Passed
Push — master ( 006e96...fba8cd )
by Julito
09:00
created

AddCourse   F

Complexity

Total Complexity 77

Size/Duplication

Total Lines 928
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 584
dl 0
loc 928
rs 2.24
c 0
b 0
f 0
wmc 77

9 Methods

Rating   Name   Duplication   Size   Complexity  
B define_course_keys() 0 53 6
A generateToolId() 0 18 3
A sort_pictures() 0 10 4
B get_course_tables() 0 93 1
A drop_course_tables() 0 6 2
A insertDocument() 0 15 1
A string2binary() 0 7 3
F register_course() 0 248 41
D fillCourse() 0 366 16

How to fix   Complexity   

Complex Class

Complex classes like AddCourse often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AddCourse, and based on these observations, apply Extract Interface, too.

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CoreBundle\Framework\Container;
5
use Chamilo\CourseBundle\Entity\CToolIntro;
6
7
/**
8
 * Class AddCourse.
9
 */
10
class AddCourse
11
{
12
    public const FIRST_EXPIRATION_DATE = 31536000; // 365 days in seconds
13
14
    /**
15
     * Defines the four needed keys to create a course based on several parameters.
16
     *
17
     * @param string    The code you want for this course
18
     * @param string    Prefix added for ALL keys
19
     * @param string    Prefix added for databases only
20
     * @param string    Prefix added for paths only
21
     * @param bool      Add unique prefix
22
     * @param bool      Use code-independent keys
23
     *
24
     * @return array An array with the needed keys ['currentCourseCode'], ['currentCourseId'], ['currentCourseDbName'],
25
     *               ['currentCourseRepository']
26
     *
27
     * @todo Eliminate the global variables.
28
     * @assert (null) === false
29
     */
30
    public static function define_course_keys(
31
        $wanted_code,
32
        $prefix_for_all = '',
33
        $prefix_for_base_name = '',
34
        $prefix_for_path = '',
35
        $add_unique_prefix = false,
36
        $use_code_indepedent_keys = true
37
    ) {
38
        $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
39
        $wanted_code = CourseManager::generate_course_code($wanted_code);
40
        $keys_course_code = $wanted_code;
41
        if (!$use_code_indepedent_keys) {
42
            $wanted_code = '';
43
        }
44
45
        $unique_prefix = '';
46
        if ($add_unique_prefix) {
47
            $unique_prefix = substr(md5(uniqid(rand())), 0, 10);
48
        }
49
50
        $keys = [];
51
        $final_suffix = ['CourseId' => '', 'CourseDb' => '', 'CourseDir' => ''];
52
        $limit_numb_try = 100;
53
        $keys_are_unique = false;
54
        $try_new_fsc_id = $try_new_fsc_db = $try_new_fsc_dir = 0;
55
56
        while (!$keys_are_unique) {
57
            $keys_course_id = $prefix_for_all.$unique_prefix.$wanted_code.$final_suffix['CourseId'];
58
            $keys_course_repository = $prefix_for_path.$unique_prefix.$wanted_code.$final_suffix['CourseDir'];
59
            $keys_are_unique = true;
60
61
            // Check whether they are unique.
62
            $query = "SELECT 1 FROM $course_table
63
                      WHERE code='".$keys_course_id."'
64
                      LIMIT 0, 1";
65
            $result = Database::query($query);
66
67
            if (Database::num_rows($result)) {
68
                $keys_are_unique = false;
69
                $try_new_fsc_id++;
70
                $final_suffix['CourseId'] = substr(md5(uniqid(rand())), 0, 4);
71
            }
72
73
            if (($try_new_fsc_id + $try_new_fsc_db + $try_new_fsc_dir) > $limit_numb_try) {
74
                return $keys;
75
            }
76
        }
77
78
        $keys['currentCourseCode'] = $keys_course_code;
79
        $keys['currentCourseId'] = $keys_course_id;
80
        $keys['currentCourseRepository'] = $keys_course_repository;
81
82
        return $keys;
83
    }
84
85
    /**
86
     * Gets an array with all the course tables (deprecated?).
87
     *
88
     * @return array
89
     *
90
     * @assert (null) !== null
91
     */
92
    public static function get_course_tables()
93
    {
94
        $tables = [];
95
        //$tables[] = 'item_property';
96
        $tables[] = 'tool';
97
        $tables[] = 'tool_intro';
98
        $tables[] = 'group_info';
99
        $tables[] = 'group_category';
100
        $tables[] = 'group_rel_user';
101
        $tables[] = 'group_rel_tutor';
102
        $tables[] = 'userinfo_content';
103
        $tables[] = 'userinfo_def';
104
        $tables[] = 'course_description';
105
        $tables[] = 'calendar_event';
106
        $tables[] = 'calendar_event_repeat';
107
        $tables[] = 'calendar_event_repeat_not';
108
        $tables[] = 'calendar_event_attachment';
109
        $tables[] = 'announcement';
110
        $tables[] = 'announcement_attachment';
111
        //$tables[] = 'resource';
112
        $tables[] = 'student_publication';
113
        $tables[] = 'student_publication_assignment';
114
        $tables[] = 'document';
115
        $tables[] = 'forum_category';
116
        $tables[] = 'forum_forum';
117
        $tables[] = 'forum_thread';
118
        $tables[] = 'forum_post';
119
        $tables[] = 'forum_mailcue';
120
        $tables[] = 'forum_attachment';
121
        $tables[] = 'forum_notification';
122
        $tables[] = 'forum_thread_qualify';
123
        $tables[] = 'forum_thread_qualify_log';
124
        $tables[] = 'link';
125
        $tables[] = 'link_category';
126
        $tables[] = 'online_connected';
127
        $tables[] = 'online_link';
128
        $tables[] = 'chat_connected';
129
        $tables[] = 'quiz';
130
        $tables[] = 'quiz_rel_question';
131
        $tables[] = 'quiz_question';
132
        $tables[] = 'quiz_answer';
133
        $tables[] = 'quiz_question_option';
134
        $tables[] = 'quiz_question_category';
135
        $tables[] = 'quiz_question_rel_category';
136
        $tables[] = 'dropbox_post';
137
        $tables[] = 'dropbox_file';
138
        $tables[] = 'dropbox_person';
139
        $tables[] = 'dropbox_category';
140
        $tables[] = 'dropbox_feedback';
141
        $tables[] = 'lp';
142
        $tables[] = 'lp_item';
143
        $tables[] = 'lp_view';
144
        $tables[] = 'lp_item_view';
145
        $tables[] = 'lp_iv_interaction';
146
        $tables[] = 'lp_iv_objective';
147
        $tables[] = 'blog';
148
        $tables[] = 'blog_comment';
149
        $tables[] = 'blog_post';
150
        $tables[] = 'blog_rating';
151
        $tables[] = 'blog_rel_user';
152
        $tables[] = 'blog_task';
153
        $tables[] = 'blog_task_rel_user';
154
        $tables[] = 'blog_attachment';
155
        $tables[] = 'permission_group';
156
        $tables[] = 'permission_user';
157
        $tables[] = 'permission_task';
158
        $tables[] = 'role';
159
        $tables[] = 'role_group';
160
        $tables[] = 'role_permissions';
161
        $tables[] = 'role_user';
162
        $tables[] = 'survey';
163
        $tables[] = 'survey_question';
164
        $tables[] = 'survey_question_option';
165
        $tables[] = 'survey_invitation';
166
        $tables[] = 'survey_answer';
167
        $tables[] = 'survey_group';
168
        $tables[] = 'wiki';
169
        $tables[] = 'wiki_conf';
170
        $tables[] = 'wiki_discuss';
171
        $tables[] = 'wiki_mailcue';
172
        $tables[] = 'course_setting';
173
        $tables[] = 'glossary';
174
        $tables[] = 'notebook';
175
        $tables[] = 'attendance';
176
        $tables[] = 'attendance_sheet';
177
        $tables[] = 'attendance_calendar';
178
        $tables[] = 'attendance_result';
179
        $tables[] = 'attendance_sheet_log';
180
        $tables[] = 'thematic';
181
        $tables[] = 'thematic_plan';
182
        $tables[] = 'thematic_advance';
183
184
        return $tables;
185
    }
186
187
    /**
188
     * Executed only before create_course_tables().
189
     *
190
     * @assert (null) === null
191
     */
192
    public static function drop_course_tables()
193
    {
194
        $list = self::get_course_tables();
195
        foreach ($list as $table) {
196
            $sql = "DROP TABLE IF EXISTS ".DB_COURSE_PREFIX.$table;
197
            Database::query($sql);
198
        }
199
    }
200
201
    /**
202
     * Sorts pictures by type (used?).
203
     *
204
     * @param array List of files (sthg like array(0=>array('png'=>1)))
205
     * @param string $type
206
     *
207
     * @return array The received array without files not matching type
208
     * @assert (array(),null) === array()
209
     */
210
    public static function sort_pictures($files, $type)
211
    {
212
        $pictures = [];
213
        foreach ($files as $value) {
214
            if (isset($value[$type]) && $value[$type] != '') {
215
                $pictures[][$type] = $value[$type];
216
            }
217
        }
218
219
        return $pictures;
220
    }
221
222
    /**
223
     * Fills the course database with some required content and example content.
224
     *
225
     * @param array $courseInfo
226
     * @param bool Whether to fill the course with example content
227
     * @param int $authorId
228
     *
229
     * @return bool False on error, true otherwise
230
     *
231
     * @version 1.2
232
     * @assert (null, '', '', null) === false
233
     * @assert (1, 'ABC', null, null) === false
234
     * @assert (1, 'TEST', 'spanish', true) === true
235
     */
236
    public static function fillCourse(
237
        $courseInfo,
238
        $fill_with_exemplary_content = null,
239
        $authorId = 0
240
    ) {
241
        if (is_null($fill_with_exemplary_content)) {
242
            $fill_with_exemplary_content = api_get_setting('example_material_course_creation') !== 'false';
243
        }
244
245
        $course_id = (int) $courseInfo['real_id'];
246
247
        if (empty($courseInfo)) {
248
            return false;
249
        }
250
        $authorId = empty($authorId) ? api_get_user_id() : (int) $authorId;
251
252
        $TABLEGROUPCATEGORIES = Database::get_course_table(TABLE_GROUP_CATEGORY);
253
        $TABLESETTING = Database::get_course_table(TABLE_COURSE_SETTING);
254
        $TABLEGRADEBOOK = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
255
        $TABLEGRADEBOOKLINK = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
256
        $course = api_get_course_entity($course_id);
257
        $settingsManager = CourseManager::getCourseSettingsManager();
258
        $settingsManager->setCourse($course);
259
260
        $alert = api_get_setting('email_alert_manager_on_new_quiz');
261
        $defaultEmailExerciseAlert = 0;
262
        if ($alert === 'true') {
263
            $defaultEmailExerciseAlert = 1;
264
        }
265
266
        /* course_setting table (courseinfo tool)   */
267
        $settings = [
268
            'email_alert_manager_on_new_doc' => ['title' => '', 'default' => 0, 'category' => 'work'],
269
            'email_alert_on_new_doc_dropbox' => ['default' => 0, 'category' => 'dropbox'],
270
            'allow_user_edit_agenda' => ['default' => 0, 'category' => 'agenda'],
271
            'allow_user_edit_announcement' => ['default' => 0, 'category' => 'announcement'],
272
            'email_alert_manager_on_new_quiz' => ['default' => $defaultEmailExerciseAlert, 'category' => 'quiz'],
273
            'allow_user_image_forum' => ['default' => 1, 'category' => 'forum'],
274
            'course_theme' => ['default' => '', 'category' => 'theme'],
275
            'allow_learning_path_theme' => ['default' => 1, 'category' => 'theme'],
276
            'allow_open_chat_window' => ['default' => 1, 'category' => 'chat'],
277
            'email_alert_to_teacher_on_new_user_in_course' => ['default' => 0, 'category' => 'registration'],
278
            'allow_user_view_user_list' => ['default' => 1, 'category' => 'user'],
279
            'display_info_advance_inside_homecourse' => ['default' => 1, 'category' => 'thematic_advance'],
280
            'email_alert_students_on_new_homework' => ['default' => 0, 'category' => 'work'],
281
            'enable_lp_auto_launch' => ['default' => 0, 'category' => 'learning_path'],
282
            'enable_exercise_auto_launch' => ['default' => 0, 'category' => 'exercise'],
283
            'enable_document_auto_launch' => ['default' => 0, 'category' => 'document'],
284
            'pdf_export_watermark_text' => ['default' => '', 'category' => 'learning_path'],
285
            'allow_public_certificates' => [
286
                'default' => api_get_setting('allow_public_certificates') === 'true' ? 1 : '',
287
                'category' => 'certificates',
288
            ],
289
            'documents_default_visibility' => ['default' => 'visible', 'category' => 'document'],
290
            'show_course_in_user_language' => ['default' => 2, 'category' => null],
291
            'email_to_teachers_on_new_work_feedback' => ['default' => 1, 'category' => null],
292
        ];
293
294
        $counter = 1;
295
        foreach ($settings as $variable => $setting) {
296
            $title = $setting['title'] ?? '';
297
            Database::query(
298
                "INSERT INTO $TABLESETTING (id, c_id, title, variable, value, category)
299
                      VALUES ($counter, $course_id, '".$title."', '".$variable."', '".$setting['default']."', '".$setting['category']."')"
300
            );
301
            $counter++;
302
        }
303
304
        /* Course homepage tools for platform admin only */
305
        /* Group tool */
306
        Database::insert(
307
            $TABLEGROUPCATEGORIES,
308
            [
309
                'c_id' => $course_id,
310
                'id' => 2,
311
                'title' => get_lang('Default groups'),
312
                'description' => '',
313
                'max_student' => 0,
314
                'self_reg_allowed' => 0,
315
                'self_unreg_allowed' => 0,
316
                'groups_per_user' => 0,
317
                'display_order' => 0,
318
                'doc_state' => 1,
319
                'calendar_state' => 1,
320
                'work_state' => 1,
321
                'announcements_state' => 1,
322
                'forum_state' => 1,
323
                'wiki_state' => 1,
324
                'chat_state' => 1,
325
            ]
326
        );
327
328
        $now = api_get_utc_datetime();
329
330
        $files = [
331
            ['path' => '/shared_folder', 'title' => get_lang('Folders of users'), 'filetype' => 'folder', 'size' => 0],
332
            ['path' => '/chat_files', 'title' => get_lang('Chat conversations history'), 'filetype' => 'folder', 'size' => 0],
333
            ['path' => '/certificates', 'title' => get_lang('Certificates'), 'filetype' => 'folder', 'size' => 0],
334
        ];
335
336
        $counter = 1;
337
        foreach ($files as $file) {
338
            self::insertDocument($courseInfo, $counter, $file, $authorId);
339
            $counter++;
340
        }
341
342
        $certificateId = 'NULL';
343
344
        /*    Documents   */
345
        if ($fill_with_exemplary_content) {
346
            $files = [
347
                ['path' => '/images', 'title' => get_lang('Images'), 'filetype' => 'folder', 'size' => 0],
348
                ['path' => '/images/gallery', 'title' => get_lang('Gallery'), 'filetype' => 'folder', 'size' => 0],
349
                ['path' => '/audio', 'title' => get_lang('Audio'), 'filetype' => 'folder', 'size' => 0],
350
                ['path' => '/flash', 'title' => get_lang('Flash'), 'filetype' => 'folder', 'size' => 0],
351
                ['path' => '/video', 'title' => get_lang('Video'), 'filetype' => 'folder', 'size' => 0],
352
            ];
353
354
            foreach ($files as $file) {
355
                self::insertDocument($courseInfo, $counter, $file, $authorId);
356
                $counter++;
357
            }
358
359
            $finder = new Symfony\Component\Finder\Finder();
360
            $defaultPath = api_get_path(SYS_PUBLIC_PATH).'img/document';
361
            $finder->in($defaultPath);
362
363
            /** @var SplFileInfo $file */
364
            foreach ($finder as $file) {
365
                $path = str_replace($defaultPath, '', $file->getRealPath());
366
                $parentName = dirname(str_replace($defaultPath, '', $file->getRealPath()));
367
                $title = $file->getFilename();
368
                $parent = DocumentManager::getDocumentByPathInCourse($courseInfo, $parentName);
369
370
                $parentId = 0;
371
                if (!empty($parent)) {
372
                    $parent = $parent[0];
373
                    $parentId = $parent['iid'];
374
                }
375
376
                if ($file->isDir()) {
377
                    $realPath = str_replace($defaultPath, '', $file->getRealPath());
378
                    DocumentManager::addDocument(
379
                        $courseInfo,
380
                        $realPath,
381
                        'folder',
382
                        null,
383
                        $title,
384
                        '',
385
                        null,
386
                        null,
387
                        null,
388
                        null,
389
                        null,
390
                        false,
391
                        null,
392
                        $parentId,
393
                        $file->getRealPath()
394
                    );
395
                } else {
396
                    $realPath = str_replace($defaultPath, '', $file->getRealPath());
397
                    $document = DocumentManager::addDocument(
398
                        $courseInfo,
399
                        $realPath,
400
                        'file',
401
                        $file->getSize(),
402
                        $title,
403
                        '',
404
                        null,
405
                        null,
406
                        null,
407
                        null,
408
                        null,
409
                        false,
410
                        null,
411
                        $parentId,
412
                        $file->getRealPath()
413
                    );
414
415
                    if ($document && $document->getTitle() === 'default.html') {
416
                        $certificateId = $document->getIid();
417
                    }
418
                }
419
            }
420
421
            $agenda = new Agenda('course');
422
            $agenda->set_course($courseInfo);
423
            $agenda->addEvent(
424
                $now,
425
                $now,
426
                0,
427
                get_lang('Course creation'),
428
                get_lang('This course was created at this time')
429
            );
430
431
            /*  Links tool */
432
            $link = new Link();
433
            $link->setCourse($courseInfo);
434
            $links = [
435
                [
436
                    'c_id' => $course_id,
437
                    'url' => 'http://www.google.com',
438
                    'title' => 'Quick and powerful search engine',
439
                    'description' => get_lang('Quick and powerful search engine'),
440
                    'category_id' => 0,
441
                    'on_homepage' => 0,
442
                    'target' => '_self',
443
                    'session_id' => 0,
444
                ],
445
                [
446
                    'c_id' => $course_id,
447
                    'url' => 'http://www.wikipedia.org',
448
                    'title' => 'Free online encyclopedia',
449
                    'description' => get_lang('Free online encyclopedia'),
450
                    'category_id' => 0,
451
                    'on_homepage' => 0,
452
                    'target' => '_self',
453
                    'session_id' => 0,
454
                ],
455
            ];
456
457
            foreach ($links as $params) {
458
                $link->save($params);
459
            }
460
461
            /* Announcement tool */
462
            AnnouncementManager::add_announcement(
463
                $courseInfo,
464
                0,
465
                get_lang('This is an announcement example'),
466
                get_lang('This is an announcement example. Only trainers are allowed to publish announcements.'),
467
                ['everyone' => 'everyone'],
468
                null,
469
                null,
470
                $now
471
            );
472
473
            $manager = Database::getManager();
474
475
            /* Introduction text */
476
            $intro_text = '<p style="text-align: center;">
477
                            <img src="'.api_get_path(REL_CODE_PATH).'img/mascot.png" alt="Mr. Chamilo" title="Mr. Chamilo" />
478
                            <h2>'.get_lang('Introduction text').'</h2>
479
                         </p>';
480
481
            $toolIntro = new CToolIntro();
482
            $toolIntro
483
                ->setCId($course_id)
484
                ->setId(TOOL_COURSE_HOMEPAGE)
485
                ->setSessionId(0)
486
                ->setIntroText($intro_text);
487
            $manager->persist($toolIntro);
488
489
            $toolIntro = new CToolIntro();
490
            $toolIntro
491
                ->setCId($course_id)
492
                ->setId(TOOL_STUDENTPUBLICATION)
493
                ->setSessionId(0)
494
                ->setIntroText(get_lang('This page allows users and groups to publish documents.'));
495
            $manager->persist($toolIntro);
496
497
            $toolIntro = new CToolIntro();
498
            $toolIntro
499
                ->setCId($course_id)
500
                ->setId(TOOL_WIKI)
501
                ->setSessionId(0)
502
                ->setIntroText(get_lang('The word Wiki is short for WikiWikiWeb. Wikiwiki is a Hawaiian word, meaning "fast" or "speed". In a wiki, people write pages together. If one person writes something wrong, the next person can correct it. The next person can also add something new to the page. Because of this, the pages improve continuously.'));
503
            $manager->persist($toolIntro);
504
505
            $manager->flush();
506
507
            /*  Exercise tool */
508
            $exercise = new Exercise($course_id);
509
            $exercise->exercise = get_lang('Sample test');
510
            $html = '<table width="100%" border="0" cellpadding="0" cellspacing="0">
511
                        <tr>
512
                        <td width="220" valign="top" align="left">
513
                            <img src="'.api_get_path(WEB_PUBLIC_PATH).'img/document/images/mr_chamilo/doubts.png">
514
                        </td>
515
                        <td valign="top" align="left">'.get_lang('Irony').'</td></tr>
516
                    </table>';
517
            $exercise->type = 1;
518
            $exercise->setRandom(0);
519
            $exercise->active = 1;
520
            $exercise->results_disabled = 0;
521
            $exercise->description = $html;
522
            $exercise->save();
523
524
            $exercise_id = $exercise->id;
525
526
            $question = new MultipleAnswer();
527
            $question->question = get_lang('Socratic irony is...');
528
            $question->description = get_lang('(more than one answer can be true)');
529
            $question->weighting = 10;
530
            $question->position = 1;
531
            $question->course = $courseInfo;
532
            $question->save($exercise);
533
            $questionId = $question->id;
534
535
            $answer = new Answer($questionId, $courseInfo['real_id']);
536
537
            $answer->createAnswer(get_lang('Ridiculise one\'s interlocutor in order to have him concede he is wrong.'), 0, get_lang('No. Socratic irony is not a matter of psychology, it concerns argumentation.'), -5, 1);
538
            $answer->createAnswer(get_lang('Admit one\'s own errors to invite one\'s interlocutor to do the same.'), 0, get_lang('No. Socratic irony is not a seduction strategy or a method based on the example.'), -5, 2);
539
            $answer->createAnswer(get_lang('Compell one\'s interlocutor, by a series of questions and sub-questions, to admit he doesn\'t know what he claims to know.'), 1, get_lang('Indeed'), 5, 3);
540
            $answer->createAnswer(get_lang('Use the Principle of Non Contradiction to force one\'s interlocutor into a dead end.'), 1, get_lang('This answer is not false. It is true that the revelation of the interlocutor\'s ignorance means showing the contradictory conclusions where lead his premisses.'), 5, 4);
541
            $answer->save();
542
543
            /* Forum tool */
544
545
            require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
546
547
            $params = [
548
                'forum_category_title' => get_lang('Example Forum Category'),
549
                'forum_category_comment' => '',
550
            ];
551
552
            $forumCategoryId = store_forumcategory($params, $courseInfo, false);
553
554
            $params = [
555
                'forum_category' => $forumCategoryId,
556
                'forum_title' => get_lang('Example Forum'),
557
                'forum_comment' => '',
558
                'default_view_type_group' => ['default_view_type' => 'flat'],
559
            ];
560
561
            $forumId = store_forum($params, $courseInfo, true);
562
            $repo = Container::getForumRepository();
563
            $forumEntity = $repo->find($forumId);
564
565
            $params = [
566
                'post_title' => get_lang('Example Thread'),
567
                'forum_id' => $forumId,
568
                'post_text' => get_lang('Example ThreadContent'),
569
                'calification_notebook_title' => '',
570
                'numeric_calification' => '',
571
                'weight_calification' => '',
572
                'forum_category' => $forumCategoryId,
573
                'thread_peer_qualify' => 0,
574
            ];
575
576
            store_thread($forumEntity, $params, $courseInfo, false);
577
578
            /* Gradebook tool */
579
            $course_code = $courseInfo['code'];
580
            // father gradebook
581
            Database::query(
582
                "INSERT INTO $TABLEGRADEBOOK (name, locked, generate_certificates, description, user_id, c_id, parent_id, weight, visible, certif_min_score, session_id, document_id)
583
                VALUES ('$course_code','0',0,'',1,$course_id,0,100,0,75,NULL,$certificateId)"
584
            );
585
            $gbid = Database:: insert_id();
586
            Database::query(
587
                "INSERT INTO $TABLEGRADEBOOK (name, locked, generate_certificates, description, user_id, c_id, parent_id, weight, visible, certif_min_score, session_id, document_id)
588
                VALUES ('$course_code','0',0,'',1,$course_id,$gbid,100,1,75,NULL,$certificateId)"
589
            );
590
            $gbid = Database:: insert_id();
591
            Database::query(
592
                "INSERT INTO $TABLEGRADEBOOKLINK (type, ref_id, user_id, c_id, category_id, created_at, weight, visible, locked)
593
                VALUES (1,$exercise_id,1,$course_id,$gbid,'$now',100,1,0)"
594
            );
595
        }
596
597
        // Installing plugins in course
598
        $app_plugin = new AppPlugin();
599
        $app_plugin->install_course_plugins($course_id);
600
601
        return true;
602
    }
603
604
    /**
605
     * @param array $courseInfo
606
     * @param int   $counter
607
     * @param array $file
608
     * @param int   $authorId
609
     */
610
    public static function insertDocument($courseInfo, $counter, $file, $authorId = 0)
611
    {
612
        DocumentManager::addDocument(
613
            $courseInfo,
614
            $file['path'],
615
            $file['filetype'],
616
            $file['size'],
617
            $file['title'],
618
            null,
619
            0,
620
            null,
621
            0,
622
            0,
623
            0,
624
            false
625
        );
626
    }
627
628
    /**
629
     * string2binary converts the string "true" or "false" to the boolean true false (0 or 1)
630
     * This is used for the Chamilo Config Settings as these store true or false as string
631
     * and the api_get_setting('course_create_active_tools') should be 0 or 1 (used for
632
     * the visibility of the tool).
633
     *
634
     * @param string $variable
635
     *
636
     * @return bool
637
     *
638
     * @author Patrick Cool, [email protected]
639
     * @assert ('true') === true
640
     * @assert ('false') === false
641
     */
642
    public static function string2binary($variable)
643
    {
644
        if ($variable == 'true') {
645
            return true;
646
        }
647
        if ($variable == 'false') {
648
            return false;
649
        }
650
    }
651
652
    /**
653
     * Function register_course to create a record in the course table of the main database.
654
     *
655
     * @param array $params      Course details (see code for details).
656
     * @param int   $accessUrlId Optional.
657
     *
658
     * @return int Created course ID
659
     *
660
     * @todo use an array called $params instead of lots of params
661
     * @assert (null) === false
662
     */
663
    public static function register_course($params, $accessUrlId = 1)
664
    {
665
        global $error_msg;
666
        $title = $params['title'];
667
        // Fix amp
668
        $title = str_replace('&amp;', '&', $title);
669
        $code = $params['code'];
670
        $visual_code = $params['visual_code'];
671
        $directory = $params['directory'];
672
        $tutor_name = isset($params['tutor_name']) ? $params['tutor_name'] : null;
673
        $categoryId = isset($params['category_id']) ? (int) $params['category_id'] : '';
674
        $course_language = isset($params['course_language']) && !empty($params['course_language']) ? $params['course_language'] : api_get_setting(
675
            'platformLanguage'
676
        );
677
        $user_id = empty($params['user_id']) ? api_get_user_id() : intval($params['user_id']);
678
        $department_name = isset($params['department_name']) ? $params['department_name'] : null;
679
        $department_url = isset($params['department_url']) ? $params['department_url'] : null;
680
        $disk_quota = isset($params['disk_quota']) ? $params['disk_quota'] : null;
681
682
        if (!isset($params['visibility'])) {
683
            $default_course_visibility = api_get_setting(
684
                'courses_default_creation_visibility'
685
            );
686
            if (isset($default_course_visibility)) {
687
                $visibility = $default_course_visibility;
688
            } else {
689
                $visibility = COURSE_VISIBILITY_OPEN_PLATFORM;
690
            }
691
        } else {
692
            $visibility = $params['visibility'];
693
        }
694
695
        $subscribe = isset($params['subscribe']) ? (int) $params['subscribe'] : $visibility == COURSE_VISIBILITY_OPEN_PLATFORM ? 1 : 0;
696
        $unsubscribe = isset($params['unsubscribe']) ? (int) $params['unsubscribe'] : 0;
697
        $expiration_date = isset($params['expiration_date']) ? $params['expiration_date'] : null;
698
        $teachers = isset($params['teachers']) ? $params['teachers'] : null;
699
        $status = isset($params['status']) ? $params['status'] : null;
700
701
        $TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER);
702
        $ok_to_register_course = true;
703
704
        // Check whether all the needed parameters are present.
705
        if (empty($code)) {
706
            $error_msg[] = 'courseSysCode is missing';
707
            $ok_to_register_course = false;
708
        }
709
        if (empty($visual_code)) {
710
            $error_msg[] = 'courseScreenCode is missing';
711
            $ok_to_register_course = false;
712
        }
713
        if (empty($directory)) {
714
            $error_msg[] = 'courseRepository is missing';
715
            $ok_to_register_course = false;
716
        }
717
718
        if (empty($title)) {
719
            $error_msg[] = 'title is missing';
720
            $ok_to_register_course = false;
721
        }
722
723
        if (empty($expiration_date)) {
724
            $expiration_date = api_get_utc_datetime(
725
                time() + self::FIRST_EXPIRATION_DATE
726
            );
727
        } else {
728
            $expiration_date = api_get_utc_datetime($expiration_date);
729
        }
730
731
        if ($visibility < 0 || $visibility > 4) {
732
            $error_msg[] = 'visibility is invalid';
733
            $ok_to_register_course = false;
734
        }
735
736
        if (empty($disk_quota)) {
737
            $disk_quota = api_get_setting('default_document_quotum');
738
        }
739
740
        if (stripos($department_url, 'http://') === false && stripos(
741
                $department_url,
742
                'https://'
743
            ) === false
744
        ) {
745
            $department_url = 'http://'.$department_url;
746
        }
747
748
        // just in case
749
        if ($department_url == 'http://') {
750
            $department_url = '';
751
        }
752
        $course_id = 0;
753
754
        if ($ok_to_register_course) {
755
            $repo = Container::getCourseRepository();
756
            $course = new \Chamilo\CoreBundle\Entity\Course();
757
            /** @var \Chamilo\CoreBundle\Entity\CourseCategory $courseCategory */
758
            $courseCategory = Container::getCourseCategoryRepository()->find($categoryId);
759
            $urlId = 1;
760
            if (api_get_current_access_url_id() !== -1) {
761
                $urlId = api_get_current_access_url_id();
762
            }
763
764
            $url = api_get_url_entity($urlId);
765
            $course
766
                ->setCode($code)
767
                ->setDirectory($directory)
768
                ->setCourseLanguage($course_language)
769
                ->setTitle($title)
770
                ->setDescription(get_lang('Course Description'))
771
                ->setCategory($courseCategory)
772
                ->setVisibility($visibility)
773
                ->setShowScore(1)
774
                ->setDiskQuota($disk_quota)
775
                ->setCreationDate(new \DateTime())
776
                ->setExpirationDate(new \DateTime($expiration_date))
777
                ->setDepartmentName($department_name)
778
                ->setDepartmentUrl($department_url)
779
                ->setSubscribe($subscribe)
780
                ->setUnsubscribe($unsubscribe)
781
                ->setVisualCode($visual_code)
782
                ->addUrl($url)
783
            ;
784
            $repo->addResourceNode(
785
                $course,
786
                api_get_user_entity(api_get_user_id()),
787
                $url
788
            );
789
790
            $repo->getEntityManager()->persist($course);
791
792
            $repo->getEntityManager()->persist($course);
793
            $repo->getEntityManager()->flush();
794
795
            $course_id = $course->getId();
796
            if ($course_id) {
797
                $sort = api_max_sort_value('0', api_get_user_id());
798
                // Default true
799
                $addTeacher = isset($params['add_user_as_teacher']) ? $params['add_user_as_teacher'] : true;
800
                if ($addTeacher) {
801
                    $i_course_sort = CourseManager::userCourseSort(
802
                        $user_id,
803
                        $code
804
                    );
805
                    if (!empty($user_id)) {
806
                        $sql = "INSERT INTO ".$TABLECOURSUSER." SET
807
                                c_id     = '".$course_id."',
808
                                user_id         = '".intval($user_id)."',
809
                                status          = '1',
810
                                is_tutor        = '0',
811
                                sort            = '".($i_course_sort)."',
812
                                relation_type = 0,
813
                                user_course_cat = '0'";
814
                        Database::query($sql);
815
                    }
816
                }
817
818
                if (!empty($teachers)) {
819
                    if (!is_array($teachers)) {
820
                        $teachers = [$teachers];
821
                    }
822
                    foreach ($teachers as $key) {
823
                        //just in case
824
                        if ($key == $user_id) {
825
                            continue;
826
                        }
827
                        if (empty($key)) {
828
                            continue;
829
                        }
830
                        $sql = "INSERT INTO ".$TABLECOURSUSER." SET
831
                            c_id     = '".Database::escape_string($course_id)."',
832
                            user_id         = '".Database::escape_string($key)."',
833
                            status          = '1',
834
                            is_tutor        = '0',
835
                            sort            = '".($sort + 1)."',
836
                            relation_type = 0,
837
                            user_course_cat = '0'";
838
                        Database::query($sql);
839
                    }
840
                }
841
842
                // Adding the course to an URL.
843
                UrlManager::add_course_to_url($course_id, $accessUrlId);
844
845
                // Add event to the system log.
846
                $user_id = api_get_user_id();
847
                Event::addEvent(
848
                    LOG_COURSE_CREATE,
849
                    LOG_COURSE_CODE,
850
                    $code,
851
                    api_get_utc_datetime(),
852
                    $user_id,
853
                    $course_id
854
                );
855
856
                $send_mail_to_admin = api_get_setting('send_email_to_admin_when_create_course');
857
858
                // @todo Improve code to send to all current portal administrators.
859
                if ($send_mail_to_admin === 'true') {
860
                    $siteName = api_get_setting('siteName');
861
                    $recipient_email = api_get_setting('emailAdministrator');
862
                    $recipient_name = api_get_person_name(
863
                        api_get_setting('administratorName'),
864
                        api_get_setting('administratorSurname')
865
                    );
866
                    $iname = api_get_setting('Institution');
867
                    $subject = get_lang(
868
                            'NewCourseCreatedIn'
869
                        ).' '.$siteName.' - '.$iname;
870
                    $message = get_lang(
871
                            'Dear'
872
                        ).' '.$recipient_name.",\n\n".get_lang(
873
                            'MessageOfNewCourseToAdmin'
874
                        ).' '.$siteName.' - '.$iname."\n";
875
                    $message .= get_lang('Course name').' '.$title."\n";
876
877
                    if ($courseCategory) {
878
                        $message .= get_lang(
879
                                'Category'
880
                            ).' '.$courseCategory->getCode()."\n";
881
                    }
882
                    $message .= get_lang('Coach').' '.$tutor_name."\n";
883
                    $message .= get_lang('Language').' '.$course_language;
884
885
                    $userInfo = api_get_user_info($user_id);
886
887
                    $additionalParameters = [
888
                        'smsType' => SmsPlugin::NEW_COURSE_BEEN_CREATED,
889
                        'userId' => $user_id,
890
                        'courseName' => $title,
891
                        'creatorUsername' => $userInfo['username'],
892
                    ];
893
894
                    api_mail_html(
895
                        $recipient_name,
896
                        $recipient_email,
897
                        $subject,
898
                        $message,
899
                        $siteName,
900
                        $recipient_email,
901
                        null,
902
                        null,
903
                        null,
904
                        $additionalParameters
905
                    );
906
                }
907
            }
908
        }
909
910
        return $course_id;
911
    }
912
913
    /**
914
     * Generate a new id for c_tool table.
915
     *
916
     * @param int $courseId The course id
917
     *
918
     * @return int the new id
919
     */
920
    public static function generateToolId($courseId)
921
    {
922
        $newIdResultData = Database::select(
923
            'id + 1 AS new_id',
924
            Database::get_course_table(TABLE_TOOL_LIST),
925
            [
926
                'where' => ['c_id = ?' => intval($courseId)],
927
                'order' => 'id',
928
                'limit' => 1,
929
            ],
930
            'first'
931
        );
932
933
        if ($newIdResultData === false) {
934
            return 1;
935
        }
936
937
        return $newIdResultData['new_id'] > 0 ? $newIdResultData['new_id'] : 1;
938
    }
939
}
940