Completed
Push — master ( 27e209...a08afa )
by Julito
186:04 queued 150:53
created

AddCourse::generateToolId()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
nc 3
nop 1
dl 0
loc 18
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CourseBundle\Entity\CToolIntro;
5
6
/**
7
 * Class AddCourse
8
 */
9
class AddCourse
10
{
11
    /**
12
     * Defines the four needed keys to create a course based on several parameters.
13
     * @param string    The code you want for this course
14
     * @param string    Prefix added for ALL keys
15
     * @param string    Prefix added for databases only
16
     * @param string    Prefix added for paths only
17
     * @param bool      Add unique prefix
18
     * @param bool      Use code-independent keys
19
     * @return array    An array with the needed keys ['currentCourseCode'], ['currentCourseId'], ['currentCourseDbName'], ['currentCourseRepository']
20
     * @todo Eliminate the global variables.
21
     * @assert (null) === false
22
     */
23
    public static function define_course_keys(
24
        $wanted_code,
25
        $prefix_for_all = '',
26
        $prefix_for_base_name = '',
0 ignored issues
show
Unused Code introduced by
The parameter $prefix_for_base_name is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

26
        /** @scrutinizer ignore-unused */ $prefix_for_base_name = '',

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
27
        $prefix_for_path = '',
28
        $add_unique_prefix = false,
29
        $use_code_indepedent_keys = true
30
    ) {
31
        $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
32
        $wanted_code = CourseManager::generate_course_code($wanted_code);
33
        $keys_course_code = $wanted_code;
34
        if (!$use_code_indepedent_keys) {
35
            $wanted_code = '';
36
        }
37
38
        if ($add_unique_prefix) {
39
            $unique_prefix = substr(md5(uniqid(rand())), 0, 10);
0 ignored issues
show
Bug introduced by
The call to rand() has too few arguments starting with min. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

39
            $unique_prefix = substr(md5(uniqid(/** @scrutinizer ignore-call */ rand())), 0, 10);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
40
        } else {
41
            $unique_prefix = '';
42
        }
43
44
        $keys = [];
45
        $final_suffix = ['CourseId' => '', 'CourseDb' => '', 'CourseDir' => ''];
46
        $limit_numb_try = 100;
47
        $keys_are_unique = false;
48
        $try_new_fsc_id = $try_new_fsc_db = $try_new_fsc_dir = 0;
49
50
        while (!$keys_are_unique) {
51
            $keys_course_id = $prefix_for_all.$unique_prefix.$wanted_code.$final_suffix['CourseId'];
52
            $keys_course_repository = $prefix_for_path.$unique_prefix.$wanted_code.$final_suffix['CourseDir'];
53
            $keys_are_unique = true;
54
55
            // Check whether they are unique.
56
            $query = "SELECT 1 FROM $course_table 
57
                      WHERE code='".$keys_course_id."' 
58
                      LIMIT 0, 1";
59
            $result = Database::query($query);
60
61
            if (Database::num_rows($result)) {
62
                $keys_are_unique = false;
63
                $try_new_fsc_id++;
64
                $final_suffix['CourseId'] = substr(md5(uniqid(rand())), 0, 4);
65
            }
66
            if (file_exists(api_get_path(SYS_COURSE_PATH).$keys_course_repository)) {
67
                $keys_are_unique = false;
68
                $try_new_fsc_dir++;
69
                $final_suffix['CourseDir'] = substr(md5(uniqid(rand())), 0, 4);
70
            }
71
72
            if (($try_new_fsc_id + $try_new_fsc_db + $try_new_fsc_dir) > $limit_numb_try) {
73
                return $keys;
74
            }
75
        }
76
77
        $keys['currentCourseCode'] = $keys_course_code;
78
        $keys['currentCourseId'] = $keys_course_id;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $keys_course_id does not seem to be defined for all execution paths leading up to this point.
Loading history...
79
        $keys['currentCourseRepository'] = $keys_course_repository;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $keys_course_repository does not seem to be defined for all execution paths leading up to this point.
Loading history...
80
81
        return $keys;
82
    }
83
84
    /**
85
     * Initializes a file repository for a newly created course.
86
     * @param string Course repository
87
     * @param string Course code
88
     * @return int 0
89
     * @assert (null,null) === false
90
     */
91
    public static function prepare_course_repository($course_repository)
92
    {
93
        $perm = api_get_permissions_for_new_directories();
94
        $perm_file = api_get_permissions_for_new_files();
95
        $htmlpage = "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <title>Not authorized</title>\n  </head>\n  <body>\n  </body>\n</html>";
96
        $cp = api_get_path(SYS_COURSE_PATH).$course_repository;
97
98
        //Creating document folder
99
        mkdir($cp, $perm);
100
        mkdir($cp.'/document', $perm);
101
        $cpt = $cp.'/document/index.html';
102
        $fd = fopen($cpt, 'w');
103
        fwrite($fd, $htmlpage);
0 ignored issues
show
Bug introduced by
It seems like $fd can also be of type false; however, parameter $handle of fwrite() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

103
        fwrite(/** @scrutinizer ignore-type */ $fd, $htmlpage);
Loading history...
104
        fclose($fd);
0 ignored issues
show
Bug introduced by
It seems like $fd can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

104
        fclose(/** @scrutinizer ignore-type */ $fd);
Loading history...
105
106
        /*
107
        @chmod($cpt, $perm_file);
108
        @copy($cpt, $cp . '/document/index.html');
109
        mkdir($cp . '/document/images', $perm);
110
        @copy($cpt, $cp . '/document/images/index.html');
111
        mkdir($cp . '/document/images/gallery/', $perm);
112
        @copy($cpt, $cp . '/document/images/gallery/index.html');
113
        mkdir($cp . '/document/shared_folder/', $perm);
114
        @copy($cpt, $cp . '/document/shared_folder/index.html');
115
        mkdir($cp . '/document/audio', $perm);
116
        @copy($cpt, $cp . '/document/audio/index.html');
117
        mkdir($cp . '/document/flash', $perm);
118
        @copy($cpt, $cp . '/document/flash/index.html');
119
        mkdir($cp . '/document/video', $perm);
120
        @copy($cpt, $cp . '/document/video/index.html');    */
121
122
        //Creatind dropbox folder
123
        mkdir($cp.'/dropbox', $perm);
124
        $cpt = $cp.'/dropbox/index.html';
125
        $fd = fopen($cpt, 'w');
126
        fwrite($fd, $htmlpage);
127
        fclose($fd);
128
        @chmod($cpt, $perm_file);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for chmod(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

128
        /** @scrutinizer ignore-unhandled */ @chmod($cpt, $perm_file);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
129
        mkdir($cp.'/group', $perm);
130
        @copy($cpt, $cp.'/group/index.html');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for copy(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

130
        /** @scrutinizer ignore-unhandled */ @copy($cpt, $cp.'/group/index.html');

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
131
        mkdir($cp.'/page', $perm);
132
        @copy($cpt, $cp.'/page/index.html');
133
        mkdir($cp.'/scorm', $perm);
134
        @copy($cpt, $cp.'/scorm/index.html');
135
        mkdir($cp.'/upload', $perm);
136
        @copy($cpt, $cp.'/upload/index.html');
137
        mkdir($cp.'/upload/forum', $perm);
138
        @copy($cpt, $cp.'/upload/forum/index.html');
139
        mkdir($cp.'/upload/forum/images', $perm);
140
        @copy($cpt, $cp.'/upload/forum/images/index.html');
141
        mkdir($cp.'/upload/test', $perm);
142
        @copy($cpt, $cp.'/upload/test/index.html');
143
        mkdir($cp.'/upload/blog', $perm);
144
        @copy($cpt, $cp.'/upload/blog/index.html');
145
        mkdir($cp.'/upload/learning_path', $perm);
146
        @copy($cpt, $cp.'/upload/learning_path/index.html');
147
        mkdir($cp.'/upload/learning_path/images', $perm);
148
        @copy($cpt, $cp.'/upload/learning_path/images/index.html');
149
        mkdir($cp.'/upload/calendar', $perm);
150
        @copy($cpt, $cp.'/upload/calendar/index.html');
151
        mkdir($cp.'/upload/calendar/images', $perm);
152
        @copy($cpt, $cp.'/upload/calendar/images/index.html');
153
        mkdir($cp.'/work', $perm);
154
        @copy($cpt, $cp.'/work/index.html');
155
        mkdir($cp.'/upload/announcements', $perm);
156
        @copy($cpt, $cp.'/upload/announcements/index.html');
157
        mkdir($cp.'/upload/announcements/images', $perm);
158
        @copy($cpt, $cp.'/upload/announcements/images/index.html');
159
160
        //Oral expression question type
161
        mkdir($cp.'/exercises', $perm);
162
        @copy($cpt, $cp.'/exercises/index.html');
163
164
        // Create .htaccess in the dropbox directory.
165
        $fp = fopen($cp.'/dropbox/.htaccess', 'w');
166
        fwrite(
167
            $fp,
168
            "AuthName AllowLocalAccess
169
                       AuthType Basic
170
171
                       order deny,allow
172
                       deny from all
173
174
                       php_flag zlib.output_compression off"
175
        );
176
        fclose($fp);
177
178
        // Build index.php of the course.
179
        /*$fd = fopen($cp . '/index.php', 'w');
180
181
        // str_replace() removes \r that cause squares to appear at the end of each line
182
        //@todo fix the harcoded include
183
        $string = str_replace(
184
            "\r",
185
            "",
186
            "<?" . "php
187
        \$cidReq = \"$course_code\";
188
        \$dbname = \"$course_code\";
189
190
        include(\"" . api_get_path(SYS_CODE_PATH) . "course_home/course_home.php\");
191
        ?>"
192
        );
193
        fwrite($fd, $string);
194
        @chmod($cp . '/index.php', $perm_file);*/
195
        return 0;
196
    }
197
198
    /**
199
     * Gets an array with all the course tables (deprecated?)
200
     * @return string[]
201
     * @assert (null) !== null
202
     */
203
    public static function get_course_tables()
204
    {
205
        $tables = [];
206
        $tables[] = 'item_property';
207
        $tables[] = 'tool';
208
        $tables[] = 'tool_intro';
209
        $tables[] = 'group_info';
210
        $tables[] = 'group_category';
211
        $tables[] = 'group_rel_user';
212
        $tables[] = 'group_rel_tutor';
213
        $tables[] = 'userinfo_content';
214
        $tables[] = 'userinfo_def';
215
        $tables[] = 'course_description';
216
        $tables[] = 'calendar_event';
217
        $tables[] = 'calendar_event_repeat';
218
        $tables[] = 'calendar_event_repeat_not';
219
        $tables[] = 'calendar_event_attachment';
220
        $tables[] = 'announcement';
221
        $tables[] = 'announcement_attachment';
222
        $tables[] = 'resource';
223
        $tables[] = 'student_publication';
224
        $tables[] = 'student_publication_assignment';
225
        $tables[] = 'document';
226
        $tables[] = 'forum_category';
227
        $tables[] = 'forum_forum';
228
        $tables[] = 'forum_thread';
229
        $tables[] = 'forum_post';
230
        $tables[] = 'forum_mailcue';
231
        $tables[] = 'forum_attachment';
232
        $tables[] = 'forum_notification';
233
        $tables[] = 'forum_thread_qualify';
234
        $tables[] = 'forum_thread_qualify_log';
235
        $tables[] = 'link';
236
        $tables[] = 'link_category';
237
        $tables[] = 'online_connected';
238
        $tables[] = 'online_link';
239
        $tables[] = 'chat_connected';
240
        $tables[] = 'quiz';
241
        $tables[] = 'quiz_rel_question';
242
        $tables[] = 'quiz_question';
243
        $tables[] = 'quiz_answer';
244
        $tables[] = 'quiz_question_option';
245
        $tables[] = 'quiz_question_category';
246
        $tables[] = 'quiz_question_rel_category';
247
        $tables[] = 'dropbox_post';
248
        $tables[] = 'dropbox_file';
249
        $tables[] = 'dropbox_person';
250
        $tables[] = 'dropbox_category';
251
        $tables[] = 'dropbox_feedback';
252
        $tables[] = 'lp';
253
        $tables[] = 'lp_item';
254
        $tables[] = 'lp_view';
255
        $tables[] = 'lp_item_view';
256
        $tables[] = 'lp_iv_interaction';
257
        $tables[] = 'lp_iv_objective';
258
        $tables[] = 'blog';
259
        $tables[] = 'blog_comment';
260
        $tables[] = 'blog_post';
261
        $tables[] = 'blog_rating';
262
        $tables[] = 'blog_rel_user';
263
        $tables[] = 'blog_task';
264
        $tables[] = 'blog_task_rel_user';
265
        $tables[] = 'blog_attachment';
266
        $tables[] = 'permission_group';
267
        $tables[] = 'permission_user';
268
        $tables[] = 'permission_task';
269
        $tables[] = 'role';
270
        $tables[] = 'role_group';
271
        $tables[] = 'role_permissions';
272
        $tables[] = 'role_user';
273
        $tables[] = 'survey';
274
        $tables[] = 'survey_question';
275
        $tables[] = 'survey_question_option';
276
        $tables[] = 'survey_invitation';
277
        $tables[] = 'survey_answer';
278
        $tables[] = 'survey_group';
279
        $tables[] = 'wiki';
280
        $tables[] = 'wiki_conf';
281
        $tables[] = 'wiki_discuss';
282
        $tables[] = 'wiki_mailcue';
283
        $tables[] = 'course_setting';
284
        $tables[] = 'glossary';
285
        $tables[] = 'notebook';
286
        $tables[] = 'attendance';
287
        $tables[] = 'attendance_sheet';
288
        $tables[] = 'attendance_calendar';
289
        $tables[] = 'attendance_result';
290
        $tables[] = 'attendance_sheet_log';
291
        $tables[] = 'thematic';
292
        $tables[] = 'thematic_plan';
293
        $tables[] = 'thematic_advance';
294
295
        return $tables;
296
    }
297
298
    /**
299
     * Executed only before create_course_tables()
300
     * @return void
301
     * @assert (null) === null
302
     */
303
    public static function drop_course_tables()
304
    {
305
        $list = self::get_course_tables();
306
        foreach ($list as $table) {
307
            $sql = "DROP TABLE IF EXISTS ".DB_COURSE_PREFIX.$table;
308
            Database::query($sql);
309
        }
310
    }
311
312
313
    /**
314
     * Returns a list of all files in the given course directory. The requested
315
     * directory will be checked against a "checker" directory to avoid access to
316
     * protected/unauthorized files
317
     * @param string Complete path to directory we want to list
318
     * @param array A list of files to which we want to add the files found
319
     * @param string Type of base directory from which we want to recover the files
320
     * @param string $path
321
     * @param string $media
322
     * @return array
323
     * @assert (null,null,null) === false
324
     * @assert ('abc',array(),'') === array()
325
     */
326
    public static function browse_folders($path, $files, $media)
327
    {
328
        if ($media == 'images') {
329
            $code_path = api_get_path(SYS_CODE_PATH).'default_course_document/images/';
330
        }
331
        if ($media == 'audio') {
332
            $code_path = api_get_path(SYS_CODE_PATH).'default_course_document/audio/';
333
        }
334
        if ($media == 'flash') {
335
            $code_path = api_get_path(SYS_CODE_PATH).'default_course_document/flash/';
336
        }
337
        if ($media == 'video') {
338
            $code_path = api_get_path(SYS_CODE_PATH).'default_course_document/video/';
339
        }
340
        if ($media == 'certificates') {
341
            $code_path = api_get_path(SYS_CODE_PATH).'default_course_document/certificates/';
342
        }
343
        if (is_dir($path)) {
344
            $handle = opendir($path);
345
            while (false !== ($file = readdir($handle))) {
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $dir_handle of readdir() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

345
            while (false !== ($file = readdir(/** @scrutinizer ignore-type */ $handle))) {
Loading history...
346
                if (is_dir($path.$file) && strpos($file, '.') !== 0) {
347
                    $files[]['dir'] = str_replace(
348
                        $code_path,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $code_path does not seem to be defined for all execution paths leading up to this point.
Loading history...
349
                        '',
350
                        $path.$file.'/'
351
                    );
352
                    $files = self::browse_folders(
353
                        $path.$file.'/',
354
                        $files,
355
                        $media
356
                    );
357
                } elseif (is_file($path.$file) && strpos($file, '.') !== 0) {
358
                    $files[]['file'] = str_replace(
359
                        $code_path,
360
                        '',
361
                        $path.$file
362
                    );
363
                }
364
            }
365
        }
366
        return $files;
367
    }
368
369
    /**
370
     * Sorts pictures by type (used?)
371
     * @param array List of files (sthg like array(0=>array('png'=>1)))
372
     * @param string $type
373
     * @return array The received array without files not matching type
374
     * @assert (array(),null) === array()
375
     */
376
    public static function sort_pictures($files, $type)
377
    {
378
        $pictures = [];
379
        foreach ($files as $value) {
380
            if (isset($value[$type]) && $value[$type] != '') {
381
                $pictures[][$type] = $value[$type];
382
            }
383
        }
384
        return $pictures;
385
    }
386
387
    /**
388
     * Fills the course database with some required content and example content.
389
     * @param int Course (int) ID
390
     * @param string Course directory name (e.g. 'ABC')
391
     * @param string Language used for content (e.g. 'spanish')
392
     * @param bool Whether to fill the course with example content
393
     * @param int $authorId
394
     * @return bool False on error, true otherwise
395
     * @version 1.2
396
     * @assert (null, '', '', null) === false
397
     * @assert (1, 'ABC', null, null) === false
398
     * @assert (1, 'TEST', 'spanish', true) === true
399
     */
400
    public static function fill_db_course(
401
        $course_id,
402
        $course_repository,
403
        $language,
0 ignored issues
show
Unused Code introduced by
The parameter $language is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

403
        /** @scrutinizer ignore-unused */ $language,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
404
        $fill_with_exemplary_content = null,
405
        $authorId = 0
406
    ) {
407
        if (is_null($fill_with_exemplary_content)) {
408
            $fill_with_exemplary_content = api_get_setting('example_material_course_creation') != 'false';
409
        }
410
        $course_id = intval($course_id);
411
412
        if (empty($course_id)) {
413
            return false;
414
        }
415
416
        $courseInfo = api_get_course_info_by_id($course_id);
417
        $authorId = empty($authorId) ? api_get_user_id() : (int) $authorId;
418
419
        $tbl_course_homepage = Database::get_course_table(TABLE_TOOL_LIST);
420
        $TABLEGROUPCATEGORIES = Database::get_course_table(TABLE_GROUP_CATEGORY);
421
        $TABLEITEMPROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY);
422
        $TABLETOOLDOCUMENT = Database::get_course_table(TABLE_DOCUMENT);
423
        $TABLESETTING = Database::get_course_table(TABLE_COURSE_SETTING);
424
        $TABLEGRADEBOOK = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
425
        $TABLEGRADEBOOKLINK = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
426
        $visible_for_course_admin = 0;
427
        /*    Course tools  */
428
        Database::query(
429
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
430
            VALUES ($course_id, 1, '".TOOL_COURSE_DESCRIPTION."','course_description/','info.gif','".self::string2binary(
431
                api_get_setting(
432
                    'course_create_active_tools',
433
                    'course_description'
434
                )
435
            )."','0','squaregrey.gif', 0,'_self','authoring','0')"
436
        );
437
        Database::query(
438
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
439
            VALUES ($course_id, 2, '".TOOL_CALENDAR_EVENT."','calendar/agenda.php','agenda.gif','".self::string2binary(
440
                api_get_setting('course_create_active_tools', 'agenda')
441
            )."','0','squaregrey.gif',0,'_self','interaction','0')"
442
        );
443
        Database::query(
444
            "INSERT INTO $tbl_course_homepage  (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
445
            VALUES ($course_id, 3, '".TOOL_DOCUMENT."','document/document.php','folder_document.gif','".self::string2binary(
446
                api_get_setting('course_create_active_tools', 'documents')
447
            )."','0','squaregrey.gif',0,'_self','authoring','0')"
448
        );
449
        Database::query(
450
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
451
            VALUES ($course_id, 4, '".TOOL_LEARNPATH."','lp/lp_controller.php','scorms.gif','".self::string2binary(
452
                api_get_setting('course_create_active_tools', 'learning_path')
453
            )."','0','squaregrey.gif',0,'_self','authoring','0')"
454
        );
455
        Database::query(
456
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
457
             VALUES ($course_id, 5, '".TOOL_LINK."','link/link.php','links.gif','".self::string2binary(
458
                api_get_setting('course_create_active_tools', 'links')
459
            )."','0','squaregrey.gif',0,'_self','authoring','0')"
460
        );
461
        Database::query(
462
            "INSERT INTO $tbl_course_homepage  (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
463
            VALUES  ($course_id, 6, '".TOOL_QUIZ."','exercise/exercise.php','quiz.gif','".self::string2binary(
464
                api_get_setting('course_create_active_tools', 'quiz')
465
            )."','0','squaregrey.gif',0,'_self','authoring','0')"
466
        );
467
        Database::query(
468
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
469
            VALUES ($course_id, 7, '".TOOL_ANNOUNCEMENT."','announcements/announcements.php','valves.gif','".self::string2binary(
470
                api_get_setting('course_create_active_tools', 'announcements')
471
            )."','0','squaregrey.gif', 0,'_self','authoring','0')"
472
        );
473
        Database::query(
474
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
475
            VALUES ($course_id, 8, '".TOOL_FORUM."','forum/index.php','forum.gif','".self::string2binary(
476
                api_get_setting('course_create_active_tools', 'forums')
477
            )."','0','squaregrey.gif',0,'_self','interaction','0')"
478
        );
479
        Database::query(
480
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
481
            VALUES ($course_id, 9, '".TOOL_DROPBOX."','dropbox/index.php','dropbox.gif','".self::string2binary(
482
                api_get_setting('course_create_active_tools', 'dropbox')
483
            )."','0','squaregrey.gif',0,'_self','interaction','0')"
484
        );
485
        Database::query(
486
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
487
            VALUES ($course_id, 10, '".TOOL_USER."','user/user.php','members.gif','".self::string2binary(
488
                api_get_setting('course_create_active_tools', 'users')
489
            )."','0','squaregrey.gif',0,'_self','interaction','0')"
490
        );
491
        Database::query(
492
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
493
            VALUES ($course_id, 11, '".TOOL_GROUP."','group/group.php','group.gif','".self::string2binary(
494
                api_get_setting('course_create_active_tools', 'groups')
495
            )."','0','squaregrey.gif',0,'_self','interaction','0')"
496
        );
497
        Database::query(
498
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
499
            VALUES ($course_id, 12, '".TOOL_CHAT."','chat/chat.php','chat.gif','".self::string2binary(
500
                api_get_setting('course_create_active_tools', 'chat')
501
            )."','0','squaregrey.gif',0,'_self','interaction','0')"
502
        );
503
        Database::query(
504
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
505
            VALUES ($course_id, 13, '".TOOL_STUDENTPUBLICATION."','work/work.php','works.gif','".self::string2binary(
506
                api_get_setting(
507
                    'course_create_active_tools',
508
                    'student_publications'
509
                )
510
            )."','0','squaregrey.gif',0,'_self','interaction','0')"
511
        );
512
        Database::query(
513
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
514
            VALUES ($course_id, 14, '".TOOL_SURVEY."','survey/survey_list.php','survey.gif','".self::string2binary(
515
                api_get_setting('course_create_active_tools', 'survey')
516
            )."','0','squaregrey.gif',0,'_self','interaction','0')"
517
        );
518
        Database::query(
519
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
520
            VALUES ($course_id, 15, '".TOOL_WIKI."','wiki/index.php','wiki.gif','".self::string2binary(
521
                api_get_setting('course_create_active_tools', 'wiki')
522
            )."','0','squaregrey.gif',0,'_self','interaction','0')"
523
        );
524
        Database::query(
525
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
526
            VALUES ($course_id, 16, '".TOOL_GRADEBOOK."','gradebook/index.php','gradebook.gif','".self::string2binary(
527
                api_get_setting('course_create_active_tools', 'gradebook')
528
            )."','0','squaregrey.gif',0,'_self','authoring','0')"
529
        );
530
        Database::query(
531
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
532
            VALUES ($course_id, 17, '".TOOL_GLOSSARY."','glossary/index.php','glossary.gif','".self::string2binary(
533
                api_get_setting('course_create_active_tools', 'glossary')
534
            )."','0','squaregrey.gif',0,'_self','authoring','0')"
535
        );
536
        Database::query(
537
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
538
            VALUES ($course_id, 18, '".TOOL_NOTEBOOK."','notebook/index.php','notebook.gif','".self::string2binary(
539
                api_get_setting('course_create_active_tools', 'notebook')
540
            )."','0','squaregrey.gif',0,'_self','interaction','0')"
541
        );
542
543
        $setting = intval(self::string2binary(
544
            api_get_setting('course_create_active_tools', 'attendances')
545
        ));
546
547
        Database::query(
548
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
549
            VALUES ($course_id, 19, '".TOOL_ATTENDANCE."','attendance/index.php','attendance.gif','".$setting."','0','squaregrey.gif',0,'_self','authoring','0')"
550
        );
551
        Database::query(
552
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
553
            VALUES ($course_id, 20, '".TOOL_COURSE_PROGRESS."','course_progress/index.php','course_progress.gif','".self::string2binary(
554
                intval(api_get_setting('course_create_active_tools', 'course_progress'))
555
            )."','0','squaregrey.gif',0,'_self','authoring','0')"
556
        );
557
558
        if (api_get_setting('search_enabled') === 'true') {
559
            Database::query(
560
                "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
561
                VALUES ($course_id, 23, '".TOOL_SEARCH."','search/','info.gif','".self::string2binary(
562
                    api_get_setting(
563
                        'course_create_active_tools',
564
                        'enable_search'
565
                    )
566
                )."','0','search.gif',0,'_self','authoring','0')"
567
            );
568
        }
569
570
        $sql = "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
571
                VALUES ($course_id, 24,'".TOOL_BLOGS."','blog/blog_admin.php','blog_admin.gif','".intval(
572
            self::string2binary(
573
                api_get_setting('course_create_active_tools', 'blogs')
574
        )
575
            )."','1','squaregrey.gif',0,'_self','admin','0')";
576
        Database::query($sql);
577
578
        /*  Course homepage tools for course admin only  */
579
        Database::query(
580
            "INSERT INTO $tbl_course_homepage  (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
581
            VALUES ($course_id, 25, '".TOOL_TRACKING."','tracking/courseLog.php','statistics.gif','$visible_for_course_admin','1','', 0,'_self','admin','0')"
582
        );
583
        Database::query(
584
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
585
            VALUES ($course_id, 26, '".TOOL_COURSE_SETTING."','course_info/infocours.php','reference.gif','$visible_for_course_admin','1','', 0,'_self','admin','0')"
586
        );
587
        Database::query(
588
            "INSERT INTO $tbl_course_homepage (c_id, id, name, link, image, visibility, admin, address, added_tool, target, category, session_id)
589
            VALUES ($course_id, 27, '".TOOL_COURSE_MAINTENANCE."','course_info/maintenance.php','backup.gif','$visible_for_course_admin','1','',0,'_self', 'admin','0')"
590
        );
591
592
        $alert = api_get_setting('email_alert_manager_on_new_quiz');
593
        if ($alert === 'true') {
594
            $defaultEmailExerciseAlert = 1;
595
        } else {
596
            $defaultEmailExerciseAlert = 0;
597
        }
598
599
        /* course_setting table (courseinfo tool)   */
600
        $settings = [
601
            'email_alert_manager_on_new_doc' => ['title' => '', 'default' => 0, 'category' => 'work'],
602
            'email_alert_on_new_doc_dropbox' => ['default' => 0, 'category' => 'dropbox'],
603
            'allow_user_edit_agenda' => ['default' => 0, 'category' => 'agenda'],
604
            'allow_user_edit_announcement' => ['default' => 0, 'category' => 'announcement'],
605
            'email_alert_manager_on_new_quiz' => ['default' => $defaultEmailExerciseAlert, 'category' => 'quiz'],
606
            'allow_user_image_forum' => ['default' => 1, 'category' => 'forum'],
607
            'course_theme' => ['default' => '', 'category' => 'theme'],
608
            'allow_learning_path_theme' => ['default' => 1, 'category' => 'theme'],
609
            'allow_open_chat_window' => ['default' => 1, 'category' => 'chat'],
610
            'email_alert_to_teacher_on_new_user_in_course' => ['default' => 0, 'category' =>'registration'],
611
            'allow_user_view_user_list' => ['default' =>1, 'category' =>'user'],
612
            'display_info_advance_inside_homecourse' => ['default' => 1, 'category' =>'thematic_advance'],
613
            'email_alert_students_on_new_homework' => ['default' => 0, 'category' =>'work'],
614
            'enable_lp_auto_launch' => ['default' => 0, 'category' =>'learning_path'],
615
            'pdf_export_watermark_text' => ['default' =>'', 'category' =>'learning_path'],
616
            'allow_public_certificates' => [
617
                'default' => api_get_setting('allow_public_certificates') === 'true' ? 1 : '',
618
                'category' =>'certificates'
619
            ],
620
            'documents_default_visibility' => ['default' =>'visible', 'category' =>'document'],
621
            'show_course_in_user_language' => ['default' => 2, 'category' => null],
622
        ];
623
624
        $counter = 1;
625
        foreach ($settings as $variable => $setting) {
626
            $title = isset($setting['title']) ? $setting['title'] : '';
627
            Database::query(
628
                "INSERT INTO $TABLESETTING (id, c_id, title, variable, value, category)
629
                 VALUES ($counter, $course_id, '".$title."', '".$variable."', '".$setting['default']."', '".$setting['category']."')"
630
            );
631
            $counter++;
632
        }
633
634
        /* Course homepage tools for platform admin only */
635
636
        /* Group tool */
637
        Database::insert(
638
            $TABLEGROUPCATEGORIES,
639
            [
640
                'c_id' => $course_id,
641
                'id' => 2,
642
                'title' => get_lang('DefaultGroupCategory'),
643
                'description' => '',
644
                'max_student' => 8,
645
                'self_reg_allowed' => 0,
646
                'self_unreg_allowed' => 0,
647
                'groups_per_user' => 0,
648
                'display_order' => 0,
649
                'doc_state' => 1,
650
                'calendar_state' => 1,
651
                'work_state' => 1,
652
                'announcements_state' => 1,
653
                'forum_state' => 1,
654
                'wiki_state' => 1,
655
                'chat_state' => 1
656
            ]
657
        );
658
659
        $now = api_get_utc_datetime();
660
661
        $files = [
662
            ['path' => '/shared_folder', 'title' => get_lang('UserFolders'), 'filetype' => 'folder', 'size' => 0],
663
            ['path' => '/chat_files', 'title' => get_lang('ChatFiles'), 'filetype' => 'folder', 'size' => 0],
664
        ];
665
666
        $counter = 1;
667
        foreach ($files as $file) {
668
            self::insertDocument($course_id, $counter, $file, $authorId);
669
            $counter++;
670
        }
671
672
        $sys_course_path = api_get_path(SYS_COURSE_PATH);
673
        $perm = api_get_permissions_for_new_directories();
674
        $perm_file = api_get_permissions_for_new_files();
675
676
        $chat_path = $sys_course_path.$course_repository.'/document/chat_files';
677
678
        if (!is_dir($chat_path)) {
679
            @mkdir($chat_path, api_get_permissions_for_new_directories());
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for mkdir(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

679
            /** @scrutinizer ignore-unhandled */ @mkdir($chat_path, api_get_permissions_for_new_directories());

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
680
        }
681
682
        /*    Documents   */
683
        if ($fill_with_exemplary_content) {
684
            $files = [
685
                ['path' => '/images', 'title' => get_lang('Images'), 'filetype' => 'folder', 'size' => 0],
686
                ['path' => '/images/gallery', 'title' => get_lang('DefaultCourseImages'), 'filetype' => 'folder', 'size' => 0],
687
                ['path' => '/audio', 'title' => get_lang('Audio'), 'filetype' => 'folder', 'size' => 0],
688
                ['path' => '/flash', 'title' => get_lang('Flash'), 'filetype' => 'folder', 'size' => 0],
689
                ['path' => '/video', 'title' => get_lang('Video'), 'filetype' => 'folder', 'size' => 0],
690
                ['path' => '/certificates', 'title' => get_lang('Certificates'), 'filetype' => 'folder', 'size' => 0]
691
            ];
692
693
            foreach ($files as $file) {
694
                self::insertDocument($course_id, $counter, $file, $authorId);
695
                $counter++;
696
            }
697
698
            // FILL THE COURSE DOCUMENT WITH DEFAULT COURSE PICTURES
699
            $folders_to_copy_from_default_course = [
700
                'images',
701
                'audio',
702
                'flash',
703
                'video',
704
                'certificates',
705
            ];
706
707
            $default_course_path = api_get_path(SYS_CODE_PATH).'default_course_document/';
708
709
            $default_document_array = [];
710
            foreach ($folders_to_copy_from_default_course as $folder) {
711
                $default_course_folder_path = $default_course_path.$folder.'/';
712
                $files = self::browse_folders(
713
                    $default_course_folder_path,
714
                    [],
715
                    $folder
716
                );
717
718
                $sorted_array = self::sort_pictures($files, 'dir');
719
                $sorted_array = array_merge(
720
                    $sorted_array,
721
                    self::sort_pictures($files, 'file')
722
                );
723
                $default_document_array[$folder] = $sorted_array;
724
            }
725
726
            // Light protection (adding index.html in every document folder)
727
            $htmlpage = "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <title>Not authorized</title>\n  </head>\n  <body>\n  </body>\n</html>";
728
729
            $example_cert_id = 0;
730
            if (is_array($default_document_array) && count(
731
                    $default_document_array
732
                ) > 0
733
            ) {
734
                foreach ($default_document_array as $media_type => $array_media) {
735
                    $path_documents = "/$media_type/";
736
737
                    //hack until feature #5242 is implemented
738
                    if ($media_type == 'images') {
739
                        $media_type = 'images/gallery';
740
                        $images_folder = $sys_course_path.$course_repository."/document/images/";
741
742
                        if (!is_dir($images_folder)) {
743
                            //Creating index.html
744
                            mkdir($images_folder, $perm);
745
                            $fd = fopen($images_folder.'index.html', 'w');
746
                            fwrite($fd, $htmlpage);
0 ignored issues
show
Bug introduced by
It seems like $fd can also be of type false; however, parameter $handle of fwrite() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

746
                            fwrite(/** @scrutinizer ignore-type */ $fd, $htmlpage);
Loading history...
747
                            @chmod($images_folder.'index.html', $perm_file);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for chmod(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

747
                            /** @scrutinizer ignore-unhandled */ @chmod($images_folder.'index.html', $perm_file);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
748
                        }
749
                    }
750
751
                    $course_documents_folder = $sys_course_path.$course_repository."/document/$media_type/";
752
                    $default_course_path = api_get_path(SYS_CODE_PATH).'default_course_document'.$path_documents;
753
754
                    if (!is_dir($course_documents_folder)) {
755
                        // Creating index.html
756
                        mkdir($course_documents_folder, $perm);
757
                        $fd = fopen(
758
                            $course_documents_folder.'index.html',
759
                            'w'
760
                        );
761
                        fwrite($fd, $htmlpage);
762
                        @chmod(
763
                            $course_documents_folder.'index.html',
764
                            $perm_file
765
                        );
766
                    }
767
768
                    if (is_array($array_media) && count($array_media) > 0) {
769
                        foreach ($array_media as $key => $value) {
770
                            if (isset($value['dir']) && !empty($value['dir'])) {
771
                                if (!is_dir($course_documents_folder.$value['dir'])) {
772
                                    //Creating folder
773
                                    mkdir(
774
                                        $course_documents_folder.$value['dir'],
775
                                        $perm
776
                                    );
777
778
                                    //Creating index.html (for light protection)
779
                                    $index_html = $course_documents_folder.$value['dir'].'/index.html';
780
                                    $fd = fopen($index_html, 'w');
781
                                    fwrite($fd, $htmlpage);
782
                                    @chmod($index_html, $perm_file);
783
784
                                    //Inserting folder in the DB
785
                                    $folder_path = substr(
786
                                        $value['dir'],
787
                                        0,
788
                                        strlen($value['dir']) - 1
789
                                    );
790
                                    $temp = explode('/', $folder_path);
791
                                    $title = $temp[count($temp) - 1];
792
793
                                    //hack until feature #5242 is implemented
794
                                    if ($title == 'gallery') {
795
                                        $title = get_lang(
796
                                            'DefaultCourseImages'
797
                                        );
798
                                    }
799
800
                                    if ($media_type == 'images/gallery') {
801
                                        $folder_path = 'gallery/'.$folder_path;
802
                                    }
803
804
                                    Database::query(
805
                                        "INSERT INTO $TABLETOOLDOCUMENT (c_id, path,title,filetype,size)
806
                                        VALUES ($course_id,'$path_documents".$folder_path."','".$title."','folder','0')"
807
                                    );
808
                                    $image_id = Database:: insert_id();
809
810
                                    Database::insert(
811
                                        $TABLEITEMPROPERTY,
812
                                        [
813
                                            'c_id' => $course_id,
814
                                            'tool' => 'document',
815
                                            'insert_user_id' => api_get_user_id(),
816
                                            'insert_date' => $now,
817
                                            'lastedit_date' => $now,
818
                                            'ref' => $image_id,
819
                                            'lastedit_type' => 'DocumentAdded',
820
                                            'lastedit_user_id' => api_get_user_id(),
821
                                            'to_group_id' => null,
822
                                            'to_user_id' =>  null,
823
                                            'visibility' => 0
824
                                        ]
825
                                    );
826
                                }
827
                            }
828
829
                            if (isset($value['file']) && !empty($value['file'])) {
830
                                if (!file_exists(
831
                                    $course_documents_folder.$value['file']
832
                                )
833
                                ) {
834
                                    //Copying file
835
                                    copy(
836
                                        $default_course_path.$value['file'],
837
                                        $course_documents_folder.$value['file']
838
                                    );
839
                                    chmod(
840
                                        $course_documents_folder.$value['file'],
841
                                        $perm_file
842
                                    );
843
                                    //echo $default_course_path.$value['file']; echo ' - '; echo $course_documents_folder.$value['file']; echo '<br />';
844
                                    $temp = explode('/', $value['file']);
845
                                    $file_size = filesize(
846
                                        $course_documents_folder.$value['file']
847
                                    );
848
849
                                    //hack until feature #5242 is implemented
850
                                    if ($media_type == 'images/gallery') {
851
                                        $value["file"] = 'gallery/'.$value["file"];
852
                                    }
853
854
                                    //Inserting file in the DB
855
                                    Database::query(
856
                                        "INSERT INTO $TABLETOOLDOCUMENT (c_id, path,title,filetype,size)
857
                                        VALUES ($course_id,'$path_documents".$value["file"]."','".$temp[count($temp) - 1]."','file','$file_size')"
858
                                    );
859
                                    $image_id = Database:: insert_id();
860
                                    if ($image_id) {
861
                                        $sql = "UPDATE $TABLETOOLDOCUMENT SET id = iid WHERE iid = $image_id";
862
                                        Database::query($sql);
863
864
                                        if ($path_documents.$value['file'] == '/certificates/default.html') {
865
                                            $example_cert_id = $image_id;
866
                                        }
867
                                        $docId = Database::insert(
868
                                            $TABLEITEMPROPERTY,
869
                                            [
870
                                                'c_id' => $course_id,
871
                                                'tool' => 'document',
872
                                                'insert_user_id' => api_get_user_id(),
873
                                                'insert_date' => $now,
874
                                                'lastedit_date' => $now,
875
                                                'ref' => $image_id,
876
                                                'lastedit_type' => 'DocumentAdded',
877
                                                'lastedit_user_id' => api_get_user_id(),
878
                                                'to_group_id' => null,
879
                                                'to_user_id' =>  null,
880
                                                'visibility' => 1
881
                                            ]
882
                                        );
883
                                        if ($docId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $docId of type integer|false is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
884
                                            $sql = "UPDATE $TABLEITEMPROPERTY SET id = iid WHERE iid = $docId";
885
                                            Database::query($sql);
886
                                        }
887
                                    }
888
                                }
889
                            }
890
                        }
891
                    }
892
                }
893
            }
894
895
            $agenda = new Agenda('course');
896
            $agenda->set_course($courseInfo);
897
            $agenda->addEvent(
898
                $now,
899
                $now,
900
                0,
901
                get_lang('AgendaCreationTitle'),
902
                get_lang('AgendaCreationContenu')
903
            );
904
905
            /*  Links tool */
906
907
            $link = new Link();
908
            $link->setCourse($courseInfo);
909
            $links = [
910
                [
911
                    'c_id' => $course_id,
912
                    'url' => 'http://www.google.com',
913
                    'title' => 'Google',
914
                    'description' => get_lang('Google'),
915
                    'category_id' => 0,
916
                    'on_homepage' => 0,
917
                    'target' => '_self',
918
                    'session_id' => 0
919
                ],
920
                [
921
                    'c_id' => $course_id,
922
                    'url' => 'http://www.wikipedia.org',
923
                    'title' => 'Wikipedia',
924
                    'description' => get_lang('Wikipedia'),
925
                    'category_id' => 0,
926
                    'on_homepage' => 0,
927
                    'target' => '_self',
928
                    'session_id' => 0
929
                ]
930
            ];
931
932
            foreach ($links as $params) {
933
                $link->save($params);
934
            }
935
936
            /* Announcement tool */
937
            AnnouncementManager::add_announcement(
938
                $courseInfo,
939
                0,
940
                get_lang('AnnouncementExampleTitle'),
941
                get_lang('AnnouncementEx'),
942
                ['everyone' => 'everyone'],
943
                null,
944
                null,
945
                $now
946
            );
947
948
            $manager = Database::getManager();
949
950
            /* Introduction text */
951
            $intro_text = '<p style="text-align: center;">
952
                            <img src="' . api_get_path(REL_CODE_PATH).'img/mascot.png" alt="Mr. Chamilo" title="Mr. Chamilo" />
953
                            <h2>' . get_lang('IntroductionText').'</h2>
954
                         </p>';
955
956
            $toolIntro = new CToolIntro();
957
            $toolIntro
958
                ->setCId($course_id)
959
                ->setId(TOOL_COURSE_HOMEPAGE)
960
                ->setSessionId(0)
961
                ->setIntroText($intro_text);
962
            $manager->persist($toolIntro);
963
964
            $toolIntro = new CToolIntro();
965
            $toolIntro
966
                ->setCId($course_id)
967
                ->setId(TOOL_STUDENTPUBLICATION)
968
                ->setSessionId(0)
969
                ->setIntroText(get_lang('IntroductionTwo'));
970
            $manager->persist($toolIntro);
971
972
            $toolIntro = new CToolIntro();
973
            $toolIntro
974
                ->setCId($course_id)
975
                ->setId(TOOL_WIKI)
976
                ->setSessionId(0)
977
                ->setIntroText(get_lang('IntroductionWiki'));
978
            $manager->persist($toolIntro);
979
980
            $manager->flush();
981
982
            /*  Exercise tool */
983
            $exercise = new Exercise($course_id);
984
            $exercise->exercise = get_lang('ExerciceEx');
985
            $html = '<table width="100%" border="0" cellpadding="0" cellspacing="0">
986
                        <tr>
987
                        <td width="220" valign="top" align="left">
988
                            <img src="' . api_get_path(WEB_CODE_PATH).'default_course_document/images/mr_chamilo/doubts.png">
989
                        </td>
990
                        <td valign="top" align="left">' . get_lang('Antique').'</td></tr>
991
                    </table>';
992
            $exercise->type = 1;
993
            $exercise->setRandom(0);
994
            $exercise->active = 1;
995
            $exercise->results_disabled = 0;
996
            $exercise->description = $html;
997
            $exercise->save();
998
999
            $exercise_id = $exercise->id;
1000
1001
            $question = new MultipleAnswer();
1002
            $question->question = get_lang('SocraticIrony');
1003
            $question->description = get_lang('ManyAnswers');
1004
            $question->weighting = 10;
1005
            $question->position = 1;
1006
            $question->course = $courseInfo;
1007
            $question->save($exercise);
1008
            $questionId = $question->id;
1009
1010
            $answer = new Answer($questionId, $courseInfo['real_id']);
0 ignored issues
show
Bug introduced by
It seems like $questionId can also be of type false; however, parameter $questionId of Answer::__construct() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1010
            $answer = new Answer(/** @scrutinizer ignore-type */ $questionId, $courseInfo['real_id']);
Loading history...
1011
1012
            $answer->createAnswer(get_lang('Ridiculise'), 0, get_lang('NoPsychology'), -5, 1);
1013
            $answer->createAnswer(get_lang('AdmitError'), 0, get_lang('NoSeduction'), -5, 2);
1014
            $answer->createAnswer(get_lang('Force'), 1, get_lang('Indeed'), 5, 3);
1015
            $answer->createAnswer(get_lang('Contradiction'), 1, get_lang('NotFalse'), 5, 4);
1016
            $answer->save();
1017
1018
            /* Forum tool */
1019
1020
            require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
1021
1022
            $params = [
1023
                'forum_category_title' => get_lang('ExampleForumCategory'),
1024
                'forum_category_comment' => ''
1025
            ];
1026
1027
            $forumCategoryId = store_forumcategory($params, $courseInfo, false);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $forumCategoryId is correct as store_forumcategory($params, $courseInfo, false) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
1028
1029
            $params = [
1030
                'forum_category' => $forumCategoryId,
1031
                'forum_title' => get_lang('ExampleForum'),
1032
                'forum_comment' => '',
1033
                'default_view_type_group' => ['default_view_type' => 'flat'],
1034
            ];
1035
1036
            $forumId = store_forum($params, $courseInfo, true);
1037
1038
            $forumInfo = get_forum_information($forumId, $courseInfo['real_id']);
0 ignored issues
show
Deprecated Code introduced by
The function get_forum_information() has been deprecated: this functionality is now moved to get_forums($forum_id) ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1038
            $forumInfo = /** @scrutinizer ignore-deprecated */ get_forum_information($forumId, $courseInfo['real_id']);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
1039
1040
            $params = [
1041
                'post_title' => get_lang('ExampleThread'),
1042
                'forum_id' => $forumId,
1043
                'post_text' => get_lang('ExampleThreadContent'),
1044
                'calification_notebook_title' => '',
1045
                'numeric_calification' => '',
1046
                'weight_calification' => '',
1047
                'forum_category' => $forumCategoryId,
1048
                'thread_peer_qualify' => 0,
1049
            ];
1050
1051
            store_thread($forumInfo, $params, $courseInfo, false);
1052
1053
            /* Gradebook tool */
1054
            $course_code = $courseInfo['code'];
1055
            // father gradebook
1056
            Database::query(
1057
                "INSERT INTO $TABLEGRADEBOOK (name, description, user_id, course_code, parent_id, weight, visible, certif_min_score, session_id, document_id)
1058
                VALUES ('$course_code','',1,'$course_code',0,100,0,75,NULL,$example_cert_id)"
1059
            );
1060
            $gbid = Database:: insert_id();
1061
            Database::query(
1062
                "INSERT INTO $TABLEGRADEBOOK (name, description, user_id, course_code, parent_id, weight, visible, certif_min_score, session_id, document_id)
1063
                VALUES ('$course_code','',1,'$course_code',$gbid,100,1,75,NULL,$example_cert_id)"
1064
            );
1065
            $gbid = Database:: insert_id();
1066
            Database::query(
1067
                "INSERT INTO $TABLEGRADEBOOKLINK (type, ref_id, user_id, course_code, category_id, created_at, weight, visible, locked)
1068
                VALUES (1,$exercise_id,1,'$course_code',$gbid,'$now',100,1,0)"
1069
            );
1070
        }
1071
1072
        //Installing plugins in course
1073
        $app_plugin = new AppPlugin();
1074
        $app_plugin->install_course_plugins($course_id);
1075
        return true;
1076
    }
1077
1078
    /**
1079
     * @param int $course_id
1080
     * @param int $counter
1081
     * @param array $file
1082
     * @param int $authorId
1083
     */
1084
    public static function insertDocument($course_id, $counter, $file, $authorId = 0)
1085
    {
1086
        $tableItem = Database::get_course_table(TABLE_ITEM_PROPERTY);
1087
        $tableDocument = Database::get_course_table(TABLE_DOCUMENT);
1088
1089
        $now = api_get_utc_datetime();
1090
        $sql = "INSERT INTO $tableDocument (id, c_id, path,title,filetype,size, readonly, session_id)
1091
                VALUES ($counter, $course_id, '".$file['path']."', '".$file['title']."', '".$file['filetype']."', '".$file['size']."', 0, 0)";
1092
        Database::query($sql);
1093
        $docId = Database:: insert_id();
1094
1095
        $authorId = empty($authorId) ? api_get_user_id() : (int) $authorId;
1096
1097
        if ($docId) {
1098
            $sql = "UPDATE $tableDocument SET id = iid WHERE iid = $docId";
1099
            Database::query($sql);
1100
1101
            $id = Database::insert(
1102
                $tableItem,
1103
                [
1104
                    'id' => $counter,
1105
                    'c_id' => $course_id,
1106
                    'tool' => 'document',
1107
                    'insert_user_id' => $authorId,
1108
                    'insert_date' => $now,
1109
                    'lastedit_date' => $now,
1110
                    'ref' => $docId,
1111
                    'lastedit_type' => 'DocumentAdded',
1112
                    'lastedit_user_id' => $authorId,
1113
                    'to_group_id' => null,
1114
                    'to_user_id' =>  null,
1115
                    'visibility' => 0
1116
                ]
1117
            );
1118
1119
            if ($id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $id of type integer|false is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
1120
                $sql = "UPDATE $tableItem SET id = iid WHERE iid = $id";
1121
                Database::query($sql);
1122
            }
1123
        }
1124
    }
1125
1126
    /**
1127
     * string2binary converts the string "true" or "false" to the boolean true false (0 or 1)
1128
     * This is used for the Chamilo Config Settings as these store true or false as string
1129
     * and the api_get_setting('course_create_active_tools') should be 0 or 1 (used for
1130
     * the visibility of the tool)
1131
     * @param string $variable
1132
     * @return bool
1133
     * @author Patrick Cool, [email protected]
1134
     * @assert ('true') === true
1135
     * @assert ('false') === false
1136
     */
1137
    public static function string2binary($variable)
1138
    {
1139
        if ($variable == 'true') {
1140
            return true;
1141
        }
1142
        if ($variable == 'false') {
1143
            return false;
1144
        }
1145
    }
1146
1147
    /**
1148
     * Function register_course to create a record in the course table of the main database
1149
     * @param array Course details (see code for details)
1150
     * @return int  Created course ID
1151
     * @todo use an array called $params instead of lots of params
1152
     * @assert (null) === false
1153
     */
1154
    public static function register_course($params)
1155
    {
1156
        global $error_msg, $firstExpirationDelay;
1157
        $title = $params['title'];
1158
        // Fix amp
1159
        $title = str_replace('&amp;', '&', $title);
1160
        $code = $params['code'];
1161
        $visual_code = $params['visual_code'];
1162
        $directory = $params['directory'];
1163
        $tutor_name = isset($params['tutor_name']) ? $params['tutor_name'] : null;
1164
        $category_code = isset($params['course_category']) ? $params['course_category'] : '';
1165
        $course_language = isset($params['course_language']) && !empty($params['course_language']) ? $params['course_language'] : api_get_setting(
1166
            'platformLanguage'
1167
        );
1168
        $user_id = empty($params['user_id']) ? api_get_user_id() : intval($params['user_id']);
1169
        $department_name = isset($params['department_name']) ?
1170
            $params['department_name'] : null;
1171
        $department_url = isset($params['department_url']) ?
1172
            $params['department_url'] : null;
1173
        $disk_quota = isset($params['disk_quota']) ?
1174
            $params['disk_quota'] : null;
1175
1176
        if (!isset($params['visibility'])) {
1177
            $default_course_visibility = api_get_setting(
1178
                'courses_default_creation_visibility'
1179
            );
1180
            if (isset($default_course_visibility)) {
1181
                $visibility = $default_course_visibility;
1182
            } else {
1183
                $visibility = COURSE_VISIBILITY_OPEN_PLATFORM;
1184
            }
1185
        } else {
1186
            $visibility = $params['visibility'];
1187
        }
1188
1189
        $subscribe = isset($params['subscribe']) ? (int) $params['subscribe'] : $visibility == COURSE_VISIBILITY_OPEN_PLATFORM ? 1 : 0;
1190
        $unsubscribe = isset($params['unsubscribe']) ? intval($params['unsubscribe']) : 0;
1191
        $expiration_date = isset($params['expiration_date']) ? $params['expiration_date'] : null;
1192
        $teachers = isset($params['teachers']) ? $params['teachers'] : null;
1193
        $status = isset($params['status']) ? $params['status'] : null;
1194
1195
        $TABLECOURSE = Database::get_main_table(TABLE_MAIN_COURSE);
1196
        $TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER);
1197
1198
        $ok_to_register_course = true;
1199
1200
        // Check whether all the needed parameters are present.
1201
        if (empty($code)) {
1202
            $error_msg[] = 'courseSysCode is missing';
1203
            $ok_to_register_course = false;
1204
        }
1205
        if (empty($visual_code)) {
1206
            $error_msg[] = 'courseScreenCode is missing';
1207
            $ok_to_register_course = false;
1208
        }
1209
        if (empty($directory)) {
1210
            $error_msg[] = 'courseRepository is missing';
1211
            $ok_to_register_course = false;
1212
        }
1213
1214
        if (empty($title)) {
1215
            $error_msg[] = 'title is missing';
1216
            $ok_to_register_course = false;
1217
        }
1218
1219
        if (empty($expiration_date)) {
1220
            $expiration_date = api_get_utc_datetime(
1221
                time() + $firstExpirationDelay
1222
            );
1223
        } else {
1224
            $expiration_date = api_get_utc_datetime($expiration_date);
1225
        }
1226
1227
        if ($visibility < 0 || $visibility > 4) {
1228
            $error_msg[] = 'visibility is invalid';
1229
            $ok_to_register_course = false;
1230
        }
1231
1232
        if (empty($disk_quota)) {
1233
            $disk_quota = api_get_setting('default_document_quotum');
1234
        }
1235
1236
        $time = api_get_utc_datetime();
1237
1238
        if (stripos($department_url, 'http://') === false && stripos(
1239
                $department_url,
1240
                'https://'
1241
            ) === false
1242
        ) {
1243
            $department_url = 'http://'.$department_url;
1244
        }
1245
        //just in case
1246
        if ($department_url == 'http://') {
1247
            $department_url = '';
1248
        }
1249
        $course_id = 0;
1250
1251
        if ($ok_to_register_course) {
1252
            // Here we must add 2 fields.
1253
            $course_id = Database::insert(
1254
                $TABLECOURSE,
1255
                [
1256
                    'code' => $code,
1257
                    'directory' => $directory,
1258
                    'course_language' => $course_language,
1259
                    'title' => $title,
1260
                    'description' => get_lang('CourseDescription'),
1261
                    'category_code' => $category_code,
1262
                    'visibility' => $visibility,
1263
                    'show_score' => 1,
1264
                    'disk_quota' => intval($disk_quota),
1265
                    'creation_date' => $time,
1266
                    'expiration_date' => $expiration_date,
1267
                    'last_edit' => $time,
1268
                    'last_visit' => null,
1269
                    'tutor_name' => $tutor_name,
1270
                    'department_name' => $department_name,
1271
                    'department_url' => $department_url,
1272
                    'subscribe' => intval($subscribe),
1273
                    'unsubscribe' => intval($unsubscribe),
1274
                    'visual_code' => $visual_code
1275
                ]
1276
            );
1277
1278
            if ($course_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $course_id of type integer|false is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
1279
                $sort = api_max_sort_value('0', api_get_user_id());
1280
                // Default true
1281
                $addTeacher = isset($params['add_user_as_teacher']) ? $params['add_user_as_teacher'] : true;
1282
                if ($addTeacher) {
1283
                    $i_course_sort = CourseManager:: userCourseSort(
1284
                        $user_id,
1285
                        $code
1286
                    );
1287
                    if (!empty($user_id)) {
1288
                        $sql = "INSERT INTO ".$TABLECOURSUSER." SET
1289
                                c_id     = '" . $course_id."',
1290
                                user_id         = '" . intval($user_id)."',
1291
                                status          = '1',
1292
                                is_tutor        = '0',
1293
                                sort            = '" . ($i_course_sort)."',
1294
                                relation_type = 0,
1295
                                user_course_cat = '0'";
1296
                        Database::query($sql);
1297
                    }
1298
                }
1299
1300
                if (!empty($teachers)) {
1301
                    if (!is_array($teachers)) {
1302
                        $teachers = [$teachers];
1303
                    }
1304
                    foreach ($teachers as $key) {
1305
                        //just in case
1306
                        if ($key == $user_id) {
1307
                            continue;
1308
                        }
1309
                        if (empty($key)) {
1310
                            continue;
1311
                        }
1312
                        $sql = "INSERT INTO ".$TABLECOURSUSER." SET
1313
                            c_id     = '" . Database::escape_string($course_id)."',
1314
                            user_id         = '" . Database::escape_string($key)."',
1315
                            status          = '1',
1316
                            is_tutor        = '0',
1317
                            sort            = '" . ($sort + 1)."',
1318
                            relation_type = 0,
1319
                            user_course_cat = '0'";
1320
                        Database::query($sql);
1321
                    }
1322
                }
1323
1324
                // Adding the course to an URL.
1325
                if (api_is_multiple_url_enabled()) {
1326
                    $url_id = 1;
1327
                    if (api_get_current_access_url_id() != -1) {
1328
                        $url_id = api_get_current_access_url_id();
1329
                    }
1330
                    UrlManager::add_course_to_url($course_id, $url_id);
1331
                } else {
1332
                    UrlManager::add_course_to_url($course_id, 1);
1333
                }
1334
1335
                // Add event to the system log.
1336
                $user_id = api_get_user_id();
1337
                Event::addEvent(
1338
                    LOG_COURSE_CREATE,
1339
                    LOG_COURSE_CODE,
1340
                    $code,
1341
                    api_get_utc_datetime(),
1342
                    $user_id,
1343
                    $course_id
1344
                );
1345
1346
                $send_mail_to_admin = api_get_setting(
1347
                    'send_email_to_admin_when_create_course'
1348
                );
1349
1350
                // @todo Improve code to send to all current portal administrators.
1351
                if ($send_mail_to_admin == 'true') {
1352
                    $siteName = api_get_setting('siteName');
1353
                    $recipient_email = api_get_setting('emailAdministrator');
1354
                    $recipient_name = api_get_person_name(
1355
                        api_get_setting('administratorName'),
1356
                        api_get_setting('administratorSurname')
1357
                    );
1358
                    $iname = api_get_setting('Institution');
1359
                    $subject = get_lang(
1360
                            'NewCourseCreatedIn'
1361
                        ).' '.$siteName.' - '.$iname;
1362
                    $message = get_lang(
1363
                            'Dear'
1364
                        ).' '.$recipient_name.",\n\n".get_lang(
1365
                            'MessageOfNewCourseToAdmin'
1366
                        ).' '.$siteName.' - '.$iname."\n";
1367
                    $message .= get_lang('CourseName').' '.$title."\n";
1368
                    $message .= get_lang(
1369
                            'Category'
1370
                        ).' '.$category_code."\n";
1371
                    $message .= get_lang('Tutor').' '.$tutor_name."\n";
1372
                    $message .= get_lang('Language').' '.$course_language;
1373
1374
                    $userInfo = api_get_user_info($user_id);
1375
1376
                    $additionalParameters = [
1377
                        'smsType' => SmsPlugin::NEW_COURSE_BEEN_CREATED,
1378
                        'userId' => $user_id,
1379
                        'courseName' => $title,
1380
                        'creatorUsername' => $userInfo['username']
1381
                    ];
1382
1383
                    api_mail_html(
1384
                        $recipient_name,
1385
                        $recipient_email,
1386
                        $subject,
1387
                        $message,
1388
                        $siteName,
1389
                        $recipient_email,
1390
                        null,
1391
                        null,
1392
                        null,
1393
                        $additionalParameters
1394
                    );
1395
                }
1396
            }
1397
        }
1398
1399
        return $course_id;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $course_id could also return false which is incompatible with the documented return type integer. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
1400
    }
1401
1402
    /**
1403
     * Generate a new id for c_tool table
1404
     * @param int $courseId The course id
1405
     * @return int the new id
1406
     */
1407
    public static function generateToolId($courseId)
1408
    {
1409
        $newIdResultData = Database::select(
1410
            'id + 1 AS new_id',
1411
            Database::get_course_table(TABLE_TOOL_LIST),
1412
            [
1413
                'where' => ['c_id = ?' => intval($courseId)],
1414
                'order' => 'id',
1415
                'limit' => 1
1416
            ],
1417
            'first'
1418
        );
1419
1420
        if ($newIdResultData === false) {
1421
            return 1;
1422
        }
1423
1424
        return $newIdResultData['new_id'] > 0 ? $newIdResultData['new_id'] : 1;
1425
    }
1426
}
1427