Test Setup Failed
Push — master ( f71949...6c6bd7 )
by Julito
55:21
created

CourseRestorer::restore_assets()   D

Complexity

Conditions 9
Paths 6

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 17
nc 6
nop 0
dl 0
loc 26
rs 4.909
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
namespace Chamilo\CourseBundle\Component\CourseCopy;
5
6
use Chamilo\CourseBundle\Component\CourseCopy\Resources\GradeBookBackup;
7
use Chamilo\CourseBundle\Component\CourseCopy\Resources\QuizQuestion;
8
use Chamilo\CourseBundle\Entity\CQuizAnswer;
9
use DocumentManager;
10
use Database;
11
use CourseManager;
12
use stdClass;
13
use TestCategory;
14
use SurveyManager;
15
use Question;
16
17
/**
18
 * Class CourseRestorer
19
 *
20
 * Class to restore items from a course object to a Chamilo-course
21
 * @author Bart Mollet <[email protected]>
22
 * @author Julio Montoya <[email protected]> Several fixes/improvements
23
 * @package chamilo.backup
24
 */
25
class CourseRestorer
26
{
27
    /**
28
    * The course-object
29
    */
30
    public $course;
31
    public $destination_course_info;
32
33
    /**
34
     * What to do with files with same name (FILE_SKIP, FILE_RENAME or
35
     * FILE_OVERWRITE)
36
     */
37
    public $file_option;
38
    public $set_tools_invisible_by_default;
39
    public $skip_content;
40
    public $tools_to_restore = array(
41
        'documents', // first restore documents
42
        'announcements',
43
        'attendance',
44
        'course_descriptions',
45
        'events',
46
        'forum_category',
47
        'forums',
48
       // 'forum_topics',
49
        'glossary',
50
        'quizzes',
51
        'test_category',
52
        'links',
53
        'learnpaths',
54
        'surveys',
55
        //'scorm_documents', ??
56
        'tool_intro',
57
        'thematic',
58
        'wiki',
59
        'works',
60
        'gradebook',
61
        'assets',
62
    );
63
64
    /** Setting per tool */
65
    public $tool_copy_settings = array();
66
67
    /**
68
     * If true adds the text "copy" in the title of an item (only for LPs right now)
69
     **/
70
    public $add_text_in_items = false;
71
    public $destination_course_id;
72
73
    /**
74
     * CourseRestorer constructor.
75
     * @param Course $course
76
     */
77
    public function __construct($course)
78
    {
79
        $this->course = $course;
80
        $courseInfo = api_get_course_info($this->course->code);
81
        if (!empty($courseInfo)) {
82
            $this->course_origin_id = $courseInfo['real_id'];
83
        } else {
84
            $this->course_origin_id = null;
85
        }
86
        $this->file_option = FILE_RENAME;
87
        $this->set_tools_invisible_by_default = false;
88
        $this->skip_content = array();
89
    }
90
91
    /**
92
     * Set the file-option
93
     * @param int $option (optional) What to do with files with same name
94
     * FILE_SKIP, FILE_RENAME or FILE_OVERWRITE
95
     */
96
    public function set_file_option($option = FILE_OVERWRITE)
97
    {
98
        $this->file_option = $option;
99
    }
100
101
    /**
102
     * @param bool $status
103
     */
104
    public function set_add_text_in_items($status)
105
    {
106
        $this->add_text_in_items = $status;
107
    }
108
109
    /**
110
     * @param array $array
111
     */
112
    public function set_tool_copy_settings($array)
113
    {
114
        $this->tool_copy_settings = $array;
115
    }
116
117
    /**
118
     * Restore a course.
119
     *
120
     * @param string $destination_course_code code of the Chamilo-course in
121
     * @param int $session_id
122
     * @param bool $update_course_settings Course settings are going to be restore?
123
     * @param bool $respect_base_content
124
     * @return false|null
125
     */
126
    public function restore(
127
        $destination_course_code = '',
128
        $session_id = 0,
129
        $update_course_settings = false,
130
        $respect_base_content = false
131
    ) {
132
        if ($destination_course_code == '') {
133
            $course_info = api_get_course_info();
134
            $this->destination_course_info = $course_info;
135
            $this->course->destination_path = $course_info['path'];
136
        } else {
137
            $course_info = api_get_course_info($destination_course_code);
138
            $this->destination_course_info = $course_info;
139
            $this->course->destination_path = $course_info['path'];
140
        }
141
        $this->destination_course_id = $course_info['real_id'];
142
143
        //Getting first teacher (for the forums)
144
        $teacher_list = CourseManager::get_teacher_list_from_course_code(
145
            $course_info['code']
146
        );
147
        $this->first_teacher_id = api_get_user_id();
148
149
        if (!empty($teacher_list)) {
150
            foreach ($teacher_list as $teacher) {
151
                $this->first_teacher_id = $teacher['user_id'];
152
                break;
153
            }
154
        }
155
156
        if (empty($this->course)) {
157
            return false;
158
        }
159
160
        // Source platform encoding - reading/detection
161
        // The correspondent data field has been added as of version 1.8.6.1
162
        if (empty($this->course->encoding)) {
163
            // The archive has been created by a system which is prior to 1.8.6.1 version.
164
            // In this case we have to detect the encoding.
165
            $sample_text = $this->course->get_sample_text()."\n";
166
            // Let us exclude ASCII lines, probably they are English texts.
167
            $sample_text = explode("\n", $sample_text);
168
            foreach ($sample_text as $key => &$line) {
169
                if (api_is_valid_ascii($line)) {
170
                    unset($sample_text[$key]);
171
                }
172
            }
173
            $sample_text = implode("\n", $sample_text);
174
            $this->course->encoding = api_detect_encoding($sample_text, $course_info['language']);
175
        }
176
177
        // Encoding conversion of the course, if it is needed.
178
        $this->course->to_system_encoding();
179
180
        foreach ($this->tools_to_restore as $tool) {
181
            $function_build = 'restore_'.$tool;
182
            $this->$function_build($session_id, $respect_base_content, $destination_course_code);
183
        }
184
185
        if ($update_course_settings) {
186
            $this->restore_course_settings($destination_course_code);
187
        }
188
189
        // Restore the item properties
190
        $table = Database::get_course_table(TABLE_ITEM_PROPERTY);
191
192
        foreach ($this->course->resources as $type => $resources) {
193
            if (is_array($resources)) {
194
                foreach ($resources as $id => $resource) {
195
                    if (isset($resource->item_properties)) {
196
                        foreach ($resource->item_properties as $property) {
197
                            // First check if there isn't already a record for this resource
198
                            $sql = "SELECT * FROM $table
199
                                    WHERE
200
                                        c_id = ".$this->destination_course_id." AND
201
                                        tool = '".$property['tool']."' AND
202
                                        ref = '".$resource->destination_id."'";
203
204
                            $params = [];
205
                            if (!empty($session_id)) {
206
                                $params['session_id'] = intval($session_id);
207
                            }
208
209
                            $res = Database::query($sql);
210
                            if (Database::num_rows($res) == 0) {
211
                                /* The to_group_id and to_user_id are set to default
212
                                values as users/groups possibly not exist in
213
                                the target course*/
214
215
                                $params['c_id'] = $this->destination_course_id;
216
                                $params['tool'] = self::DBUTF8($property['tool']);
217
                                $params['insert_user_id'] = $this->checkUserId($property['insert_user_id']);
218
                                $params['insert_date'] = self::DBUTF8($property['insert_date']);
219
                                $params['lastedit_date'] = self::DBUTF8($property['lastedit_date']);
220
                                $params['ref'] = $resource->destination_id;
221
                                $params['lastedit_type'] = self::DBUTF8($property['lastedit_type']);
222
                                $params['lastedit_user_id'] = $this->checkUserId($property['lastedit_user_id']);
223
                                $params['visibility'] = self::DBUTF8($property['visibility']);
224
                                $params['start_visible'] = self::DBUTF8($property['start_visible']);
225
                                $params['end_visible'] = self::DBUTF8($property['end_visible']);
226
                                $params['to_user_id'] = $this->checkUserId($property['to_user_id']);
227
228
                                $id = Database::insert($table, $params);
229
                                if ($id) {
230
                                    $sql = "UPDATE $table SET id = iid WHERE iid = $id";
231
                                    Database::query($sql);
232
                                }
233
                            }
234
                        }
235
                    }
236
                }
237
            }
238
        }
239
    }
240
241
    /**
242
     * Restore only harmless course settings:
243
     * course_language, visibility, department_name,department_url,
244
     * subscribe, unsubscribe ,category_code
245
     *
246
     * @param string $destination_course_code
247
     */
248
    public function restore_course_settings($destination_course_code)
249
    {
250
        $origin_course_info = api_get_course_info($destination_course_code);
251
        $course_info = $this->course->info;
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Chamilo\CourseBundle\Component\CourseCopy\Course.

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

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

Loading history...
252
        $params['course_language'] = $course_info['language'];
253
        $params['visibility'] = $course_info['visibility'];
254
        $params['department_name'] = $course_info['department_name'];
255
        $params['department_url'] = $course_info['department_url'];
256
257
        $params['category_code'] = $course_info['categoryCode'];
258
        $params['subscribe'] = $course_info['subscribe_allowed'];
259
        $params['unsubscribe'] = $course_info['unsubscribe'];
260
        CourseManager::update_attributes($origin_course_info['real_id'], $params);
261
    }
262
263
    /**
264
     * Restore documents
265
     *
266
     * @param int $session_id
267
     * @param bool $respect_base_content
268
     * @param string $destination_course_code
269
     */
270
    public function restore_documents(
271
        $session_id = 0,
272
        $respect_base_content = false,
273
        $destination_course_code = ''
274
    ) {
275
        $course_info = api_get_course_info($destination_course_code);
276
277
        if (!$this->course->has_resources(RESOURCE_DOCUMENT)) {
278
            return;
279
        }
280
281
        $table = Database::get_course_table(TABLE_DOCUMENT);
282
        $resources = $this->course->resources;
283
        $path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/';
284
285
        foreach ($resources[RESOURCE_DOCUMENT] as $id => $document) {
286
            $my_session_id = empty($document->item_properties[0]['id_session']) ? 0 : $session_id;
287
288
            if ($document->file_type == FOLDER) {
289
                $visibility = $document->item_properties[0]['visibility'];
290
                $new = substr($document->path, 8);
291
292
                $folderList = explode('/', $new);
293
                $tempFolder = '';
294
295
                // Check if the parent path exists.
296
                foreach ($folderList as $folder) {
297
                    $folderToCreate = $tempFolder.$folder;
298
                    $sysFolderPath = $path.'document'.$folderToCreate;
299
                    $tempFolder .= $folder.'/';
300
301
                    if (empty($folderToCreate)) {
302
                        continue;
303
                    }
304
305
                    $title = $document->title;
306
                    if (empty($title)) {
307
                        $title = basename($sysFolderPath);
308
                    }
309
310
                    // File doesn't exist in file system.
311
                    if (!is_dir($sysFolderPath)) {
312
                        // Creating directory
313
                        create_unexisting_directory(
314
                            $course_info,
315
                            api_get_user_id(),
316
                            $my_session_id,
317
                            0,
318
                            0,
319
                            $path.'document',
320
                            $folderToCreate,
321
                            $title,
322
                            $visibility
323
                        );
324
325
                        continue;
326
                    }
327
328
                    // File exist in file system.
329
                    $documentData = DocumentManager::get_document_id(
330
                        $course_info,
331
                        $folderToCreate,
332
                        $my_session_id
333
                    );
334
335
                    if (empty($documentData)) {
336
                        /* This means the folder exists in the
337
                        filesystem but not in the DB, trying to fix it */
338
                        add_document(
339
                            $course_info,
340
                            $folderToCreate,
341
                            'folder',
342
                            0,
343
                            $title,
344
                            null,
345
                            null,
346
                            false,
347
                            null,
348
                            $my_session_id
349
                        );
350
                    } else {
351
                        $insertUserId = isset($document->item_properties[0]['insert_user_id']) ? $document->item_properties[0]['insert_user_id'] : api_get_user_id();
352
                        $insertUserId = $this->checkUserId($insertUserId);
353
354
                        // Check if user exists in platform
355
                        $toUserId = isset($document->item_properties[0]['to_user_id']) ? $document->item_properties[0]['to_user_id'] : null;
356
                        $toUserId = $this->checkUserId($toUserId, true);
357
358
                        $groupId = isset($document->item_properties[0]['to_group_id']) ? $document->item_properties[0]['to_group_id'] : null;
359
                        $groupInfo = $this->checkGroupId($groupId);
360
361
                        // if folder exists then just refresh it
362
                        api_item_property_update(
363
                            $course_info,
364
                            TOOL_DOCUMENT,
365
                            $documentData,
366
                            'FolderUpdated',
367
                            $insertUserId,
368
                            $groupInfo,
0 ignored issues
show
Bug introduced by
It seems like $groupInfo defined by $this->checkGroupId($groupId) on line 359 can also be of type null; however, api_item_property_update() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
369
                            $toUserId,
370
                            null,
371
                            null,
372
                            $my_session_id
373
                        );
374
                    }
375
                }
376
            } elseif ($document->file_type == DOCUMENT) {
377
                //Checking if folder exists in the database otherwise we created it
378
                $dir_to_create = dirname($document->path);
379
380
                if (!empty($dir_to_create) && $dir_to_create != 'document' && $dir_to_create != '/') {
381
                    if (is_dir($path.dirname($document->path))) {
382
                        $sql = "SELECT id FROM $table
383
                                WHERE
384
                                    c_id = ".$this->destination_course_id." AND
385
                                    path = '/".self::DBUTF8escapestring(substr(dirname($document->path), 9))."'";
386
                        $res = Database::query($sql);
387
                        if (Database::num_rows($res) == 0) {
388
                            //continue;
389
                            $visibility = $document->item_properties[0]['visibility'];
390
                            $new = '/'.substr(dirname($document->path), 9);
391
                            $title = $document->title;
392
                            if (empty($title)) {
393
                                $title = str_replace('/', '', $new);
394
                            }
395
396
                            // This code fixes the possibility for a file without a directory entry to be
397
                            $document_id = add_document(
398
                                $course_info,
399
                                $new,
400
                                'folder',
401
                                0,
402
                                $title,
403
                                null,
404
                                null,
405
                                false
406
                            );
407
408
                            $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
409
                            $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
410
                            $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
411
                            $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
412
                            $groupInfo = $this->checkGroupId($toGroupId);
413
                            $insertUserId = $this->checkUserId($insertUserId);
414
                            $toUserId = $this->checkUserId($toUserId, true);
415
416
                            api_item_property_update(
417
                                $course_info,
418
                                TOOL_DOCUMENT,
419
                                $document_id,
420
                                'FolderCreated',
421
                                $insertUserId,
422
                                $groupInfo,
0 ignored issues
show
Bug introduced by
It seems like $groupInfo defined by $this->checkGroupId($toGroupId) on line 412 can also be of type null; however, api_item_property_update() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
423
                                $toUserId,
424
                                null,
425
                                null,
426
                                $my_session_id
427
                            );
428
                        }
429
                    }
430
                }
431
432
                if (file_exists($path.$document->path)) {
433
                    switch ($this->file_option) {
434
                        case FILE_OVERWRITE:
435
                            $origin_path = $this->course->backup_path.'/'.$document->path;
436
437
                            if (file_exists($origin_path)) {
438
                                copy($origin_path, $path.$document->path);
439
                                $sql = "SELECT id FROM $table
440
                                        WHERE
441
                                            c_id = ".$this->destination_course_id." AND
442
                                            path = '/".self::DBUTF8escapestring(substr($document->path, 9))."'";
443
444
                                $res = Database::query($sql);
445
                                $count = Database::num_rows($res);
446
447
                                if ($count == 0) {
448
                                    $params = [
449
                                        'path' => "/".self::DBUTF8(substr($document->path, 9)),
450
                                        'c_id' => $this->destination_course_id,
451
                                        'comment'=> self::DBUTF8($document->comment),
452
                                        'title' => self::DBUTF8($document->title),
453
                                        'filetype' => self::DBUTF8($document->file_type),
454
                                        'size' => self::DBUTF8($document->size),
455
                                        'session_id' => $my_session_id,
456
                                        'readonly' => 0,
457
                                    ];
458
459
                                    $document_id = Database::insert($table, $params);
460
461
                                    if ($document_id) {
462
                                        $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
463
                                        Database::query($sql);
464
                                    }
465
                                    $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
466
467
                                    $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
468
                                    $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
469
                                    $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
470
                                    $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
471
472
                                    $insertUserId = $this->checkUserId($insertUserId);
473
                                    $toUserId = $this->checkUserId($toUserId, true);
474
                                    $groupInfo = $this->checkGroupId($toGroupId);
475
476
                                    api_item_property_update(
477
                                        $course_info,
478
                                        TOOL_DOCUMENT,
479
                                        $document_id,
480
                                        'DocumentAdded',
481
                                        $insertUserId,
482
                                        $groupInfo,
0 ignored issues
show
Bug introduced by
It seems like $groupInfo defined by $this->checkGroupId($toGroupId) on line 474 can also be of type null; however, api_item_property_update() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
483
                                        $toUserId,
484
                                        null,
485
                                        null,
486
                                        $my_session_id
487
                                    );
488
                                } else {
489
                                    $obj = Database::fetch_object($res);
490
                                    $document_id = $obj->id;
491
                                    $params = [
492
                                        'path' => "/".self::DBUTF8(substr($document->path, 9)),
493
                                        'c_id' => $this->destination_course_id,
494
                                        'comment'=> self::DBUTF8($document->comment),
495
                                        'title' => self::DBUTF8($document->title),
496
                                        'filetype' => self::DBUTF8($document->file_type),
497
                                        'size' => self::DBUTF8($document->size),
498
                                        'session_id' => $my_session_id,
499
                                    ];
500
501
                                    Database::update(
502
                                        $table,
503
                                        $params,
504
                                        [
505
                                            'c_id = ? AND path = ?' => [
506
                                                $this->destination_course_id,
507
                                                "/".self::DBUTF8escapestring(substr($document->path, 9)),
508
                                            ],
509
                                        ]
510
                                    );
511
512
                                    $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $obj->id;
513
514
                                    $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
515
                                    $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
516
                                    $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
517
                                    $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
518
519
                                    $insertUserId = $this->checkUserId($insertUserId);
520
                                    $toUserId = $this->checkUserId($toUserId, true);
521
                                    $groupInfo = $this->checkGroupId($toGroupId);
522
523
                                    api_item_property_update(
524
                                        $course_info,
525
                                        TOOL_DOCUMENT,
526
                                        $obj->id,
527
                                        'default',
528
                                        $insertUserId,
529
                                        $groupInfo,
0 ignored issues
show
Bug introduced by
It seems like $groupInfo defined by $this->checkGroupId($toGroupId) on line 521 can also be of type null; however, api_item_property_update() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
530
                                        $toUserId,
531
                                        null,
532
                                        null,
533
                                        $my_session_id
534
                                    );
535
                                }
536
537
                                // Replace old course code with the new destination code
538
                                $file_info = pathinfo($path.$document->path);
539
540
                                if (isset($file_info['extension']) && in_array($file_info['extension'], array('html', 'htm'))) {
541
                                    $content = file_get_contents($path.$document->path);
542
                                    if (UTF8_CONVERT) {
543
                                        $content = utf8_encode($content);
544
                                    }
545
                                    $content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
546
                                        $content,
547
                                        $this->course->code,
548
                                        $this->course->destination_path,
549
                                        $this->course->backup_path,
550
                                        $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Chamilo\CourseBundle\Component\CourseCopy\Course.

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

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

Loading history...
551
                                    );
552
                                    file_put_contents($path.$document->path, $content);
553
                                }
554
555
                                $params = [
556
                                    'comment'=> self::DBUTF8($document->comment),
557
                                    'title' => self::DBUTF8($document->title),
558
                                    'size' => self::DBUTF8($document->size),
559
                                ];
560
                                Database::update(
561
                                    $table,
562
                                    $params,
563
                                    [
564
                                        'c_id = ? AND id = ?' => [
565
                                            $this->destination_course_id,
566
                                            $document_id,
567
                                        ],
568
                                    ]
569
                                );
570
                            }
571
                            break;
572
                        case FILE_SKIP:
573
                            $sql = "SELECT id FROM $table
574
                                    WHERE
575
                                        c_id = ".$this->destination_course_id." AND
576
                                        path='/".self::DBUTF8escapestring(substr($document->path, 9))."'";
577
                            $res = Database::query($sql);
578
                            $obj = Database::fetch_object($res);
579
                            $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $obj->id;
580
                            break;
581
                        case FILE_RENAME:
582
                            $i = 1;
583
                            $ext = explode('.', basename($document->path));
584 View Code Duplication
                            if (count($ext) > 1) {
585
                                $ext = array_pop($ext);
586
                                $file_name_no_ext = substr($document->path, 0, - (strlen($ext) + 1));
587
                                $ext = '.'.$ext;
588
                            } else {
589
                                $ext = '';
590
                                $file_name_no_ext = $document->path;
591
                            }
592
                            $new_file_name = $file_name_no_ext.'_'.$i.$ext;
593
                            $file_exists = file_exists($path.$new_file_name);
594 View Code Duplication
                            while ($file_exists) {
595
                                $i++;
596
                                $new_file_name = $file_name_no_ext.'_'.$i.$ext;
597
                                $file_exists = file_exists($path.$new_file_name);
598
                            }
599
600
                            if (!empty($session_id)) {
601
                                $document_path = explode('/', $document->path, 3);
602
                                $course_path = $path;
603
                                $orig_base_folder = $document_path[1];
604
                                $orig_base_path   = $course_path.$document_path[0].'/'.$document_path[1];
605
606
                                if (is_dir($orig_base_path)) {
607
                                    $new_base_foldername = $orig_base_folder;
608
                                    $new_base_path = $orig_base_path;
609
610
                                    if ($_SESSION['orig_base_foldername'] != $new_base_foldername) {
611
                                        unset($_SESSION['new_base_foldername']);
612
                                        unset($_SESSION['orig_base_foldername']);
613
                                        unset($_SESSION['new_base_path']);
614
                                    }
615
616
                                    $folder_exists = file_exists($new_base_path);
617
                                    if ($folder_exists) {
618
                                        // e.g: carpeta1 in session
619
                                        $_SESSION['orig_base_foldername'] = $new_base_foldername;
620
                                        $x = '';
621
                                        while ($folder_exists) {
622
                                            $x = $x + 1;
623
                                            $new_base_foldername = $document_path[1].'_'.$x;
624
                                            $new_base_path = $orig_base_path.'_'.$x;
625
                                            if ($_SESSION['new_base_foldername'] == $new_base_foldername) {
626
                                                break;
627
                                            }
628
                                            $folder_exists = file_exists($new_base_path);
629
                                        }
630
                                        $_SESSION['new_base_foldername'] = $new_base_foldername;
631
                                        $_SESSION['new_base_path'] = $new_base_path;
632
                                    }
633
634
                                    if (isset($_SESSION['new_base_foldername']) && isset($_SESSION['new_base_path'])) {
635
                                        $new_base_foldername = $_SESSION['new_base_foldername'];
636
                                        $new_base_path = $_SESSION['new_base_path'];
637
                                    }
638
639
                                    $dest_document_path = $new_base_path.'/'.$document_path[2]; // e.g: "/var/www/wiener/courses/CURSO4/document/carpeta1_1/subcarpeta1/collaborative.png"
640
                                    $basedir_dest_path = dirname($dest_document_path); // e.g: "/var/www/wiener/courses/CURSO4/document/carpeta1_1/subcarpeta1"
641
                                    $base_path_document = $course_path.$document_path[0]; // e.g: "/var/www/wiener/courses/CURSO4/document"
642
                                    $path_title = '/'.$new_base_foldername.'/'.$document_path[2];
643
644
                                    copy_folder_course_session(
645
                                        $basedir_dest_path,
646
                                        $base_path_document,
647
                                        $session_id,
648
                                        $course_info,
649
                                        $document,
650
                                        $this->course_origin_id
651
                                    );
652
653
                                    if (file_exists($course_path.$document->path)) {
654
                                        copy($course_path.$document->path, $dest_document_path);
655
                                    }
656
657
                                    // Replace old course code with the new destination code see BT#1985
658
                                    if (file_exists($dest_document_path)) {
659
                                        $file_info = pathinfo($dest_document_path);
660
                                        if (in_array($file_info['extension'], array('html', 'htm'))) {
661
                                            $content = file_get_contents($dest_document_path);
662
                                            if (UTF8_CONVERT) {
663
                                                $content = utf8_encode($content);
664
                                            }
665
                                            $content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
666
                                                $content,
667
                                                $this->course->code,
668
                                                $this->course->destination_path,
669
                                                $this->course->backup_path,
670
                                                $this->course->info['path']
671
                                            );
672
                                            file_put_contents($dest_document_path, $content);
673
                                        }
674
                                    }
675
676
                                    $params = [
677
                                        'path' => self::DBUTF8($path_title),
678
                                        'c_id' => $this->destination_course_id,
679
                                        'comment'=> self::DBUTF8($document->comment),
680
                                        'title' => self::DBUTF8(basename($path_title)),
681
                                        'filetype' => self::DBUTF8($document->file_type),
682
                                        'size' => self::DBUTF8($document->size),
683
                                        'session_id' => $my_session_id,
684
                                    ];
685
686
                                    $document_id = Database::insert($table, $params);
687
688
                                    if ($document_id) {
689
                                        $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
690
                                        Database::query($sql);
691
                                    }
692
693
                                    $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
694
695
                                    $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
696
                                    $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
697
                                    $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
698
                                    $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
699
700
                                    $insertUserId = $this->checkUserId($insertUserId);
701
                                    $toUserId = $this->checkUserId($toUserId, true);
702
                                    $groupInfo = $this->checkGroupId($toGroupId);
703
704
                                    api_item_property_update(
705
                                        $course_info,
706
                                        TOOL_DOCUMENT,
707
                                        $document_id,
708
                                        'DocumentAdded',
709
                                        $insertUserId,
710
                                        $groupInfo,
0 ignored issues
show
Bug introduced by
It seems like $groupInfo defined by $this->checkGroupId($toGroupId) on line 702 can also be of type null; however, api_item_property_update() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
711
                                        $toUserId,
712
                                        null,
713
                                        null,
714
                                        $my_session_id
715
                                    );
716
                                } else {
717
                                    if (file_exists($path.$document->path)) {
718
                                        copy($path.$document->path, $path.$new_file_name);
719
                                    }
720
                                    //Replace old course code with the new destination code see BT#1985
721 View Code Duplication
                                    if (file_exists($path.$new_file_name)) {
722
                                        $file_info = pathinfo($path.$new_file_name);
723
                                        if (in_array($file_info['extension'], array('html', 'htm'))) {
724
                                            $content = file_get_contents($path.$new_file_name);
725
                                            if (UTF8_CONVERT) {
726
                                                $content = utf8_encode($content);
727
                                            }
728
                                            $content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
729
                                                $content,
730
                                                $this->course->code,
731
                                                $this->course->destination_path,
732
                                                $this->course->backup_path,
733
                                                $this->course->info['path']
734
                                            );
735
                                            file_put_contents($path.$new_file_name, $content);
736
                                        }
737
                                    }
738
739
                                    $params = [
740
                                        'path' => "/".self::DBUTF8escapestring(substr($new_file_name, 9)),
741
                                        'c_id' => $this->destination_course_id,
742
                                        'comment'=> self::DBUTF8($document->comment),
743
                                        'title' => self::DBUTF8($document->title),
744
                                        'filetype' => self::DBUTF8($document->file_type),
745
                                        'size' => self::DBUTF8($document->size),
746
                                        'session_id' => $my_session_id,
747
                                    ];
748
749
                                    $document_id = Database::insert($table, $params);
750
751
                                    if ($document_id) {
752
                                        $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
753
                                        Database::query($sql);
754
755
                                        $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
756
757
                                        $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
758
                                        $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
759
                                        $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
760
                                        $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
761
762
                                        $insertUserId = $this->checkUserId($insertUserId);
763
                                        $toUserId = $this->checkUserId($toUserId, true);
764
                                        $groupInfo = $this->checkGroupId($toGroupId);
765
766
                                        api_item_property_update(
767
                                            $course_info,
768
                                            TOOL_DOCUMENT,
769
                                            $document_id,
770
                                            'DocumentAdded',
771
                                            $insertUserId,
772
                                            $groupInfo,
0 ignored issues
show
Bug introduced by
It seems like $groupInfo defined by $this->checkGroupId($toGroupId) on line 764 can also be of type null; however, api_item_property_update() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
773
                                            $toUserId,
774
                                            null,
775
                                            null,
776
                                            $my_session_id
777
                                        );
778
                                    }
779
                                }
780
                            } else {
781
                                copy(
782
                                    $this->course->backup_path.'/'.$document->path,
783
                                    $path.$new_file_name
784
                                );
785
786
                                // Replace old course code with the new destination code see BT#1985
787 View Code Duplication
                                if (file_exists($path.$new_file_name)) {
788
                                    $file_info = pathinfo($path.$new_file_name);
789
                                    if (in_array($file_info['extension'], array('html', 'htm'))) {
790
                                        $content = file_get_contents($path.$new_file_name);
791
                                        if (UTF8_CONVERT) {
792
                                            $content = utf8_encode($content);
793
                                        }
794
                                        $content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
795
                                            $content,
796
                                            $this->course->code,
797
                                            $this->course->destination_path,
798
                                            $this->course->backup_path,
799
                                            $this->course->info['path']
800
                                        );
801
                                        file_put_contents($path.$new_file_name, $content);
802
                                    }
803
                                }
804
805
                                $params = [
806
                                    'c_id' => $this->destination_course_id,
807
                                    'path' => "/".self::DBUTF8escapestring(substr($new_file_name, 9)),
808
                                    'comment'=> self::DBUTF8($document->comment),
809
                                    'title' => self::DBUTF8($document->title),
810
                                    'filetype' => self::DBUTF8($document->file_type),
811
                                    'size' => self::DBUTF8($document->size),
812
                                    'session_id' => $my_session_id,
813
                                ];
814
815
                                $document_id = Database::insert($table, $params);
816
817
                                if ($document_id) {
818
                                    $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
819
                                    Database::query($sql);
820
                                }
821
822
                                $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
823
824
                                $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
825
                                $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
826
                                $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
827
                                $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
828
829
                                $insertUserId = $this->checkUserId($insertUserId);
830
                                $toUserId = $this->checkUserId($toUserId, true);
831
                                $groupInfo = $this->checkGroupId($toGroupId);
832
833
                                api_item_property_update(
834
                                    $course_info,
835
                                    TOOL_DOCUMENT,
836
                                    $document_id,
837
                                    'DocumentAdded',
838
                                    $insertUserId,
839
                                    $groupInfo,
0 ignored issues
show
Bug introduced by
It seems like $groupInfo defined by $this->checkGroupId($toGroupId) on line 831 can also be of type null; however, api_item_property_update() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
840
                                    $toUserId,
841
                                    null,
842
                                    null,
843
                                    $my_session_id
844
                                );
845
                            }
846
                            break;
847
848
                    } // end switch
849
                } else {
850
                    // end if file exists
851
                    //make sure the source file actually exists
852
                    if (is_file($this->course->backup_path.'/'.$document->path) &&
853
                        is_readable($this->course->backup_path.'/'.$document->path) &&
854
                        is_dir(dirname($path.$document->path)) &&
855
                        is_writeable(dirname($path.$document->path))
856
                    ) {
857
                        copy(
858
                            $this->course->backup_path.'/'.$document->path,
859
                            $path.$document->path
860
                        );
861
862
                        // Replace old course code with the new destination code see BT#1985
863
                        if (file_exists($path.$document->path)) {
864
                            $file_info = pathinfo($path.$document->path);
865
                            if (isset($file_info['extension']) && in_array($file_info['extension'], array('html', 'htm'))) {
866
                                $content = file_get_contents($path.$document->path);
867
                                if (UTF8_CONVERT) {
868
                                    $content = utf8_encode($content);
869
                                }
870
                                $content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
871
                                    $content,
872
                                    $this->course->code,
873
                                    $this->course->destination_path,
874
                                    $this->course->backup_path,
875
                                    $this->course->info['path']
876
                                );
877
                                file_put_contents($path.$document->path, $content);
878
                            }
879
                        }
880
881
                        $params = [
882
                            'c_id' => $this->destination_course_id,
883
                            'path' => "/".self::DBUTF8(substr($document->path, 9)),
884
                            'comment'=> self::DBUTF8($document->comment),
885
                            'title' => self::DBUTF8($document->title),
886
                            'filetype' => self::DBUTF8($document->file_type),
887
                            'size' => self::DBUTF8($document->size),
888
                            'session_id' => $my_session_id,
889
                            'readonly' => 0,
890
                        ];
891
892
                        $document_id = Database::insert($table, $params);
893
894
                        if ($document_id) {
895
                            $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
896
                            Database::query($sql);
897
                        }
898
899
                        $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
900
901
                        $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
902
                        $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
903
                        $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
904
                        $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
905
906
                        $insertUserId = $this->checkUserId($insertUserId);
907
                        $toUserId = $this->checkUserId($toUserId, true);
908
                        $groupInfo = $this->checkGroupId($toGroupId);
909
910
                        api_item_property_update(
911
                            $course_info,
912
                            TOOL_DOCUMENT,
913
                            $document_id,
914
                            'DocumentAdded',
915
                            $insertUserId,
916
                            $groupInfo,
0 ignored issues
show
Bug introduced by
It seems like $groupInfo defined by $this->checkGroupId($toGroupId) on line 908 can also be of type null; however, api_item_property_update() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
917
                            $toUserId,
918
                            null,
919
                            null,
920
                            $my_session_id
921
                        );
922
                    } else {
923
                        // There was an error in checking existence and
924
                        // permissions for files to copy. Try to determine
925
                        // the exact issue
926
                        // Issue with origin document?
927
                        if (!is_file($this->course->backup_path.'/'.$document->path)) {
928
                            error_log('Course copy generated an ignorable error while trying to copy '.$this->course->backup_path.'/'.$document->path.': origin file not found');
929
                        } elseif (!is_readable($this->course->backup_path.'/'.$document->path)) {
930
                            error_log('Course copy generated an ignorable error while trying to copy '.$this->course->backup_path.'/'.$document->path.': origin file not readable');
931
                        }
932
                        // Issue with destination directories?
933 View Code Duplication
                        if (!is_dir(dirname($path.$document->path))) {
934
                            error_log('Course copy generated an ignorable error while trying to copy '.$this->course->backup_path.'/'.$document->path.' to '.dirname($path.$document->path).': destination directory not found');
935
                        }
936 View Code Duplication
                        if (!is_writeable(dirname($path.$document->path))) {
937
                            error_log('Course copy generated an ignorable error while trying to copy '.$this->course->backup_path.'/'.$document->path.' to '.dirname($path.$document->path).': destination directory not writable');
938
                        }
939
                    }
940
                } // end file doesn't exist
941
            }
942
943
            // add image information for area questions
944
            if (preg_match('/^quiz-.*$/', $document->title) &&
945
                preg_match('/^document\/images\/.*$/', $document->path)
946
            ) {
947
                $this->course->resources[RESOURCE_DOCUMENT]['image_quiz'][$document->title] = [
948
                    'path' => $document->path,
949
                    'title' => $document->title,
950
                    'source_id' => $document->source_id,
951
                    'destination_id' => $document->destination_id,
952
                ];
953
            }
954
        } // end for each
955
956
        // Delete sessions for the copy the new folder in session
957
        unset($_SESSION['new_base_foldername']);
958
        unset($_SESSION['orig_base_foldername']);
959
        unset($_SESSION['new_base_path']);
960
    }
961
962
    /**
963
     * Restore scorm documents
964
     * TODO @TODO check that the restore function with renaming doesn't break the scorm structure!
965
     * see #7029
966
     */
967
    public function restore_scorm_documents()
968
    {
969
        $perm = api_get_permissions_for_new_directories();
970
971
        if ($this->course->has_resources(RESOURCE_SCORM)) {
972
            $resources = $this->course->resources;
973
            foreach ($resources[RESOURCE_SCORM] as $document) {
974
                $path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/';
975
                @mkdir(dirname($path.$document->path), $perm, true);
976
977
                if (file_exists($path.$document->path)) {
978
                    switch ($this->file_option) {
979
                        case FILE_OVERWRITE:
980
                            rmdirr($path.$document->path);
981
                            copyDirTo(
982
                                $this->course->backup_path.'/'.$document->path,
983
                                $path.dirname($document->path),
984
                                false
985
                            );
986
                            break;
987
                        case FILE_SKIP:
988
                            break;
989
                        case FILE_RENAME:
990
                            $i = 1;
991
                            $ext = explode('.', basename($document->path));
992 View Code Duplication
                            if (count($ext) > 1) {
993
                                $ext = array_pop($ext);
994
                                $file_name_no_ext = substr($document->path, 0, - (strlen($ext) + 1));
995
                                $ext = '.'.$ext;
996
                            } else {
997
                                $ext = '';
998
                                $file_name_no_ext = $document->path;
999
                            }
1000
1001
                            $new_file_name = $file_name_no_ext.'_'.$i.$ext;
1002
                            $file_exists = file_exists($path.$new_file_name);
1003
1004 View Code Duplication
                            while ($file_exists) {
1005
                                $i++;
1006
                                $new_file_name = $file_name_no_ext.'_'.$i.$ext;
1007
                                $file_exists = file_exists($path.$new_file_name);
1008
                            }
1009
1010
                            rename(
1011
                                $this->course->backup_path.'/'.$document->path,
1012
                                $this->course->backup_path.'/'.$new_file_name
1013
                            );
1014
                            copyDirTo(
1015
                                $this->course->backup_path.'/'.$new_file_name,
1016
                                $path.dirname($new_file_name),
1017
                                false
1018
                            );
1019
                            rename(
1020
                                $this->course->backup_path.'/'.$new_file_name,
1021
                                $this->course->backup_path.'/'.$document->path
1022
                            );
1023
1024
                            break;
1025
                    } // end switch
1026
                } else {
1027
                    // end if file exists
1028
                    copyDirTo(
1029
                        $this->course->backup_path.'/'.$document->path,
1030
                        $path.dirname($document->path),
1031
                        false
1032
                    );
1033
                }
1034
            } // end for each
1035
        }
1036
    }
1037
1038
    /**
1039
     * Restore forums
1040
     *
1041
     * @param int $sessionId
1042
     */
1043
    public function restore_forums($sessionId = 0)
1044
    {
1045
        if ($this->course->has_resources(RESOURCE_FORUM)) {
1046
            $sessionId = intval($sessionId);
1047
            $table_forum = Database::get_course_table(TABLE_FORUM);
1048
            $resources = $this->course->resources;
1049
            foreach ($resources[RESOURCE_FORUM] as $id => $forum) {
1050
                $params = (array) $forum->obj;
1051
                $cat_id = '';
1052
                if (isset($this->course->resources[RESOURCE_FORUMCATEGORY]) &&
1053
                    isset($this->course->resources[RESOURCE_FORUMCATEGORY][$params['forum_category']])) {
1054
                    if ($this->course->resources[RESOURCE_FORUMCATEGORY][$params['forum_category']]->destination_id == -1) {
1055
                        $cat_id = $this->restore_forum_category(
1056
                            $params['forum_category'],
1057
                            $sessionId
1058
                        );
1059
                    } else {
1060
                        $cat_id = $this->course->resources[RESOURCE_FORUMCATEGORY][$params['forum_category']]->destination_id;
1061
                    }
1062
                }
1063
1064
                $params = self::DBUTF8_array($params);
1065
                $params['c_id'] = $this->destination_course_id;
1066
                $params['forum_category'] = $cat_id;
1067
                $params['session_id'] = $sessionId;
1068
                $params['start_time'] = isset($params['start_time']) && $params['start_time'] === '0000-00-00 00:00:00' ? null : $params['start_time'];
1069
                $params['end_time'] = isset($params['end_time']) && $params['end_time'] === '0000-00-00 00:00:00' ? null : $params['end_time'];
1070
                $params['forum_id'] = 0;
1071
                unset($params['iid']);
1072
1073
                $params['forum_comment'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1074
                    $params['forum_comment'],
1075
                    $this->course->code,
1076
                    $this->course->destination_path,
1077
                    $this->course->backup_path,
1078
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Chamilo\CourseBundle\Component\CourseCopy\Course.

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

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

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

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

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

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

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

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

Loading history...
1243
        );
1244
        $new_id = Database::insert($table_post, $params);
1245
1246
        if ($new_id) {
1247
            $sql = "UPDATE $table_post SET post_id = iid WHERE iid = $new_id";
1248
            Database::query($sql);
1249
        }
1250
1251
        api_item_property_update(
1252
            $this->destination_course_info,
1253
            TOOL_FORUM_POST,
1254
            $new_id,
1255
            'PostAdded',
1256
            api_get_user_id(),
1257
            0,
1258
            0,
1259
            null,
1260
            null,
1261
            $sessionId
1262
        );
1263
        $this->course->resources[RESOURCE_FORUMPOST][$id]->destination_id = $new_id;
1264
1265
        return $new_id;
1266
    }
1267
1268
    /**
1269
     * Restore links
1270
     */
1271
    public function restore_links($session_id = 0)
1272
    {
1273
        if ($this->course->has_resources(RESOURCE_LINK)) {
1274
            $link_table = Database::get_course_table(TABLE_LINK);
1275
            $resources = $this->course->resources;
1276
1277
            foreach ($resources[RESOURCE_LINK] as $id => $link) {
1278
                $cat_id = $this->restore_link_category(
1279
                    $link->category_id,
1280
                    $session_id
1281
                );
1282
                $sql = "SELECT MAX(display_order)
1283
                        FROM $link_table
1284
                        WHERE
1285
                            c_id = ".$this->destination_course_id." AND
1286
                            category_id='" . intval($cat_id)."'";
1287
                $result = Database::query($sql);
1288
                list($max_order) = Database::fetch_array($result);
1289
1290
                $params = [];
1291
                if (!empty($session_id)) {
1292
                    $params['session_id'] = $session_id;
1293
                }
1294
1295
                $params['c_id'] = $this->destination_course_id;
1296
                $params['url'] = self::DBUTF8($link->url);
1297
                $params['title'] = self::DBUTF8($link->title);
1298
                $params['description'] = self::DBUTF8($link->description);
1299
                $params['category_id'] = $cat_id;
1300
                $params['on_homepage'] = $link->on_homepage;
1301
                $params['display_order'] = $max_order + 1;
1302
                $params['target'] = $link->target;
1303
1304
                $id = Database::insert($link_table, $params);
1305
1306 View Code Duplication
                if ($id) {
1307
                    $sql = "UPDATE $link_table SET id = iid WHERE iid = $id";
1308
                    Database::query($sql);
1309
1310
                    api_item_property_update(
1311
                        $this->destination_course_info,
1312
                        TOOL_LINK,
1313
                        $id,
1314
                        'LinkAdded',
1315
                        api_get_user_id()
1316
                    );
1317
1318
                    if (!isset($this->course->resources[RESOURCE_LINK][$id])) {
1319
                        $this->course->resources[RESOURCE_LINK][$id] = new stdClass();
1320
                    }
1321
                    $this->course->resources[RESOURCE_LINK][$id]->destination_id = $id;
1322
                }
1323
            }
1324
        }
1325
    }
1326
1327
    /**
1328
     * Restore a link-category
1329
     * @param int
1330
     * @param int
1331
     */
1332
    public function restore_link_category($id, $session_id = 0)
1333
    {
1334
        $params = [];
1335
        if (!empty($session_id)) {
1336
            $params['session_id'] = $session_id;
1337
        }
1338
1339
        if ($id == 0) {
1340
            return 0;
1341
        }
1342
        $link_cat_table = Database::get_course_table(TABLE_LINK_CATEGORY);
1343
        $resources = $this->course->resources;
1344
        $link_cat = $resources[RESOURCE_LINKCATEGORY][$id];
1345
        if (is_object($link_cat) && !$link_cat->is_restored()) {
1346
            $sql = "SELECT MAX(display_order) FROM  $link_cat_table
1347
                    WHERE c_id = ".$this->destination_course_id;
1348
            $result = Database::query($sql);
1349
            list($orderMax) = Database::fetch_array($result, 'NUM');
1350
            $display_order = $orderMax + 1;
1351
1352
            $params['c_id'] = $this->destination_course_id;
1353
            $params['category_title'] = self::DBUTF8($link_cat->title);
1354
            $params['description'] = self::DBUTF8($link_cat->description);
1355
            $params['display_order'] = $display_order;
1356
            $new_id = Database::insert($link_cat_table, $params);
1357
1358
            if ($new_id) {
1359
                $sql = "UPDATE $link_cat_table SET id = iid WHERE iid = $new_id";
1360
                Database::query($sql);
1361
                api_set_default_visibility($new_id, TOOL_LINK_CATEGORY);
1362
            }
1363
1364
            $this->course->resources[RESOURCE_LINKCATEGORY][$id]->destination_id = $new_id;
1365
            return $new_id;
1366
        }
1367
1368
        return $this->course->resources[RESOURCE_LINKCATEGORY][$id]->destination_id;
1369
    }
1370
1371
    /**
1372
     * Restore tool intro
1373
     * @param int
1374
     */
1375
    public function restore_tool_intro($sessionId = 0)
1376
    {
1377
        if ($this->course->has_resources(RESOURCE_TOOL_INTRO)) {
1378
            $sessionId = intval($sessionId);
1379
            $tool_intro_table = Database::get_course_table(TABLE_TOOL_INTRO);
1380
            $resources = $this->course->resources;
1381
            foreach ($resources[RESOURCE_TOOL_INTRO] as $id => $tool_intro) {
1382
                $sql = "DELETE FROM $tool_intro_table
1383
                        WHERE
1384
                            c_id = ".$this->destination_course_id." AND
1385
                            id='".self::DBUTF8escapestring($tool_intro->id)."'";
1386
                Database::query($sql);
1387
1388
                $tool_intro->intro_text = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1389
                    $tool_intro->intro_text,
1390
                    $this->course->code,
1391
                    $this->course->destination_path,
1392
                    $this->course->backup_path,
1393
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Chamilo\CourseBundle\Component\CourseCopy\Course.

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

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

Loading history...
1394
                );
1395
1396
                $params = [
1397
                    'c_id' => $this->destination_course_id,
1398
                    'id' => ($tool_intro->id === false ? '' : self::DBUTF8($tool_intro->id)),
1399
                    '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, Chamilo\CourseBundle\Com...ourseRestorer::DBUTF8() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
1400
                    'session_id' => $sessionId,
1401
                ];
1402
1403
                $id = Database::insert($tool_intro_table, $params);
1404
                if ($id) {
1405
                    if (!isset($this->course->resources[RESOURCE_TOOL_INTRO][$id])) {
1406
                        $this->course->resources[RESOURCE_TOOL_INTRO][$id] = new stdClass();
1407
                    }
1408
1409
                    $this->course->resources[RESOURCE_TOOL_INTRO][$id]->destination_id = $id;
1410
                }
1411
            }
1412
        }
1413
    }
1414
1415
    /**
1416
     * Restore events
1417
     * @param int
1418
     */
1419
    public function restore_events($sessionId = 0)
1420
    {
1421
        if ($this->course->has_resources(RESOURCE_EVENT)) {
1422
            $sessionId = intval($sessionId);
1423
            $table = Database::get_course_table(TABLE_AGENDA);
1424
            $resources = $this->course->resources;
1425
            foreach ($resources[RESOURCE_EVENT] as $id => $event) {
1426
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
1427
                $event->content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1428
                    $event->content,
1429
                    $this->course->code,
1430
                    $this->course->destination_path,
1431
                    $this->course->backup_path,
1432
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Chamilo\CourseBundle\Component\CourseCopy\Course.

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

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

Loading history...
1433
                );
1434
1435
                $params = [
1436
                    'c_id' => $this->destination_course_id,
1437
                    'title' => self::DBUTF8($event->title),
1438
                    'content' => ($event->content === false ? '' : self::DBUTF8($event->content)),
1439
                    'all_day' => $event->all_day,
1440
                    'start_date' => $event->start_date,
1441
                    'end_date' => $event->end_date,
1442
                    'session_id' => $sessionId,
1443
                ];
1444
                $new_event_id = Database::insert($table, $params);
1445
1446 View Code Duplication
                if ($new_event_id) {
1447
                    $sql = "UPDATE $table SET id = iid WHERE iid = $new_event_id";
1448
                    Database::query($sql);
1449
1450
                    if (!isset($this->course->resources[RESOURCE_EVENT][$id])) {
1451
                        $this->course->resources[RESOURCE_EVENT][$id] = new stdClass();
1452
                    }
1453
                    $this->course->resources[RESOURCE_EVENT][$id]->destination_id = $new_event_id;
1454
                }
1455
1456
                // Copy event attachment
1457
                $origin_path = $this->course->backup_path.'/upload/calendar/';
1458
                $destination_path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/upload/calendar/';
1459
1460
                if (!empty($this->course->orig)) {
0 ignored issues
show
Bug introduced by
The property orig does not seem to exist in Chamilo\CourseBundle\Component\CourseCopy\Course.

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

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

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

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

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

Loading history...
1553
                );
1554
1555
                $params = [];
1556
1557
                $session_id = intval($session_id);
1558
                $params['session_id'] = $session_id;
1559
                $params['c_id'] = $this->destination_course_id;
1560
                $params['description_type'] = self::DBUTF8($descriptionType);
1561
                $params['title'] = self::DBUTF8($title);
1562
                $params['content'] = ($description_content === false ? '' : self::DBUTF8($description_content));
1563
                $params['progress'] = 0;
1564
1565
                $id = Database::insert($table, $params);
1566 View Code Duplication
                if ($id) {
1567
                    $sql = "UPDATE $table SET id = iid WHERE iid = $id";
1568
                    Database::query($sql);
1569
1570
                    if (!isset($this->course->resources[RESOURCE_COURSEDESCRIPTION][$id])) {
1571
                        $this->course->resources[RESOURCE_COURSEDESCRIPTION][$id] = new stdClass();
1572
                    }
1573
                    $this->course->resources[RESOURCE_COURSEDESCRIPTION][$id]->destination_id = $id;
1574
                }
1575
            }
1576
        }
1577
    }
1578
1579
    /**
1580
     * Restore announcements
1581
     * @param int
1582
     */
1583
    public function restore_announcements($sessionId = 0)
1584
    {
1585
        if ($this->course->has_resources(RESOURCE_ANNOUNCEMENT)) {
1586
            $sessionId = intval($sessionId);
1587
            $table = Database::get_course_table(TABLE_ANNOUNCEMENT);
1588
            $resources = $this->course->resources;
1589
            foreach ($resources[RESOURCE_ANNOUNCEMENT] as $id => $announcement) {
1590
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
1591
                $announcement->content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1592
                    $announcement->content,
1593
                    $this->course->code,
1594
                    $this->course->destination_path,
1595
                    $this->course->backup_path,
1596
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Chamilo\CourseBundle\Component\CourseCopy\Course.

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

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

Loading history...
1597
                );
1598
1599
                $params = [
1600
                    'c_id' => $this->destination_course_id,
1601
                    'title' =>  self::DBUTF8($announcement->title),
1602
                    'content' => ($announcement->content === false ? '' : self::DBUTF8($announcement->content)),
1603
                    'end_date' => $announcement->date,
1604
                    'display_order' => $announcement->display_order,
1605
                    'email_sent' => $announcement->email_sent,
1606
                    'session_id' => $sessionId,
1607
                ];
1608
1609
                $new_announcement_id = Database::insert($table, $params);
1610
1611 View Code Duplication
                if ($new_announcement_id) {
1612
                    $sql = "UPDATE $table SET id = iid WHERE iid = $new_announcement_id";
1613
                    Database::query($sql);
1614
1615
                    if (!isset($this->course->resources[RESOURCE_ANNOUNCEMENT][$id])) {
1616
                        $this->course->resources[RESOURCE_ANNOUNCEMENT][$id] = new stdClass();
1617
                    }
1618
                    $this->course->resources[RESOURCE_ANNOUNCEMENT][$id]->destination_id = $new_announcement_id;
1619
                }
1620
1621
                $origin_path = $this->course->backup_path.'/upload/announcements/';
1622
                $destination_path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/upload/announcements/';
1623
1624
                // Copy announcement attachment file
1625
                if (!empty($this->course->orig)) {
0 ignored issues
show
Bug introduced by
The property orig does not seem to exist in Chamilo\CourseBundle\Component\CourseCopy\Course.

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

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

Loading history...
1626
1627
                    $table_attachment = Database::get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
1628
                    $sql = 'SELECT path, comment, size, filename
1629
                            FROM '.$table_attachment.'
1630
                            WHERE
1631
                                c_id = '.$this->destination_course_id.' AND
1632
                                announcement_id = '.$id;
1633
                    $attachment_event = Database::query($sql);
1634
                    $attachment_event = Database::fetch_object($attachment_event);
1635
1636 View Code Duplication
                    if (file_exists($origin_path.$attachment_event->path) &&
1637
                        !is_dir($origin_path.$attachment_event->path)
1638
                    ) {
1639
                        $new_filename = uniqid(''); //ass seen in the add_agenda_attachment_file() function in agenda.inc.php
1640
                        $copy_result = copy(
1641
                            $origin_path.$attachment_event->path,
1642
                            $destination_path.$new_filename
1643
                        );
1644
1645
                        if ($copy_result) {
1646
                            $table_attachment = Database::get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
1647
1648
                            $params = [
1649
                                'c_id' => $this->destination_course_id,
1650
                                'path' => self::DBUTF8($new_filename),
1651
                                'comment' => self::DBUTF8($attachment_event->comment),
1652
                                'size' => $attachment_event->size,
1653
                                'filename' => $attachment_event->filename,
1654
                                'announcement_id' => $new_announcement_id,
1655
                            ];
1656
1657
                            $attachmentId = Database::insert($table_attachment, $params);
1658
1659
                            if ($attachmentId) {
1660
                                $sql = "UPDATE $table_attachment SET id = iid WHERE iid = $attachmentId";
1661
                                Database::query($sql);
1662
                            }
1663
                        }
1664
                    }
1665 View Code Duplication
                } else {
1666
                    // get the info of the file
1667
                    if (!empty($announcement->attachment_path) &&
1668
                        is_file($origin_path.$announcement->attachment_path) &&
1669
                        is_readable($origin_path.$announcement->attachment_path)
1670
                    ) {
1671
                        $new_filename = uniqid(''); //ass seen in the add_agenda_attachment_file() function in agenda.inc.php
1672
                        $copy_result = copy($origin_path.$announcement->attachment_path, $destination_path.$new_filename);
1673
1674
                        if ($copy_result) {
1675
                            $table_attachment = Database::get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
1676
1677
                            $params = [
1678
                                'c_id' => $this->destination_course_id,
1679
                                'path' => self::DBUTF8($new_filename),
1680
                                'comment' => self::DBUTF8($announcement->attachment_comment),
1681
                                'size' => $announcement->attachment_size,
1682
                                'filename' => $announcement->attachment_filename,
1683
                                'announcement_id' => $new_announcement_id,
1684
                            ];
1685
1686
                            $attachmentId = Database::insert($table_attachment, $params);
1687
1688
                            if ($attachmentId) {
1689
                                $sql = "UPDATE $table_attachment SET id = iid WHERE iid = $attachmentId";
1690
                                Database::query($sql);
1691
                            }
1692
                        }
1693
                    }
1694
                }
1695
            }
1696
        }
1697
    }
1698
1699
    /**
1700
     * Restore Quiz
1701
     * @param int $session_id
1702
     * @param bool $respect_base_content
1703
     */
1704
    public function restore_quizzes(
1705
        $session_id = 0,
1706
        $respect_base_content = false
1707
    ) {
1708
        if ($this->course->has_resources(RESOURCE_QUIZ)) {
1709
            $table_qui = Database::get_course_table(TABLE_QUIZ_TEST);
1710
            $table_rel = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
1711
            $table_doc = Database::get_course_table(TABLE_DOCUMENT);
1712
            $resources = $this->course->resources;
1713
1714
            foreach ($resources[RESOURCE_QUIZ] as $id => $quiz) {
1715
                if (isset($quiz->obj)) {
1716
                    // For new imports
1717
                    $quiz = $quiz->obj;
1718
                } else {
1719
                    // For backward compatibility
1720
                    $quiz->obj = $quiz;
1721
                }
1722
1723
                $doc = '';
1724
                if (!empty($quiz->sound)) {
1725
                    if (isset($this->course->resources[RESOURCE_DOCUMENT][$quiz->sound]) &&
1726
                        $this->course->resources[RESOURCE_DOCUMENT][$quiz->sound]->is_restored()) {
1727
                        $sql = "SELECT path FROM $table_doc
1728
                                WHERE
1729
                                    c_id = ".$this->destination_course_id."  AND
1730
                                    id = " . $resources[RESOURCE_DOCUMENT][$quiz->sound]->destination_id;
1731
                        $doc = Database::query($sql);
1732
                        $doc = Database::fetch_object($doc);
1733
                        $doc = str_replace('/audio/', '', $doc->path);
1734
                    }
1735
                }
1736
1737
                if ($id != -1) {
1738
                    // check resources inside html from ckeditor tool and copy correct urls into recipient course
1739
                    $quiz->description = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1740
                        $quiz->description,
1741
                        $this->course->code,
1742
                        $this->course->destination_path,
1743
                        $this->course->backup_path,
1744
                        $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Chamilo\CourseBundle\Component\CourseCopy\Course.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Loading history...
2863
        self::allow_create_all_directory($origin, $destination, false);
0 ignored issues
show
Deprecated Code introduced by
The method Chamilo\CourseBundle\Com..._create_all_directory() has been deprecated.

This method has been deprecated.

Loading history...
2864
    }
2865
2866
    /**
2867
    * copy all directory and sub directory
2868
    * @param string The path origin
2869
    * @param string The path destination
2870
    * @param boolean Option Overwrite
2871
    * @param string $source
2872
    * @param string $dest
2873
    * @return void
2874
    * @deprecated
2875
    */
2876
    public function allow_create_all_directory($source, $dest, $overwrite = false)
2877
    {
2878
        if (!is_dir($dest)) {
2879
            mkdir($dest, api_get_permissions_for_new_directories());
2880
        }
2881
        if ($handle = opendir($source)) {
2882
            // if the folder exploration is sucsessful, continue
2883
            while (false !== ($file = readdir($handle))) {
2884
                // as long as storing the next file to $file is successful, continue
2885
                if ($file != '.' && $file != '..') {
2886
                    $path = $source.'/'.$file;
2887
                    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...
2888
                       /* if (!is_file($dest . '/' . $file) || $overwrite)
2889
                        if (!@copy($path, $dest . '/' . $file)) {
2890
                            echo '<font color="red">File ('.$path.') '.get_lang('NotHavePermission').'</font>';
2891
                        }*/
2892
                    } elseif (is_dir($path)) {
2893
                        if (!is_dir($dest.'/'.$file)) {
2894
                                                mkdir($dest.'/'.$file);
2895
                        }
2896
                        self:: allow_create_all_directory($path, $dest.'/'.$file, $overwrite);
0 ignored issues
show
Deprecated Code introduced by
The method Chamilo\CourseBundle\Com..._create_all_directory() has been deprecated.

This method has been deprecated.

Loading history...
2897
                    }
2898
                }
2899
            }
2900
            closedir($handle);
2901
        }
2902
    }
2903
2904
    /**
2905
     * Gets the new ID of one specific tool item from the tool name and the old ID
2906
     * @param	string	Tool name
2907
     * @param	integer	Old ID
2908
     * @return	integer	New ID
2909
     */
2910
    public function get_new_id($tool, $ref)
2911
    {
2912
        // Check if the value exist in the current array.
2913
        if ($tool === 'hotpotatoes') {
2914
            $tool = 'document';
2915
        }
2916
2917
        if (isset($this->course->resources[$tool][$ref]) &&
2918
            isset($this->course->resources[$tool][$ref]->destination_id) &&
2919
            !empty($this->course->resources[$tool][$ref]->destination_id)
2920
        ) {
2921
            return $this->course->resources[$tool][$ref]->destination_id;
2922
        }
2923
2924
        // Check if the course is the same (last hope).
2925
        if ($this->course_origin_id == $this->destination_course_id) {
2926
2927
            return $ref;
2928
        }
2929
2930
        return '';
2931
    }
2932
2933
    /**
2934
     * Restore glossary
2935
     */
2936
    public function restore_glossary($session_id = 0)
2937
    {
2938
        if ($this->course->has_resources(RESOURCE_GLOSSARY)) {
2939
            $table_glossary = Database::get_course_table(TABLE_GLOSSARY);
2940
            $resources = $this->course->resources;
2941
            foreach ($resources[RESOURCE_GLOSSARY] as $id => $glossary) {
2942
2943
                $params = [];
2944
                if (!empty($session_id)) {
2945
                    $session_id = intval($session_id);
2946
                    $params['session_id'] = $session_id;
2947
                }
2948
2949
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
2950
                $glossary->description = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2951
                    $glossary->description,
2952
                    $this->course->code,
2953
                    $this->course->destination_path,
2954
                    $this->course->backup_path,
2955
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Chamilo\CourseBundle\Component\CourseCopy\Course.

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

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

Loading history...
2956
                );
2957
2958
                $params['c_id'] = $this->destination_course_id;
2959
                $params['description'] = ($glossary->description === false ? '' : self::DBUTF8($glossary->description));
2960
                $params['display_order'] = $glossary->display_order;
2961
                $params['name'] = self::DBUTF8($glossary->name);
2962
                $params['glossary_id'] = 0;
2963
                $my_id = Database::insert($table_glossary, $params);
2964 View Code Duplication
                if ($my_id) {
2965
2966
                    $sql = "UPDATE $table_glossary SET glossary_id = iid WHERE iid = $my_id";
2967
                    Database::query($sql);
2968
2969
                    api_item_property_update(
2970
                        $this->destination_course_info,
2971
                        TOOL_GLOSSARY,
2972
                        $my_id,
2973
                        'GlossaryAdded',
2974
                        api_get_user_id()
2975
                    );
2976
2977
                    if (!isset($this->course->resources[RESOURCE_GLOSSARY][$id])) {
2978
                        $this->course->resources[RESOURCE_GLOSSARY][$id] = new stdClass();
2979
                    }
2980
2981
                    $this->course->resources[RESOURCE_GLOSSARY][$id]->destination_id = $my_id;
2982
                }
2983
            }
2984
        }
2985
    }
2986
2987
    /**
2988
     * @param int $session_id
2989
     */
2990
    public function restore_wiki($session_id = 0)
2991
    {
2992
        if ($this->course->has_resources(RESOURCE_WIKI)) {
2993
            // wiki table of the target course
2994
            $table_wiki = Database::get_course_table(TABLE_WIKI);
2995
            $table_wiki_conf = Database::get_course_table(TABLE_WIKI_CONF);
2996
2997
            // storing all the resources that have to be copied in an array
2998
            $resources = $this->course->resources;
2999
3000
            foreach ($resources[RESOURCE_WIKI] as $id => $wiki) {
3001
                // the sql statement to insert the groups from the old course to the new course
3002
3003
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
3004
                $wiki->content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
3005
                    $wiki->content,
3006
                    $this->course->code,
3007
                    $this->course->destination_path,
3008
                    $this->course->backup_path,
3009
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Chamilo\CourseBundle\Component\CourseCopy\Course.

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

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

Loading history...
3010
                );
3011
3012
                $params = [
3013
                    'c_id' => $this->destination_course_id,
3014
                    'page_id' => self::DBUTF8($wiki->page_id),
3015
                    'reflink' => self::DBUTF8($wiki->reflink),
3016
                    'title' => self::DBUTF8($wiki->title),
3017
                    'content' => ($wiki->content === false ? '' : self::DBUTF8($wiki->content)),
3018
                    'user_id' => intval($wiki->user_id),
3019
                    'group_id' => intval($wiki->group_id),
3020
                    'dtime' => self::DBUTF8($wiki->dtime),
3021
                    'progress' => self::DBUTF8($wiki->progress),
3022
                    'version' => intval($wiki->version),
3023
                    'session_id' => !empty($session_id) ? intval($session_id) : 0,
3024
                    'addlock' => 0,
3025
                    'editlock' => 0,
3026
                    'visibility' => 0,
3027
                    'addlock_disc' => 0,
3028
                    'visibility_disc' => 0,
3029
                    'ratinglock_disc' => 0,
3030
                    'assignment' => 0,
3031
                    'comment' => '',
3032
                    'is_editing' => 0,
3033
                    'linksto' => 0,
3034
                    'tag' => '',
3035
                    'user_ip' => '',
3036
                ];
3037
3038
                $new_id = Database::insert($table_wiki, $params);
3039
3040
                if ($new_id) {
3041
                    $sql = "UPDATE $table_wiki SET page_id = '$new_id', id = iid
3042
                            WHERE c_id = ".$this->destination_course_id." AND iid = '$new_id'";
3043
                    Database::query($sql);
3044
3045
                    $this->course->resources[RESOURCE_WIKI][$id]->destination_id = $new_id;
3046
3047
                    // we also add an entry in wiki_conf
3048
                    $params = [
3049
                        'c_id' => $this->destination_course_id,
3050
                        'page_id' => $new_id,
3051
                        'task' => '',
3052
                        'feedback1' => '',
3053
                        'feedback2' => '',
3054
                        'feedback3' => '',
3055
                        'fprogress1' => '',
3056
                        'fprogress2' => '',
3057
                        'fprogress3' => '',
3058
                        'max_size' => 0,
3059
                        'max_text' => 0,
3060
                        'max_version' => 0,
3061
                        'startdate_assig' => null,
3062
                        'enddate_assig' => null,
3063
                        'delayedsubmit' => 0,
3064
                    ];
3065
3066
                    Database::insert($table_wiki_conf, $params);
3067
                }
3068
            }
3069
        }
3070
    }
3071
3072
    /**
3073
     * Restore Thematics
3074
     * @param int $session_id
3075
     */
3076
    public function restore_thematic($session_id = 0)
3077
    {
3078
        if ($this->course->has_resources(RESOURCE_THEMATIC)) {
3079
            $table_thematic = Database::get_course_table(TABLE_THEMATIC);
3080
            $table_thematic_advance = Database::get_course_table(TABLE_THEMATIC_ADVANCE);
3081
            $table_thematic_plan = Database::get_course_table(TABLE_THEMATIC_PLAN);
3082
3083
            $resources = $this->course->resources;
3084
            foreach ($resources[RESOURCE_THEMATIC] as $id => $thematic) {
3085
3086
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
3087
                $thematic->params['content'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
3088
                    $thematic->params['content'],
3089
                    $this->course->code,
3090
                    $this->course->destination_path,
3091
                    $this->course->backup_path,
3092
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Chamilo\CourseBundle\Component\CourseCopy\Course.

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

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

Loading history...
3093
                );
3094
                $thematic->params['c_id'] = $this->destination_course_id;
3095
                unset($thematic->params['id']);
3096
                unset($thematic->params['iid']);
3097
3098
                $last_id = Database::insert($table_thematic, $thematic->params, false);
3099
3100
                if ($last_id) {
3101
3102
                    $sql = "UPDATE $table_thematic SET id = iid WHERE iid = $last_id";
3103
                    Database::query($sql);
3104
3105
                    api_item_property_update(
3106
                        $this->destination_course_info,
3107
                        'thematic',
3108
                        $last_id,
3109
                        "ThematicAdded",
3110
                        api_get_user_id()
3111
                    );
3112
3113 View Code Duplication
                    foreach ($thematic->thematic_advance_list as $thematic_advance) {
3114
                        unset($thematic_advance['id']);
3115
                        unset($thematic_advance['iid']);
3116
                        $thematic_advance['attendance_id'] = 0;
3117
                        $thematic_advance['thematic_id'] = $last_id;
3118
                        $thematic_advance['c_id'] = $this->destination_course_id;
3119
3120
                        $my_id = Database::insert(
3121
                            $table_thematic_advance,
3122
                            $thematic_advance,
3123
                            false
3124
                        );
3125
3126
                        if ($my_id) {
3127
                            $sql = "UPDATE $table_thematic_advance SET id = iid WHERE iid = $my_id";
3128
                            Database::query($sql);
3129
3130
                            api_item_property_update(
3131
                                $this->destination_course_info,
3132
                                'thematic_advance',
3133
                                $my_id,
3134
                                'ThematicAdvanceAdded',
3135
                                api_get_user_id()
3136
                            );
3137
                        }
3138
                    }
3139
3140 View Code Duplication
                    foreach ($thematic->thematic_plan_list as $thematic_plan) {
3141
                        unset($thematic_plan['id']);
3142
                        unset($thematic_plan['iid']);
3143
                        $thematic_plan['thematic_id'] = $last_id;
3144
                        $thematic_plan['c_id'] = $this->destination_course_id;
3145
                        $my_id = Database::insert($table_thematic_plan, $thematic_plan, false);
3146
3147
                        if ($my_id) {
3148
                            $sql = "UPDATE $table_thematic_plan SET id = iid WHERE iid = $my_id";
3149
                            Database::query($sql);
3150
3151
                            api_item_property_update(
3152
                                $this->destination_course_info,
3153
                                'thematic_plan',
3154
                                $my_id,
3155
                                'ThematicPlanAdded',
3156
                                api_get_user_id()
3157
                            );
3158
                        }
3159
                    }
3160
                }
3161
            }
3162
        }
3163
    }
3164
3165
    /**
3166
     * Restore Attendance
3167
     * @param int $session_id
3168
     */
3169
    public function restore_attendance($session_id = 0)
3170
    {
3171
        if ($this->course->has_resources(RESOURCE_ATTENDANCE)) {
3172
            $table_attendance = Database::get_course_table(TABLE_ATTENDANCE);
3173
            $table_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR);
3174
3175
            $resources = $this->course->resources;
3176
            foreach ($resources[RESOURCE_ATTENDANCE] as $id => $obj) {
3177
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
3178
                $obj->params['description'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
3179
                    $obj->params['description'],
3180
                    $this->course->code,
3181
                    $this->course->destination_path,
3182
                    $this->course->backup_path,
3183
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Chamilo\CourseBundle\Component\CourseCopy\Course.

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

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

Loading history...
3184
                );
3185
3186
                unset($obj->params['id']);
3187
                unset($obj->params['iid']);
3188
                $obj->params['c_id'] = $this->destination_course_id;
3189
                $last_id = Database::insert($table_attendance, $obj->params);
3190
3191
                if (is_numeric($last_id)) {
3192
                    $sql = "UPDATE $table_attendance SET id = iid WHERE iid = $last_id";
3193
                    Database::query($sql);
3194
3195
                    $this->course->resources[RESOURCE_ATTENDANCE][$id]->destination_id = $last_id;
3196
3197
                    api_item_property_update(
3198
                        $this->destination_course_info,
3199
                        TOOL_ATTENDANCE,
3200
                        $last_id,
3201
                        "AttendanceAdded",
3202
                        api_get_user_id()
3203
                    );
3204
3205
                    foreach ($obj->attendance_calendar as $attendance_calendar) {
3206
                        unset($attendance_calendar['id']);
3207
                        unset($attendance_calendar['iid']);
3208
3209
                        $attendance_calendar['attendance_id'] = $last_id;
3210
                        $attendance_calendar['c_id'] = $this->destination_course_id;
3211
                        $attendanceCalendarId = Database::insert(
3212
                            $table_attendance_calendar,
3213
                            $attendance_calendar
3214
                        );
3215
3216
                        $sql = "UPDATE $table_attendance_calendar SET id = iid WHERE iid = $attendanceCalendarId";
3217
                        Database::query($sql);
3218
                    }
3219
                }
3220
            }
3221
        }
3222
    }
3223
3224
    /**
3225
     * Restore Works
3226
     * @param int $sessionId
3227
     */
3228
    public function restore_works($sessionId = 0)
3229
    {
3230
        require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
3231
        if ($this->course->has_resources(RESOURCE_WORK)) {
3232
            $table_work_assignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
3233
3234
            $resources = $this->course->resources;
3235
            foreach ($resources[RESOURCE_WORK] as $obj) {
3236
3237
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
3238
                $obj->params['description'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
3239
                    $obj->params['description'],
3240
                    $this->course->code,
3241
                    $this->course->destination_path,
3242
                    $this->course->backup_path,
3243
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Chamilo\CourseBundle\Component\CourseCopy\Course.

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

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

Loading history...
3244
                );
3245
3246
                $id_work = $obj->params['id'];
3247
                $obj->params['id'] = null;
3248
                $obj->params['c_id'] = $this->destination_course_info['real_id'];
3249
3250
                // re-create dir
3251
                // @todo check security against injection of dir in crafted course backup here!
3252
                $path = $obj->params['url'];
3253
                $path = '/'.str_replace('/', '', substr($path, 1));
3254
3255
                $workData = array();
3256
                switch ($this->file_option) {
3257
                    case FILE_SKIP:
3258
                        $workData = get_work_data_by_path(
3259
                            $path,
3260
                            $this->destination_course_info['real_id']
3261
                        );
3262
                        if (!empty($workData)) {
3263
                            continue;
3264
                        }
3265
                        break;
3266
                    case FILE_OVERWRITE:
3267
                        // Creating folder.
3268
                        $workData = get_work_data_by_path(
3269
                            $path,
3270
                            $this->destination_course_info['real_id']
3271
                        );
3272
                        break;
3273
                    case FILE_RENAME:
3274
                        $obj->params['new_dir'] = $obj->params['title'];
3275
3276
                        if (!empty($this->course_origin_id)) {
3277
                            $sql = 'SELECT * FROM '.$table_work_assignment.'
3278
                                    WHERE
3279
                                        c_id = ' . $this->course_origin_id.' AND
3280
                                        publication_id = ' . $id_work;
3281
3282
                            $result = Database::query($sql);
3283
                            $cant = Database::num_rows($result);
3284
                            if ($cant > 0) {
3285
                                $row = Database::fetch_assoc($result);
3286
                            }
3287
3288
                            $obj->params['enableExpiryDate'] = empty($row['expires_on']) ? false : true;
3289
                            $obj->params['enableEndDate'] = empty($row['ends_on']) ? false : true;
3290
                            $obj->params['expires_on'] = $row['expires_on'];
3291
                            $obj->params['ends_on'] = $row['ends_on'];
3292
                            $obj->params['enable_qualification'] = $row['enable_qualification'];
3293
                            $obj->params['add_to_calendar'] = !empty($row['add_to_calendar']) ? 1 : 0;
3294
3295
                            if (empty($workData)) {
3296
                                addDir(
3297
                                    $obj->params,
3298
                                    api_get_user_id(),
3299
                                    $this->destination_course_info,
3300
                                    0,
3301
                                    $sessionId
3302
                                );
3303
                            } else {
3304
                                $workId = $workData['iid'];
3305
                                updateWork(
3306
                                    $workId,
3307
                                    $obj->params,
3308
                                    $this->destination_course_info,
3309
                                    $sessionId
3310
                                );
3311
                                updatePublicationAssignment(
3312
                                    $workId,
3313
                                    $obj->params,
3314
                                    $this->destination_course_info,
3315
                                    0
3316
                                );
3317
                            }
3318
                        }
3319
                        break;
3320
                }
3321
            }
3322
        }
3323
    }
3324
3325
    /**
3326
     * Restore gradebook
3327
     * @param int $sessionId
3328
     * @return  bool
3329
     */
3330
    public function restore_gradebook($sessionId = 0)
3331
    {
3332
        if (in_array($this->file_option, [FILE_SKIP, FILE_RENAME])) {
3333
            return false;
3334
        }
3335
        // if overwrite
3336
        if ($this->course->has_resources(RESOURCE_GRADEBOOK)) {
3337
            $resources = $this->course->resources;
3338
            $destinationCourseCode = $this->destination_course_info['code'];
3339
            // Delete destination gradebook
3340
            $cats = \Category:: load(
3341
                null,
3342
                null,
3343
                $destinationCourseCode,
3344
                null,
3345
                null,
3346
                $sessionId
3347
            );
3348
3349
            if (!empty($cats)) {
3350
                /** @var \Category $cat */
3351
                foreach ($cats as $cat) {
3352
                    $cat->delete_all();
3353
                }
3354
            }
3355
3356
            /** @var GradeBookBackup $obj */
3357
            foreach ($resources[RESOURCE_GRADEBOOK] as $id => $obj) {
3358
                if (!empty($obj->categories)) {
3359
                    $categoryIdList = [];
3360
                    /** @var \Category $cat */
3361
                    foreach ($obj->categories as $cat) {
3362
                        $cat->set_course_code($destinationCourseCode);
3363
                        $cat->set_session_id($sessionId);
3364
3365
                        $parentId = $cat->get_parent_id();
3366
                        if (!empty($parentId)) {
3367
                            if (isset($categoryIdList[$parentId])) {
3368
                                $cat->set_parent_id($categoryIdList[$parentId]);
3369
                            }
3370
                        }
3371
                        $oldId = $cat->get_id();
3372
                        $categoryId = $cat->add();
3373
                        $categoryIdList[$oldId] = $categoryId;
3374
                        if (!empty($cat->evaluations)) {
3375
                            /** @var \Evaluation $evaluation */
3376
                            foreach ($cat->evaluations as $evaluation) {
3377
                                $evaluation->set_category_id($categoryId);
3378
                                $evaluation->set_course_code($destinationCourseCode);
3379
                                $evaluation->setSessionId($sessionId);
3380
                                $evaluation->add();
3381
                            }
3382
                        }
3383
3384
                        if (!empty($cat->links)) {
3385
                            /** @var \AbstractLink $link */
3386
                            foreach ($cat->links as $link) {
3387
                                $link->set_category_id($categoryId);
3388
                                $link->set_course_code($destinationCourseCode);
3389
                                $link->set_session_id($sessionId);
3390
                                $import = false;
3391
                                $itemId = $link->get_ref_id();
3392
                                switch ($link->get_type()) {
3393
                                    case LINK_EXERCISE:
3394
                                        $type = RESOURCE_QUIZ;
3395
                                        break;
3396
                                    /*case LINK_DROPBOX:
3397
                                        break;*/
3398
                                    case LINK_STUDENTPUBLICATION:
3399
                                        $type = RESOURCE_WORK;
3400
                                        break;
3401
                                    case LINK_LEARNPATH:
3402
                                        $type = RESOURCE_LEARNPATH;
3403
                                        break;
3404
                                    case LINK_FORUM_THREAD:
3405
                                        $type = RESOURCE_FORUMTOPIC;
3406
                                        break;
3407
                                    case LINK_ATTENDANCE:
3408
                                        $type = RESOURCE_ATTENDANCE;
3409
                                        break;
3410
                                    case LINK_SURVEY:
3411
                                        $type = RESOURCE_ATTENDANCE;
3412
                                        break;
3413
                                    case LINK_HOTPOTATOES:
3414
                                        $type = RESOURCE_QUIZ;
3415
                                        break;
3416
                                }
3417
3418
                                 if ($this->course->has_resources($type) &&
3419
                                    isset($this->course->resources[$type][$itemId])
3420
                                ) {
3421
                                    $item = $this->course->resources[$type][$itemId];
3422
                                    if ($item && $item->is_restored()) {
3423
                                        $link->set_ref_id($item->destination_id);
3424
                                        $import = true;
3425
                                    }
3426
                                }
3427
3428
                                if ($import) {
3429
                                    $link->add();
3430
                                }
3431
                            }
3432
                        }
3433
                    }
3434
                }
3435
            }
3436
        }
3437
    }
3438
3439
    /**
3440
     * Restore course assets (not included in documents)
3441
     */
3442
    public function restore_assets()
3443
    {
3444
        if ($this->course->has_resources(RESOURCE_ASSET)) {
3445
            $resources = $this->course->resources;
3446
            $path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/';
3447
3448
            foreach ($resources[RESOURCE_ASSET] as $id => $asset) {
3449
                if (is_file($this->course->backup_path.'/'.$asset->path) &&
3450
                    is_readable($this->course->backup_path.'/'.$asset->path) &&
3451
                    is_dir(dirname($path.$asset->path)) &&
3452
                    is_writeable(dirname($path.$asset->path))
3453
                ) {
3454
                    switch ($this->file_option) {
3455
                        case FILE_SKIP:
3456
                            continue;
3457
                        case FILE_OVERWRITE:
3458
                            copy(
3459
                                $this->course->backup_path.'/'.$asset->path,
3460
                                $path.$asset->path
3461
                            );
3462
                            break;
3463
                    }
3464
                }
3465
            }
3466
        }
3467
    }
3468
3469
3470
    /**
3471
     * @param string $str
3472
     * @return string
3473
     */
3474
    public function DBUTF8($str)
3475
    {
3476
        if (UTF8_CONVERT) {
3477
            $str = utf8_encode($str);
3478
        }
3479
        return $str;
3480
    }
3481
3482
    /**
3483
     * @param string $str
3484
     * @return string
3485
     */
3486
    public function DBUTF8escapestring($str)
3487
    {
3488
        if (UTF8_CONVERT) {
3489
            $str = utf8_encode($str);
3490
        }
3491
        return Database::escape_string($str);
3492
    }
3493
3494
    /**
3495
     * @param array $array
3496
     * @return mixed
3497
     */
3498
    public function DBUTF8_array($array)
3499
    {
3500
        if (UTF8_CONVERT) {
3501
            foreach ($array as &$item) {
3502
                $item = utf8_encode($item);
3503
            }
3504
            return $array;
3505
        } else {
3506
            return $array;
3507
        }
3508
    }
3509
3510
    /**
3511
     * @param int $groupId
3512
     * @return array
3513
     */
3514
    public function checkGroupId($groupId)
3515
    {
3516
        return \GroupManager::get_group_properties($groupId);
3517
    }
3518
3519
    /**
3520
     * Check if user exist otherwise use current user
3521
     * @param int $userId
3522
     * @param bool $returnNull
3523
     *
3524
     * @return int
3525
     */
3526
    private function checkUserId($userId, $returnNull = false)
3527
    {
3528
        if (!empty($userId)) {
3529
            $userInfo = api_get_user_info($userId);
3530
            if (empty($userInfo)) {
3531
3532
                return api_get_user_id();
3533
            }
3534
        }
3535
3536
        if ($returnNull) {
3537
            return null;
3538
        }
3539
3540
        if (empty($userId)) {
3541
3542
            return api_get_user_id();
3543
        }
3544
3545
        return $userId;
3546
    }
3547
}
3548