ImportCsv::dumpDatabaseTables()   B
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 111
Code Lines 101

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 101
nc 2
nop 0
dl 0
loc 111
rs 8
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CourseBundle\Entity\CCalendarEvent;
6
use Chamilo\CourseBundle\Entity\CItemProperty;
7
use Chamilo\PluginBundle\Entity\StudentFollowUp\CarePost;
8
use Fhaculty\Graph\Graph;
9
use Monolog\Handler\BufferHandler;
10
use Monolog\Handler\ErrorLogHandler;
11
use Monolog\Handler\RotatingFileHandler;
12
use Monolog\Handler\StreamHandler;
13
use Monolog\Logger;
14
15
if (PHP_SAPI != 'cli') {
16
    exit('Run this script through the command line or comment this line in the code');
17
}
18
19
if (file_exists('multiple_url_fix.php')) {
20
    require 'multiple_url_fix.php';
21
}
22
23
require_once __DIR__.'/../inc/global.inc.php';
24
25
ini_set('memory_limit', -1);
26
ini_set('max_execution_time', 0);
27
ini_set('log_errors', '1');
28
ini_set('display_errors', '1');
29
30
/**
31
 * Class ImportCsv.
32
 */
33
class ImportCsv
34
{
35
    public $test;
36
    public $defaultLanguage = 'dutch';
37
    public $extraFieldIdNameList = [
38
        'session' => 'external_session_id',
39
        'session_career' => 'external_career_id',
40
        'course' => 'external_course_id',
41
        'user' => 'external_user_id',
42
        'calendar_event' => 'external_calendar_event_id',
43
        'career' => 'external_career_id',
44
        'career_urls' => 'career_urls',
45
        'career_diagram' => 'career_diagram',
46
    ];
47
    public $defaultAdminId = 1;
48
    public $defaultSessionVisibility = 1;
49
50
    /**
51
     * When creating a user the expiration date is set to registration date + this value.
52
     *
53
     * @var int number of years
54
     */
55
    public $expirationDateInUserCreation = 1;
56
57
    public $batchSize = 20;
58
59
    /**
60
     * When updating a user the expiration date is set to update date + this value.
61
     *
62
     * @var int number of years
63
     */
64
    public $expirationDateInUserUpdate = 1;
65
    public $daysCoachAccessBeforeBeginning = 14;
66
    public $daysCoachAccessAfterBeginning = 14;
67
    public $conditions;
68
    private $logger;
69
    private $dumpValues;
70
    private $updateEmailToDummy;
71
72
    /**
73
     * @param Monolog\Logger $logger
74
     * @param array
75
     */
76
    public function __construct($logger, $conditions)
77
    {
78
        $this->logger = $logger;
79
        $this->conditions = $conditions;
80
        $this->updateEmailToDummy = false;
81
    }
82
83
    /**
84
     * @param bool $dump
85
     */
86
    public function setDumpValues($dump)
87
    {
88
        $this->dumpValues = $dump;
89
    }
90
91
    /**
92
     * @return bool
93
     */
94
    public function getDumpValues()
95
    {
96
        return $this->dumpValues;
97
    }
98
99
    /**
100
     * Runs the import process.
101
     */
102
    public function run()
103
    {
104
        global $_configuration;
105
106
        $value = api_get_configuration_value('import_csv_custom_url_id');
107
        if (!empty($value)) {
108
            $_configuration['access_url'] = $value;
109
        }
110
111
        $path = api_get_path(SYS_CODE_PATH).'cron/incoming/';
112
        if (!is_dir($path)) {
113
            echo "The folder! $path does not exits";
114
115
            return 0;
116
        }
117
118
        if ($this->getDumpValues()) {
119
            $this->dumpDatabaseTables();
120
        }
121
122
        echo 'Reading files: '.PHP_EOL.PHP_EOL;
123
124
        $files = scandir($path);
125
        $fileToProcess = [];
126
        $fileToProcessStatic = [];
127
        $teacherBackup = [];
128
        $groupBackup = [];
129
130
        $this->prepareImport();
131
132
        if (!empty($files)) {
133
            foreach ($files as $file) {
134
                $fileInfo = pathinfo($file);
135
                if (isset($fileInfo['extension']) && $fileInfo['extension'] === 'csv') {
136
                    // Checking teachers_yyyymmdd.csv,
137
                    // courses_yyyymmdd.csv, students_yyyymmdd.csv and sessions_yyyymmdd.csv
138
                    $parts = explode('_', $fileInfo['filename']);
139
                    $preMethod = ucwords($parts[1]);
140
                    $preMethod = str_replace('-static', 'Static', $preMethod);
141
                    $method = 'import'.$preMethod;
142
                    $isStatic = strpos($method, 'Static');
143
144
                    if ($method == 'importSessionsextidStatic') {
145
                        $method = 'importSessionsExtIdStatic';
146
                    }
147
148
                    if ($method == 'importCourseinsertStatic') {
149
                        $method = 'importSubscribeUserToCourse';
150
                    }
151
152
                    if ($method == 'importUnsubsessionsextidStatic') {
153
                        $method = 'importUnsubsessionsExtidStatic';
154
                    }
155
156
                    if ($method == 'importCareersdiagram') {
157
                        $method = 'importCareersDiagram';
158
                    }
159
160
                    if ($method == 'importCareersresults') {
161
                        $method = 'importCareersResults';
162
                    }
163
164
                    if ($method == 'importCareersresultsremoveStatic') {
165
                        $method = 'importCareersResultsRemoveStatic';
166
                    }
167
168
                    if ($method == 'importOpensessions') {
169
                        $method = 'importOpenSessions';
170
                    }
171
172
                    if ($method == 'importOpensessions') {
173
                        $method = 'importOpenSessions';
174
                    }
175
176
                    if ($method === 'importSessionsall') {
177
                        $method = 'importSessionsUsersCareers';
178
                    }
179
180
                    if ($method === 'importSubsessionsextidStatic') {
181
                        $method = 'importSubscribeUserToCourseSessionExtStatic';
182
                    }
183
184
                    if (method_exists($this, $method)) {
185
                        if ((
186
                                $method == 'importSubscribeStatic' ||
187
                                $method == 'importSubscribeUserToCourse'
188
                            ) ||
189
                            empty($isStatic)
190
                        ) {
191
                            $fileToProcess[$parts[1]][] = [
192
                                'method' => $method,
193
                                'file' => $path.$fileInfo['basename'],
194
                            ];
195
                        } else {
196
                            $fileToProcessStatic[$parts[1]][] = [
197
                                'method' => $method,
198
                                'file' => $path.$fileInfo['basename'],
199
                            ];
200
                        }
201
                    } else {
202
                        echo "Error - This file '$file' can't be processed.".PHP_EOL;
203
                        echo "Trying to call $method".PHP_EOL;
204
                        echo "The file have to has this format:".PHP_EOL;
205
                        echo "prefix_students_ddmmyyyy.csv, prefix_teachers_ddmmyyyy.csv,
206
                        prefix_courses_ddmmyyyy.csv, prefix_sessions_ddmmyyyy.csv ".PHP_EOL;
207
                        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
208
                    }
209
                }
210
            }
211
212
            if (empty($fileToProcess) && empty($fileToProcessStatic)) {
213
                echo 'Error - no files to process.';
214
215
                return 0;
216
            }
217
218
            $sections = [
219
                'students',
220
                'teachers',
221
                'courses',
222
                'sessions',
223
                'sessionsall',
224
                'opensessions',
225
                'subscribe-static',
226
                'courseinsert-static',
227
                'unsubscribe-static',
228
                'care',
229
                'skillset',
230
                //'careers',
231
                //'careersdiagram',
232
                //'careersresults',
233
            ];
234
235
            foreach ($sections as $section) {
236
                if (isset($fileToProcess[$section]) && !empty($fileToProcess[$section])) {
237
                    $this->logger->addInfo("-- Import $section --");
238
                    $files = $fileToProcess[$section];
239
                    foreach ($files as $fileInfo) {
240
                        $method = $fileInfo['method'];
241
                        $file = $fileInfo['file'];
242
                        echo 'File: '.$file.PHP_EOL;
243
                        echo 'Method : '.$method.PHP_EOL;
244
                        echo PHP_EOL;
245
246
                        $this->logger->addInfo('====================================================');
247
                        $this->logger->addInfo("Reading file: $file");
248
                        $this->logger->addInfo("Loading method $method ");
249
                        if ($method == 'importSessions' || $method == 'importOpenSessions') {
250
                            $this->$method(
251
                                $file,
252
                                true,
253
                                $teacherBackup,
254
                                $groupBackup
255
                            );
256
                        } else {
257
                            $this->$method($file, true);
258
                        }
259
                        $this->logger->addInfo('--Finish reading file--');
260
                    }
261
                }
262
            }
263
264
            $sections = [
265
                'students-static',
266
                'teachers-static',
267
                'courses-static',
268
                'sessions-static',
269
                'sessionsextid-static',
270
                'unsubscribe-static',
271
                'unsubsessionsextid-static',
272
                'subsessionsextid-static',
273
                'calendar-static',
274
                //'careersresultsremove-static',
275
            ];
276
277
            foreach ($sections as $section) {
278
                if (isset($fileToProcessStatic[$section]) &&
279
                    !empty($fileToProcessStatic[$section])
280
                ) {
281
                    $this->logger->addInfo("-- Import static files $section --");
282
                    $files = $fileToProcessStatic[$section];
283
                    foreach ($files as $fileInfo) {
284
                        $method = $fileInfo['method'];
285
286
                        $file = $fileInfo['file'];
287
                        echo 'Static file: '.$file.PHP_EOL;
288
                        echo 'Method : '.$method.PHP_EOL;
289
                        echo PHP_EOL;
290
                        $this->logger->addInfo("Reading static file: $file");
291
                        $this->logger->addInfo("Loading method $method ");
292
                        $this->$method(
293
                            $file,
294
                            true,
295
                            $teacherBackup,
296
                            $groupBackup
297
                        );
298
                        $this->logger->addInfo('--Finish reading file--');
299
                    }
300
                }
301
            }
302
303
            $this->logger->addInfo('teacher backup');
304
            $this->logger->addInfo(print_r($teacherBackup, 1));
305
306
            // Careers at the end:
307
            $sections = [
308
                'careers',
309
                'careersdiagram',
310
                'careersresults',
311
            ];
312
313
            foreach ($sections as $section) {
314
                if (isset($fileToProcess[$section]) && !empty($fileToProcess[$section])) {
315
                    $this->logger->addInfo("-- Import $section --");
316
                    $files = $fileToProcess[$section];
317
                    foreach ($files as $fileInfo) {
318
                        $method = $fileInfo['method'];
319
                        $file = $fileInfo['file'];
320
                        echo 'File: '.$file.PHP_EOL;
321
                        echo 'Method : '.$method.PHP_EOL;
322
                        echo PHP_EOL;
323
324
                        $this->logger->addInfo('====================================================');
325
                        $this->logger->addInfo("Reading file: $file");
326
                        $this->logger->addInfo("Loading method $method ");
327
                        $this->$method($file, true);
328
                        $this->logger->addInfo('--Finish reading file--');
329
                    }
330
                }
331
            }
332
333
            $removeResults = 'careersresultsremove-static';
334
            if (isset($fileToProcessStatic[$removeResults]) &&
335
                !empty($fileToProcessStatic[$removeResults])
336
            ) {
337
                $files = $fileToProcessStatic[$removeResults];
338
                foreach ($files as $fileInfo) {
339
                    $method = $fileInfo['method'];
340
                    $file = $fileInfo['file'];
341
                    echo 'Static file: '.$file.PHP_EOL;
342
                    echo 'Method : '.$method.PHP_EOL;
343
                    echo PHP_EOL;
344
                    $this->logger->addInfo("Reading static file: $file");
345
                    $this->logger->addInfo("Loading method $method ");
346
                    $this->$method(
347
                        $file,
348
                        true
349
                    );
350
                    $this->logger->addInfo('--Finish reading file--');
351
                }
352
            }
353
        }
354
    }
355
356
    /**
357
     * @param $file
358
     * @param bool $moveFile
359
     */
360
    public function importCare($file, $moveFile = false)
361
    {
362
        $data = Import::csv_reader($file);
363
        $counter = 1;
364
        $batchSize = $this->batchSize;
365
        $em = Database::getManager();
366
367
        if (!empty($data)) {
368
            $this->logger->addInfo(count($data)." records found.");
369
            $items = [];
370
            foreach ($data as $list) {
371
                $post = [];
372
                foreach ($list as $key => $value) {
373
                    $key = (string) trim($key);
374
                    // Remove utf8 bom
375
                    $key = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $key);
376
                    $post[$key] = $value;
377
                }
378
379
                if (empty($post)) {
380
                    continue;
381
                }
382
383
                $externalId = $post['External_care_id'];
384
                $items[$externalId] = $post;
385
            }
386
            ksort($items);
387
388
            foreach ($items as $row) {
389
                // Insert user
390
                //$insertUserInfo = api_get_user_info_from_username($row['Added_by']);
391
392
                // User about the post
393
                $userId = UserManager::get_user_id_from_original_id(
394
                    $row['Added_by'],
395
                    $this->extraFieldIdNameList['user']
396
                );
397
398
                $insertUserInfo = api_get_user_info($userId);
399
400
                if (empty($insertUserInfo)) {
401
                    $this->logger->addInfo("User: '".$row['Added_by']."' doesn't exists. Skip this entry.");
402
                    continue;
403
                }
404
                $insertUserInfo = api_get_user_entity($insertUserInfo['user_id']);
405
406
                // User about the post
407
                $userId = UserManager::get_user_id_from_original_id(
408
                    $row['External_user_id'],
409
                    $this->extraFieldIdNameList['user']
410
                );
411
412
                if (empty($userId)) {
413
                    $this->logger->addInfo("User does '".$row['External_user_id']."' not exists skip this entry.");
414
                    continue;
415
                }
416
417
                $userInfo = api_get_user_entity($userId);
418
419
                if (empty($userInfo)) {
420
                    $this->logger->addInfo("Chamilo user does not found: #".$userId."' ");
421
                    continue;
422
                }
423
424
                // Dates
425
                $createdAt = $this->createDateTime($row['Added_On']);
426
                $updatedAt = $this->createDateTime($row['Edited_on']);
427
428
                // Parent
429
                $parent = null;
430
                if (!empty($row['Parent_id'])) {
431
                    $parentId = $items[$row['Parent_id']];
432
                    $criteria = [
433
                        'externalCareId' => $parentId,
434
                    ];
435
                    $parent = $em->getRepository('ChamiloPluginBundle:StudentFollowUp\CarePost')->findOneBy($criteria);
436
                }
437
438
                // Tags
439
                $tags = explode(',', $row['Tags']);
440
441
                // Check if post already was added:
442
                $criteria = [
443
                    'externalCareId' => $row['External_care_id'],
444
                ];
445
                $post = $em->getRepository('ChamiloPluginBundle:StudentFollowUp\CarePost')->findOneBy($criteria);
446
447
                if (empty($post)) {
448
                    $post = new CarePost();
449
                    $this->logger->addInfo("New post will be created no match for externalCareId = ".$row['External_care_id']);
450
                }
451
452
                $contentDecoded = utf8_encode(base64_decode($row['Article']));
453
454
                $post
455
                    ->setTitle($row['Title'])
456
                    ->setContent($contentDecoded)
457
                    ->setExternalCareId($row['External_care_id'])
458
                    ->setCreatedAt($createdAt)
459
                    ->setUpdatedAt($updatedAt)
460
                    ->setPrivate((int) $row['Private'])
461
                    ->setInsertUser($insertUserInfo)
462
                    ->setExternalSource((int) $row['Source_is_external'])
463
                    ->setParent($parent)
464
                    ->setTags($tags)
465
                    ->setUser($userInfo)
466
                    ->setAttachment($row['Attachement'])
467
                ;
468
                $em->persist($post);
469
                $em->flush();
470
471
                $this->logger->addInfo("Post id saved #".$post->getId());
472
473
                if (($counter % $batchSize) === 0) {
474
                    $em->flush();
475
                    $em->clear(); // Detaches all objects from Doctrine!
476
                }
477
                $counter++;
478
            }
479
480
            $em->clear(); // Detaches all objects from Doctrine!
481
        }
482
    }
483
484
    /**
485
     * @return mixed
486
     */
487
    public function getUpdateEmailToDummy()
488
    {
489
        return $this->updateEmailToDummy;
490
    }
491
492
    /**
493
     * @param mixed $updateEmailToDummy
494
     */
495
    public function setUpdateEmailToDummy($updateEmailToDummy)
496
    {
497
        $this->updateEmailToDummy = $updateEmailToDummy;
498
    }
499
500
    /**
501
     * Change emails of all users except admins.
502
     */
503
    public function updateUsersEmails()
504
    {
505
        if ($this->getUpdateEmailToDummy() === true) {
506
            $sql = "UPDATE user SET email = CONCAT(username,'@example.com') WHERE id NOT IN (SELECT user_id FROM admin)";
507
            Database::query($sql);
508
        }
509
    }
510
511
    /**
512
     * Prepares extra fields before the import.
513
     */
514
    private function prepareImport()
515
    {
516
        // Create user extra field: extra_external_user_id
517
        UserManager::create_extra_field(
518
            $this->extraFieldIdNameList['user'],
519
            1,
520
            'External user id',
521
            null
522
        );
523
524
        // Create course extra field: extra_external_course_id
525
        CourseManager::create_course_extra_field(
526
            $this->extraFieldIdNameList['course'],
527
            1,
528
            'External course id',
529
            ''
530
        );
531
532
        // Course skill set.
533
        CourseManager::create_course_extra_field(
534
            'skillset',
535
            1,
536
            'Skill set',
537
            ''
538
        );
539
540
        CourseManager::create_course_extra_field(
541
            'disable_import_calendar',
542
            13,
543
            'Disable import calendar',
544
            ''
545
        );
546
547
        // Create session extra field extra_external_session_id
548
        SessionManager::create_session_extra_field(
549
            $this->extraFieldIdNameList['session'],
550
            1,
551
            'External session id'
552
        );
553
554
        SessionManager::create_session_extra_field(
555
            $this->extraFieldIdNameList['session_career'],
556
            1,
557
            'Career id'
558
        );
559
560
        // Create calendar_event extra field extra_external_session_id
561
        $extraField = new ExtraField('calendar_event');
562
        $extraField->save(
563
            [
564
                'field_type' => ExtraField::FIELD_TYPE_TEXT,
565
                'variable' => $this->extraFieldIdNameList['calendar_event'],
566
                'display_text' => 'External calendar event id',
567
            ]
568
        );
569
570
        $extraField = new ExtraField('career');
571
        $extraField->save(
572
            [
573
                'visible_to_self' => 1,
574
                'field_type' => ExtraField::FIELD_TYPE_TEXT,
575
                'variable' => $this->extraFieldIdNameList['career'],
576
                'display_text' => 'External career id',
577
            ]
578
        );
579
580
        $extraField->save(
581
            [
582
                'visible_to_self' => 1,
583
                'field_type' => ExtraField::FIELD_TYPE_TEXTAREA,
584
                'variable' => $this->extraFieldIdNameList['career_diagram'],
585
                'display_text' => 'Career diagram',
586
            ]
587
        );
588
589
        $extraField->save(
590
            [
591
                'visible_to_self' => 1,
592
                'field_type' => ExtraField::FIELD_TYPE_TEXTAREA,
593
                'variable' => $this->extraFieldIdNameList['career_urls'],
594
                'display_text' => 'Career urls',
595
            ]
596
        );
597
    }
598
599
    /**
600
     * @param string $file
601
     */
602
    private function moveFile($file)
603
    {
604
        $moved = str_replace('incoming', 'treated', $file);
605
606
        if ($this->test) {
607
            $result = 1;
608
        } else {
609
            $result = rename($file, $moved);
610
        }
611
612
        if ($result) {
613
            $this->logger->addInfo("Moving file to the treated folder: $file");
614
        } else {
615
            $this->logger->addError(
616
                "Error - Cant move file to the treated folder: $file"
617
            );
618
        }
619
    }
620
621
    /**
622
     * @param array $row
623
     *
624
     * @return array
625
     */
626
    private function cleanUserRow($row)
627
    {
628
        $row['lastname'] = $row['LastName'];
629
        $row['firstname'] = $row['FirstName'];
630
        $row['email'] = $row['Email'];
631
        $row['username'] = $row['UserName'];
632
        $row['password'] = $row['Password'];
633
        $row['auth_source'] = isset($row['AuthSource']) ? $row['AuthSource'] : PLATFORM_AUTH_SOURCE;
634
        $row['official_code'] = $row['OfficialCode'];
635
        $row['phone'] = isset($row['PhoneNumber']) ? $row['PhoneNumber'] : '';
636
637
        if (isset($row['StudentID'])) {
638
            $row['extra_'.$this->extraFieldIdNameList['user']] = $row['StudentID'];
639
        }
640
641
        if (isset($row['TeacherID'])) {
642
            $row['extra_'.$this->extraFieldIdNameList['user']] = $row['TeacherID'];
643
        }
644
645
        return $row;
646
    }
647
648
    /**
649
     * @param array $row
650
     *
651
     * @return array
652
     */
653
    private function cleanCourseRow($row)
654
    {
655
        $row['title'] = $row['Title'];
656
        $row['course_code'] = $row['Code'];
657
        $row['course_category'] = $row['CourseCategory'];
658
        $row['email'] = $row['Teacher'];
659
        $row['language'] = $row['Language'];
660
        $row['visibility'] = isset($row['Visibility']) ? $row['Visibility'] : COURSE_VISIBILITY_REGISTERED;
661
662
        $row['teachers'] = [];
663
        if (isset($row['Teacher']) && !empty($row['Teacher'])) {
664
            $this->logger->addInfo("Teacher list found: ".$row['Teacher']);
665
            $teachers = explode(',', $row['Teacher']);
666
            if (!empty($teachers)) {
667
                foreach ($teachers as $teacherUserName) {
668
                    $teacherUserName = trim($teacherUserName);
669
                    $userInfo = api_get_user_info_from_username($teacherUserName);
670
                    if (!empty($userInfo)) {
671
                        $this->logger->addInfo("Username found: $teacherUserName");
672
                        $row['teachers'][] = $userInfo['user_id'];
673
                    }
674
                }
675
            }
676
        }
677
678
        if (isset($row['CourseID'])) {
679
            $row['extra_'.$this->extraFieldIdNameList['course']] = $row['CourseID'];
680
        }
681
682
        return $row;
683
    }
684
685
    /**
686
     * File to import.
687
     *
688
     * @param string $file
689
     */
690
    private function importTeachersStatic($file)
691
    {
692
        $this->importTeachers($file, true);
693
    }
694
695
    /**
696
     * File to import.
697
     *
698
     * @param string $file
699
     * @param bool   $moveFile
700
     */
701
    private function importTeachers($file, $moveFile = true)
702
    {
703
        $this->fixCSVFile($file);
704
        $data = Import::csvToArray($file);
705
706
        /* Unique identifier: official-code username.
707
        Email address and password should never get updated. *ok
708
        The only fields that I can think of that should update if the data changes in the csv file are FirstName and LastName. *ok
709
        A slight edit of these fields should be taken into account. ???
710
        Adding teachers is no problem, but deleting them shouldn’t be automated, but we should get a log of “to delete teachers”.
711
        We’ll handle that manually if applicable.
712
        No delete!
713
        */
714
        $language = $this->defaultLanguage;
715
716
        if (!empty($data)) {
717
            $this->logger->addInfo(count($data)." records found.");
718
            $expirationDateOnCreation = api_get_utc_datetime(strtotime("+".intval($this->expirationDateInUserCreation)."years"));
719
            $expirationDateOnUpdate = api_get_utc_datetime(strtotime("+".intval($this->expirationDateInUserUpdate)."years"));
720
721
            $batchSize = $this->batchSize;
722
            $em = Database::getManager();
723
            $counter = 1;
724
            foreach ($data as $row) {
725
                $row = $this->cleanUserRow($row);
726
                $externalUserId = $row['official_code'];
727
                $row['extra_'.$this->extraFieldIdNameList['user']] = $externalUserId;
728
729
                $user_id = UserManager::get_user_id_from_original_id(
730
                    $row['extra_'.$this->extraFieldIdNameList['user']],
731
                    $this->extraFieldIdNameList['user']
732
                );
733
                $userInfo = [];
734
                $userInfoByOfficialCode = null;
735
736
                if (!empty($user_id)) {
737
                    $userInfo = api_get_user_info($user_id);
738
                    $userInfoByOfficialCode = api_get_user_info_from_official_code($row['official_code']);
739
                }
740
741
                if (empty($userInfo) && empty($userInfoByOfficialCode)) {
742
                    // Create user
743
                    $userId = UserManager::create_user(
744
                        $row['firstname'],
745
                        $row['lastname'],
746
                        COURSEMANAGER,
747
                        $row['email'],
748
                        $row['username'],
749
                        $row['password'],
750
                        $row['official_code'],
751
                        $language, //$row['language'],
752
                        $row['phone'],
753
                        null, //$row['picture'], //picture
754
                        $row['auth_source'], // ?
755
                        $expirationDateOnCreation, //'0000-00-00 00:00:00', //$row['expiration_date'], //$expiration_date = '0000-00-00 00:00:00',
756
                        1, //active
757
                        0,
758
                        null, // extra
759
                        null, //$encrypt_method = '',
760
                        false //$send_mail = false
761
                    );
762
763
                    $row['extra_mail_notify_invitation'] = 1;
764
                    $row['extra_mail_notify_message'] = 1;
765
                    $row['extra_mail_notify_group_message'] = 1;
766
767
                    if ($userId) {
768
                        foreach ($row as $key => $value) {
769
                            if (substr($key, 0, 6) == 'extra_') {
770
                                //an extra field
771
                                UserManager::update_extra_field_value(
772
                                    $userId,
773
                                    substr($key, 6),
774
                                    $value
775
                                );
776
                            }
777
                        }
778
                        $this->logger->addInfo("Teachers - User created: ".$row['username']);
779
                    } else {
780
                        $this->logger->addError("Teachers - User NOT created: ".$row['username']." ".$row['firstname']." ".$row['lastname']);
781
                        $this->logger->addError(strip_tags(Display::getFlashToString()));
782
                        Display::cleanFlashMessages();
783
                    }
784
                } else {
785
                    if (empty($userInfo)) {
786
                        $this->logger->addError("Teachers - Can't update user :".$row['username']);
787
                        continue;
788
                    }
789
790
                    // Update user
791
                    $result = UserManager::update_user(
792
                        $userInfo['user_id'],
793
                        $row['firstname'], // <<-- changed
794
                        $row['lastname'], // <<-- changed
795
                        $userInfo['username'],
796
                        null, //$password = null,
797
                        $row['auth_source'],
798
                        $userInfo['email'],
799
                        COURSEMANAGER,
800
                        $userInfo['official_code'],
801
                        $userInfo['phone'],
802
                        $userInfo['picture_uri'],
803
                        $expirationDateOnUpdate,
804
                        $userInfo['active'],
805
                        null, //$creator_id = null,
806
                        0, //$hr_dept_id = 0,
807
                        null, // $extra = null,
808
                        null, //$language = 'english',
809
                        null, //$encrypt_method = '',
810
                        false, //$send_email = false,
811
                        0 //$reset_password = 0
812
                    );
813
814
                    $table = Database::get_main_table(TABLE_MAIN_USER);
815
                    $authSource = Database::escape_string($row['auth_source']);
816
                    $sql = "UPDATE $table SET auth_source = '$authSource' WHERE id = ".$userInfo['user_id'];
817
                    Database::query($sql);
818
819
                    $this->logger->addInfo(
820
                        'Teachers - #'.$userInfo['user_id']." auth_source was changed from '".$userInfo['auth_source']."' to '".$row['auth_source']."' "
821
                    );
822
823
                    if ($result) {
824
                        foreach ($row as $key => $value) {
825
                            if (substr($key, 0, 6) == 'extra_') {
826
                                //an extra field
827
                                UserManager::update_extra_field_value(
828
                                    $userInfo['user_id'],
829
                                    substr($key, 6),
830
                                    $value
831
                                );
832
                            }
833
                        }
834
                        $this->logger->addInfo("Teachers - User updated: ".$row['username']);
835
                    } else {
836
                        $this->logger->addError("Teachers - User not updated: ".$row['username']);
837
                    }
838
                }
839
840
                if (($counter % $batchSize) === 0) {
841
                    $em->flush();
842
                    $em->clear(); // Detaches all objects from Doctrine!
843
                }
844
                $counter++;
845
            }
846
847
            $em->clear(); // Detaches all objects from Doctrine!
848
        }
849
850
        if ($moveFile) {
851
            $this->moveFile($file);
852
        }
853
854
        $this->updateUsersEmails();
855
    }
856
857
    /**
858
     * @param string $file
859
     */
860
    private function importStudentsStatic($file)
861
    {
862
        $this->importStudents($file, true);
863
    }
864
865
    /**
866
     * @param string $file
867
     * @param bool   $moveFile
868
     */
869
    private function importStudents($file, $moveFile = true)
870
    {
871
        $this->fixCSVFile($file);
872
        $data = Import::csvToArray($file);
873
874
        /*
875
         * Another users import.
876
        Unique identifier: official code and username . ok
877
        Password should never get updated. ok
878
        If an update should need to occur (because it changed in the .csv),
879
        we’ll want that logged. We will handle this manually in that case.
880
        All other fields should be updateable, though passwords should of course not get updated. ok
881
        If a user gets deleted (not there anymore),
882
        He should be set inactive one year after the current date.
883
        So I presume you’ll just update the expiration date.
884
        We want to grant access to courses up to a year after deletion.
885
         */
886
        $timeStart = microtime(true);
887
888
        $batchSize = $this->batchSize;
889
        $em = Database::getManager();
890
891
        if (!empty($data)) {
892
            $language = $this->defaultLanguage;
893
            $this->logger->addInfo(count($data)." records found.");
894
895
            $expirationDateOnCreate = api_get_utc_datetime(
896
                strtotime("+".intval($this->expirationDateInUserCreation)."years")
897
            );
898
            $expirationDateOnUpdate = api_get_utc_datetime(
899
                strtotime("+".intval($this->expirationDateInUserUpdate)."years")
900
            );
901
902
            $counter = 1;
903
            $secondsInYear = 365 * 24 * 60 * 60;
904
905
            foreach ($data as $row) {
906
                $row = $this->cleanUserRow($row);
907
                $externalUserId = $row['official_code'];
908
                $row['extra_'.$this->extraFieldIdNameList['user']] = $externalUserId;
909
910
                $user_id = UserManager::get_user_id_from_original_id(
911
                    $row['extra_'.$this->extraFieldIdNameList['user']],
912
                    $this->extraFieldIdNameList['user']
913
                );
914
915
                $userInfo = [];
916
                $userInfoByOfficialCode = null;
917
                if (!empty($user_id)) {
918
                    $userInfo = api_get_user_info($user_id, false, true);
919
                    $userInfoByOfficialCode = api_get_user_info_from_official_code($row['official_code']);
920
                }
921
922
                $userInfoFromUsername = api_get_user_info_from_username($row['username']);
923
                if (!empty($userInfoFromUsername)) {
924
                    $extraFieldValue = new ExtraFieldValue('user');
925
                    $extraFieldValues = $extraFieldValue->get_values_by_handler_and_field_variable(
926
                        $userInfoFromUsername['user_id'],
927
                        $this->extraFieldIdNameList['user']
928
                    );
929
930
                    if (!empty($extraFieldValues)) {
931
                        $value = 0;
932
                        foreach ($extraFieldValues as $extraFieldValue) {
933
                            if (isset($extraFieldValue['value'])) {
934
                                $value = $extraFieldValue['value'];
935
                            }
936
                        }
937
                        if (!empty($user_id) && $value != $user_id) {
938
                            $emails = api_get_configuration_value('cron_notification_help_desk');
939
                            if (!empty($emails)) {
940
                                $this->logger->addInfo('Preparing email to users in configuration: "cron_notification_help_desk"');
941
                                $subject = 'User not added due to same username';
942
                                $body = 'Cannot add username: "'.$row['username'].'"
943
                                    with external_user_id: '.$row['extra_'.$this->extraFieldIdNameList['user']].'
944
                                    because '.$userInfoFromUsername['username'].' with external_user_id '.$value.' exists on the portal';
945
                                $this->logger->addInfo($body);
946
                                foreach ($emails as $email) {
947
                                    api_mail_html('', $email, $subject, $body);
948
                                }
949
                            }
950
                        }
951
                    }
952
                }
953
954
                if (empty($userInfo) && empty($userInfoByOfficialCode)) {
955
                    // Create user
956
                    $result = UserManager::create_user(
957
                        $row['firstname'],
958
                        $row['lastname'],
959
                        STUDENT,
960
                        $row['email'],
961
                        $row['username'],
962
                        $row['password'],
963
                        $row['official_code'],
964
                        $language, //$row['language'],
965
                        $row['phone'],
966
                        null, //$row['picture'], //picture
967
                        $row['auth_source'], // ?
968
                        $expirationDateOnCreate,
969
                        1, //active
970
                        0,
971
                        null, // extra
972
                        null, //$encrypt_method = '',
973
                        false //$send_mail = false
974
                    );
975
976
                    $row['extra_mail_notify_invitation'] = 1;
977
                    $row['extra_mail_notify_message'] = 1;
978
                    $row['extra_mail_notify_group_message'] = 1;
979
980
                    if ($result) {
981
                        foreach ($row as $key => $value) {
982
                            if (substr($key, 0, 6) === 'extra_') {
983
                                //an extra field
984
                                UserManager::update_extra_field_value(
985
                                    $result,
986
                                    substr($key, 6),
987
                                    $value
988
                                );
989
                            }
990
                        }
991
                        $this->logger->addInfo("Students - User created: ".$row['username']);
992
                    } else {
993
                        $this->logger->addError("Students - User NOT created: ".$row['username']." ".$row['firstname']." ".$row['lastname']);
994
                        $this->logger->addError(strip_tags(Display::getFlashToString()));
995
                        Display::cleanFlashMessages();
996
                    }
997
                } else {
998
                    if (empty($userInfo)) {
999
                        $this->logger->addError("Students - Can't update user :".$row['username']);
1000
                        continue;
1001
                    }
1002
1003
                    if (isset($row['action']) && $row['action'] === 'delete') {
1004
                        // Inactive one year later
1005
                        $userInfo['expiration_date'] = api_get_utc_datetime(api_strtotime(time() + $secondsInYear));
1006
                    }
1007
1008
                    $password = $row['password']; // change password
1009
                    $email = $row['email']; // change email
1010
                    $resetPassword = 2; // allow password change
1011
1012
                    // Conditions that disables the update of password and email:
1013
                    if (isset($this->conditions['importStudents'])) {
1014
                        if (isset($this->conditions['importStudents']['update']) &&
1015
                            isset($this->conditions['importStudents']['update']['avoid'])
1016
                        ) {
1017
                            // Blocking email update -
1018
                            // 1. Condition
1019
                            $avoidUsersWithEmail = $this->conditions['importStudents']['update']['avoid']['email'];
1020
                            if ($userInfo['email'] != $row['email'] && in_array($row['email'], $avoidUsersWithEmail)) {
1021
                                $this->logger->addInfo("Students - User email is not updated : ".$row['username']." because the avoid conditions (email).");
1022
                                // Do not change email keep the old email.
1023
                                $email = $userInfo['email'];
1024
                            }
1025
1026
                            // 2. Condition
1027
                            if (!in_array($userInfo['email'], $avoidUsersWithEmail) && !in_array($row['email'], $avoidUsersWithEmail)) {
1028
                                $this->logger->addInfo("Students - User email is not updated from ".$userInfo['email']." to ".$row['email']." because the avoid conditions (email).");
1029
                                $email = $userInfo['email'];
1030
                            }
1031
1032
                            // 3. Condition
1033
                            if (in_array($userInfo['email'], $avoidUsersWithEmail) && !in_array($row['email'], $avoidUsersWithEmail)) {
1034
                                $this->logger->addInfo('Email to be updated from:'.$userInfo['email'].' to '.$row['email']);
1035
                                $email = $row['email'];
1036
                            }
1037
1038
                            // Blocking password update
1039
                            //$avoidUsersWithPassword = $this->conditions['importStudents']['update']['avoid']['password'];
1040
1041
                            /*if (isset($row['password'])) {
1042
                                $user = api_get_user_entity($userInfo['id']);
1043
                                $encoded = UserManager::encryptPassword(
1044
                                    $row['password'],
1045
                                    $user
1046
                                );
1047
1048
                                if ($userInfo['password'] != $encoded &&
1049
                                    in_array($row['password'], $avoidUsersWithPassword)
1050
                                ) {
1051
                                    $this->logger->addInfo(
1052
                                        "Students - User password is not updated: ".$row['username']." because the avoid conditions (password)."
1053
                                    );
1054
                                    $password = null;
1055
                                    $resetPassword = 0; // disallow password change
1056
                                }
1057
                            }*/
1058
                        }
1059
                    }
1060
1061
                    // Always disallow password change during update
1062
                    $password = null;
1063
                    $resetPassword = 0; // disallow password change
1064
1065
                    // Update user
1066
                    $result = UserManager::update_user(
1067
                        $userInfo['user_id'],
1068
                        $row['firstname'], // <<-- changed
1069
                        $row['lastname'], // <<-- changed
1070
                        $row['username'], // <<-- changed
1071
                        $password, //$password = null,
1072
                        $row['auth_source'],
1073
                        $email,
1074
                        STUDENT,
1075
                        $userInfo['official_code'],
1076
                        $userInfo['phone'],
1077
                        $userInfo['picture_uri'],
1078
                        $expirationDateOnUpdate,
1079
                        $userInfo['active'],
1080
                        null, //$creator_id = null,
1081
                        0, //$hr_dept_id = 0,
1082
                        null, // $extra = null,
1083
                        null, //$language = 'english',
1084
                        null, //$encrypt_method = '',
1085
                        false, //$send_email = false,
1086
                        $resetPassword //$reset_password = 0
1087
                    );
1088
1089
                    $table = Database::get_main_table(TABLE_MAIN_USER);
1090
                    $authSource = Database::escape_string($row['auth_source']);
1091
                    $sql = "UPDATE $table SET auth_source = '$authSource' WHERE id = ".$userInfo['user_id'];
1092
                    Database::query($sql);
1093
1094
                    $this->logger->addInfo(
1095
                        "Students - #".$userInfo['user_id']." auth_source was changed from '".$userInfo['auth_source']."' to '".$row['auth_source']."' "
1096
                    );
1097
1098
                    if ($result) {
1099
                        if ($row['username'] != $userInfo['username']) {
1100
                            $this->logger->addInfo("Students - Username was changes from '".$userInfo['username']."' to '".$row['username']."' ");
1101
                        }
1102
                        foreach ($row as $key => $value) {
1103
                            if (substr($key, 0, 6) === 'extra_') {
1104
                                //an extra field
1105
                                UserManager::update_extra_field_value(
1106
                                    $userInfo['user_id'],
1107
                                    substr($key, 6),
1108
                                    $value
1109
                                );
1110
                            }
1111
                        }
1112
                        $this->logger->addInfo(
1113
                            'Students - User updated: username:'.$row['username'].' firstname:'.$row['firstname'].' lastname:'.$row['lastname'].' email:'.$email
1114
                        );
1115
                    } else {
1116
                        $this->logger->addError("Students - User NOT updated: ".$row['username']." ".$row['firstname']." ".$row['lastname']);
1117
                    }
1118
                }
1119
1120
                if (($counter % $batchSize) === 0) {
1121
                    $em->flush();
1122
                    $em->clear(); // Detaches all objects from Doctrine!
1123
                    $this->logger->addInfo("Detaches all objects");
1124
                }
1125
                $counter++;
1126
            }
1127
            $em->clear(); // Detaches all objects from Doctrine!
1128
        }
1129
1130
        $timeEnd = microtime(true);
1131
        $executionTime = round(($timeEnd - $timeStart) / 60, 2);
1132
        $this->logger->addInfo("Execution Time for process students: $executionTime Min");
1133
1134
        if ($moveFile) {
1135
            $this->moveFile($file);
1136
        }
1137
1138
        $this->updateUsersEmails();
1139
    }
1140
1141
    /**
1142
     * @param string $file
1143
     */
1144
    private function importCoursesStatic($file, $moveFile, &$teacherBackup = [], &$groupBackup = [])
1145
    {
1146
        $this->importCourses($file, true, $teacherBackup, $groupBackup);
1147
    }
1148
1149
    /**
1150
     * @param string $file
1151
     * @param bool   $moveFile
1152
     *
1153
     * @return int
1154
     */
1155
    private function importCalendarStatic($file, $moveFile = true)
1156
    {
1157
        $this->fixCSVFile($file);
1158
1159
        $this->updateUsersEmails();
1160
        $data = Import::csvToArray($file);
1161
1162
        if (!empty($data)) {
1163
            $this->logger->addInfo(count($data).' records found.');
1164
            $eventsToCreate = [];
1165
            $errorFound = false;
1166
1167
            $courseExtraFieldValue = new ExtraFieldValue('course');
1168
1169
            foreach ($data as $row) {
1170
                $sessionId = null;
1171
                $externalSessionId = null;
1172
                if (isset($row['external_sessionID'])) {
1173
                    $externalSessionId = $row['external_sessionID'];
1174
                    $sessionId = SessionManager::getSessionIdFromOriginalId(
1175
                        $externalSessionId,
1176
                        $this->extraFieldIdNameList['session']
1177
                    );
1178
                }
1179
1180
                $courseCode = null;
1181
                if (isset($row['coursecode'])) {
1182
                    $courseCode = $row['coursecode'];
1183
                }
1184
                $courseInfo = api_get_course_info($courseCode);
1185
                $courseId = $courseInfo['real_id'] ?? 0;
1186
1187
                $item = $courseExtraFieldValue->get_values_by_handler_and_field_variable(
1188
                    $courseId,
1189
                    'disable_import_calendar'
1190
                );
1191
1192
                if (!empty($item) && isset($item['value']) && $item['value'] == 1) {
1193
                    $this->logger->addInfo(
1194
                        "Course '".$courseInfo['code']."' has 'disable_import_calendar' turn on. Skip"
1195
                    );
1196
                    $errorFound = true;
1197
                }
1198
1199
                if (empty($courseInfo)) {
1200
                    $this->logger->addInfo("Course '$courseCode' does not exists");
1201
                } else {
1202
                    if ($courseInfo['visibility'] == COURSE_VISIBILITY_HIDDEN) {
1203
                        $this->logger->addInfo("Course '".$courseInfo['code']."' has hidden visibility. Skip");
1204
                        $errorFound = true;
1205
                    }
1206
                }
1207
1208
                if (empty($sessionId)) {
1209
                    $this->logger->addInfo("external_sessionID: $externalSessionId does not exists.");
1210
                }
1211
                $teacherId = null;
1212
                $sessionInfo = [];
1213
                if (!empty($sessionId) && !empty($courseInfo)) {
1214
                    $sessionInfo = api_get_session_info($sessionId);
1215
                    $courseIncluded = SessionManager::relation_session_course_exist($sessionId, $courseId);
1216
1217
                    if ($courseIncluded == false) {
1218
                        $this->logger->addInfo(
1219
                            "Course '$courseCode' is not included in session: $sessionId"
1220
                        );
1221
                        $errorFound = true;
1222
                    } else {
1223
                        $teachers = CourseManager::get_coach_list_from_course_code($courseInfo['code'], $sessionId);
1224
1225
                        // Getting first teacher.
1226
                        if (!empty($teachers)) {
1227
                            $teacher = current($teachers);
1228
                            $teacherId = $teacher['user_id'];
1229
                        } else {
1230
                            $teacherId = $sessionInfo['id_coach'];
1231
                        }
1232
                    }
1233
                } else {
1234
                    $errorFound = true;
1235
                }
1236
1237
                if (empty($teacherId)) {
1238
                    $errorFound = true;
1239
                    $this->logger->addInfo(
1240
                        "No teacher found in course code : '$courseCode' and session: '$sessionId'"
1241
                    );
1242
                }
1243
1244
                $date = $row['date'];
1245
                $startTime = $row['time_start'];
1246
                $endTime = $row['time_end'];
1247
                $title = $row['title'];
1248
                $comment = $row['comment'] ?? '';
1249
                $color = $row['color'] ?? '';
1250
1251
                $startDateYear = substr($date, 0, 4);
1252
                $startDateMonth = substr($date, 4, 2);
1253
                $startDateDay = substr($date, 6, 8);
1254
1255
                $startDate = $startDateYear.'-'.$startDateMonth.'-'.$startDateDay.' '.$startTime.':00';
1256
                $endDate = $startDateYear.'-'.$startDateMonth.'-'.$startDateDay.' '.$endTime.':00';
1257
1258
                if (!api_is_valid_date($startDate) || !api_is_valid_date($endDate)) {
1259
                    $this->logger->addInfo("Verify your dates: '$startDate' : '$endDate' ");
1260
                    $errorFound = true;
1261
                }
1262
1263
                // Check session dates.
1264
                if ($sessionInfo && !empty($sessionInfo['access_start_date'])) {
1265
                    $date = new \DateTime($sessionInfo['access_start_date']);
1266
                    $intervalInput = '7';
1267
                    if (!empty($row['dateinterval'])) {
1268
                        if ((int) $row['dateinterval'] >= 0) {
1269
                            $intervalInput = (int) $row['dateinterval'];
1270
                        }
1271
                    }
1272
                    $interval = new \DateInterval('P'.$intervalInput.'D');
1273
                    $date->sub($interval);
1274
                    if ($date->getTimestamp() > time()) {
1275
                        $this->logger->addInfo(
1276
                            "Calendar event # ".$row['external_calendar_itemID']."
1277
                            in session [$externalSessionId] was not added
1278
                            because the startdate is more than $intervalInput days in the future: ".$sessionInfo['access_start_date']
1279
                        );
1280
                        $errorFound = true;
1281
                    }
1282
                }
1283
1284
                $sendAnnouncement = false;
1285
                if (isset($row['sendmail']) && 1 === (int) $row['sendmail']) {
1286
                    $sendAnnouncement = true;
1287
                }
1288
1289
                // New condition.
1290
                if ($errorFound == false) {
1291
                    $eventsToCreate[] = [
1292
                        'start' => $startDate,
1293
                        'end' => $endDate,
1294
                        'title' => $title,
1295
                        'sender_id' => $teacherId,
1296
                        'course_id' => $courseInfo['real_id'],
1297
                        'session_id' => $sessionId,
1298
                        'comment' => $comment,
1299
                        'color' => $color,
1300
                        'send_announcement' => $sendAnnouncement,
1301
                        $this->extraFieldIdNameList['calendar_event'] => $row['external_calendar_itemID'],
1302
                    ];
1303
                }
1304
                $errorFound = false;
1305
            }
1306
1307
            if (empty($eventsToCreate)) {
1308
                $this->logger->addInfo('No events to add');
1309
1310
                return 0;
1311
            }
1312
1313
            $extraFieldValue = new ExtraFieldValue('calendar_event');
1314
            $extraFieldName = $this->extraFieldIdNameList['calendar_event'];
1315
            $externalEventId = null;
1316
1317
            $extraField = new ExtraField('calendar_event');
1318
            $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable($extraFieldName);
1319
1320
            if (empty($extraFieldInfo)) {
1321
                $this->logger->addInfo(
1322
                    "No calendar event extra field created: $extraFieldName"
1323
                );
1324
1325
                return 0;
1326
            }
1327
1328
            $this->logger->addInfo('Ready to insert # '.count($eventsToCreate).' events');
1329
            $batchSize = $this->batchSize;
1330
            $counter = 1;
1331
            $em = Database::getManager();
1332
            $eventStartDateList = [];
1333
            $eventEndDateList = [];
1334
            $report = [
1335
                'mail_sent' => 0,
1336
                'mail_not_sent_announcement_exists' => 0,
1337
                'mail_not_sent_because_date' => 0,
1338
                'mail_not_sent_because_setting' => 0,
1339
            ];
1340
1341
            $eventsToCreateFinal = [];
1342
            foreach ($eventsToCreate as $event) {
1343
                $update = false;
1344
                $item = null;
1345
                if (!isset($event[$extraFieldName])) {
1346
                    $this->logger->addInfo('No external_calendar_itemID found. Skipping ...');
1347
                    continue;
1348
                } else {
1349
                    $externalEventId = $event[$extraFieldName];
1350
                    if (empty($externalEventId)) {
1351
                        $this->logger->addInfo('external_calendar_itemID was set but empty. Skipping ...');
1352
                        continue;
1353
                    }
1354
1355
                    $item = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
1356
                        $extraFieldName,
1357
                        $externalEventId,
1358
                        false,
1359
                        false,
1360
                        false
1361
                    );
1362
1363
                    if (!empty($item)) {
1364
                        $update = true;
1365
                    }
1366
                }
1367
1368
                $courseInfo = api_get_course_info_by_id($event['course_id']);
1369
                $event['course_info'] = $courseInfo;
1370
                $event['update'] = $update;
1371
                $event['item'] = $item;
1372
1373
                $calendarEvent = null;
1374
                /* Check if event changed of course code */
1375
                if (!empty($item) && isset($item['item_id']) && !empty($item['item_id'])) {
1376
                    /** @var CCalendarEvent $calendarEvent */
1377
                    $calendarEvent = $em->getRepository('ChamiloCourseBundle:CCalendarEvent')->find($item['item_id']);
1378
                }
1379
1380
                if ($calendarEvent) {
1381
                    $this->logger->addInfo('Calendar event found '.$item['item_id']);
1382
                    if ($calendarEvent->getCId() != $courseInfo['real_id']) {
1383
                        $this->logger->addInfo('Move from course #'.$calendarEvent->getCId().' to #'.$courseInfo['real_id']);
1384
                        // Seems that the course id changed in the csv
1385
                        $calendarEvent->setCId($courseInfo['real_id']);
1386
                        $em->persist($calendarEvent);
1387
                        $em->flush();
1388
1389
                        $criteria = [
1390
                            'tool' => 'calendar_event',
1391
                            'ref' => $item['item_id'],
1392
                        ];
1393
                        /** @var CItemProperty $itemProperty */
1394
                        $itemProperty = $em->getRepository('ChamiloCourseBundle:CItemProperty')->findOneBy($criteria);
1395
                        $courseEntity = $em->getRepository('ChamiloCoreBundle:Course')->find($courseInfo['real_id']);
1396
                        if ($itemProperty && $courseEntity) {
1397
                            $itemProperty->setCourse($courseEntity);
1398
                            $em->persist($itemProperty);
1399
                            $em->flush();
1400
                        }
1401
                    }
1402
1403
                    // Checking if session still exists
1404
                    $calendarSessionId = (int) $calendarEvent->getSessionId();
1405
                    if (!empty($calendarSessionId)) {
1406
                        $calendarSessionInfo = api_get_session_info($calendarSessionId);
1407
                        if (empty($calendarSessionInfo)) {
1408
                            $calendarId = (int) $calendarEvent->getIid();
1409
1410
                            // Delete calendar events because the session was deleted!
1411
                            $this->logger->addInfo(
1412
                                "Delete event # $calendarId because session # $calendarSessionId doesn't exist"
1413
                            );
1414
1415
                            $sql = "DELETE FROM c_calendar_event
1416
                                    WHERE iid = $calendarId AND session_id = $calendarSessionId";
1417
                            Database::query($sql);
1418
                            $this->logger->addInfo($sql);
1419
1420
                            $sql = "DELETE FROM c_item_property
1421
                                    WHERE
1422
                                        tool = 'calendar_event' AND
1423
                                        ref = $calendarSessionId AND
1424
                                        session_id = $calendarSessionId";
1425
                            Database::query($sql);
1426
                            $this->logger->addInfo($sql);
1427
                        }
1428
                    }
1429
                } else {
1430
                    $this->logger->addInfo('Calendar event not found '.$item['item_id']);
1431
                }
1432
1433
                $event['external_event_id'] = $externalEventId;
1434
                if (isset($eventStartDateList[$courseInfo['real_id']]) &&
1435
                    isset($eventStartDateList[$courseInfo['real_id']][$event['session_id']])
1436
                ) {
1437
                    $currentItemDate = api_strtotime($event['start']);
1438
                    $firstDate = $eventStartDateList[$courseInfo['real_id']][$event['session_id']];
1439
                    if ($currentItemDate < api_strtotime($firstDate)) {
1440
                        $eventStartDateList[$courseInfo['real_id']][$event['session_id']] = $event['start'];
1441
                        $eventEndDateList[$courseInfo['real_id']][$event['session_id']] = $event['end'];
1442
                    }
1443
                } else {
1444
                    // First time
1445
                    $eventStartDateList[$courseInfo['real_id']][$event['session_id']] = $event['start'];
1446
                    $eventEndDateList[$courseInfo['real_id']][$event['session_id']] = $event['end'];
1447
                }
1448
                $eventsToCreateFinal[] = $event;
1449
            }
1450
1451
            $eventAlreadySent = [];
1452
1453
            $tpl = new Template(null, false, false, false, false, false, false);
1454
1455
            foreach ($eventsToCreateFinal as $event) {
1456
                $courseInfo = $event['course_info'];
1457
                $item = $event['item'];
1458
                $update = $event['update'];
1459
                $externalEventId = $event['external_event_id'];
1460
                $info = 'Course: '.$courseInfo['real_id'].' ('.$courseInfo['code'].') - Session: '.$event['session_id'].' external event id: '.$externalEventId;
1461
1462
                $agenda = new Agenda(
1463
                    'course',
1464
                    $event['sender_id'],
1465
                    $courseInfo['real_id'],
1466
                    $event['session_id']
1467
                );
1468
                $agenda->set_course($courseInfo);
1469
                $agenda->setSessionId($event['session_id']);
1470
                $agenda->setSenderId($event['sender_id']);
1471
                $agenda->setIsAllowedToEdit(true);
1472
                $eventComment = $event['comment'];
1473
                $color = $event['color'];
1474
1475
                // To use the event comment you need
1476
                // ALTER TABLE c_calendar_event ADD COLUMN comment TEXT;
1477
                // add in configuration.php allow_agenda_event_comment = true
1478
                if (empty($courseInfo)) {
1479
                    $this->logger->addInfo(
1480
                        "No course found for event #$externalEventId Course #".$event['course_id']." Skipping ..."
1481
                    );
1482
                    continue;
1483
                }
1484
1485
                if (empty($event['sender_id'])) {
1486
                    $this->logger->addInfo(
1487
                        "No sender found for event #$externalEventId Send #".$event['sender_id']." Skipping ..."
1488
                    );
1489
                    continue;
1490
                }
1491
1492
                // Taking first element of course-session event
1493
                $alreadyAdded = false;
1494
                $firstDate = $eventStartDateList[$courseInfo['real_id']][$event['session_id']];
1495
                $firstEndDate = $eventEndDateList[$courseInfo['real_id']][$event['session_id']];
1496
1497
                if (isset($eventAlreadySent[$courseInfo['real_id']]) &&
1498
                    isset($eventAlreadySent[$courseInfo['real_id']][$event['session_id']])
1499
                ) {
1500
                    $alreadyAdded = true;
1501
                } else {
1502
                    $eventAlreadySent[$courseInfo['real_id']][$event['session_id']] = true;
1503
                }
1504
1505
                // Working days (Mon-Fri) see BT#12156#note-16
1506
                $days = 3;
1507
                $startDatePlusDays = api_strtotime("$days weekdays");
1508
1509
                /*
1510
                $timePart = date('H:i:s', api_strtotime('now'));
1511
                $datePart = date('Y-m-d', api_strtotime("$days weekdays"));
1512
                $startDatePlusDays = "$timePart $datePart";
1513
                */
1514
                $this->logger->addInfo(
1515
                    'startDatePlusDays: '.api_get_utc_datetime($startDatePlusDays).' - First date: '.$firstDate
1516
                );
1517
1518
                // Send.
1519
                $sendMail = false;
1520
                if ($startDatePlusDays > api_strtotime($firstDate)) {
1521
                    $sendMail = true;
1522
                }
1523
1524
                $allowAnnouncementSendEmail = false;
1525
                if ($event['send_announcement']) {
1526
                    $allowAnnouncementSendEmail = true;
1527
                }
1528
1529
                // Send announcement to users
1530
                if ($allowAnnouncementSendEmail) {
1531
                    if ($sendMail && $alreadyAdded == false) {
1532
                        $start = $firstDate;
1533
                        $end = $firstEndDate;
1534
1535
                        if (!empty($end) &&
1536
                            api_format_date($start, DATE_FORMAT_LONG) ==
1537
                            api_format_date($end, DATE_FORMAT_LONG)
1538
                        ) {
1539
                            $date = api_format_date($start, DATE_FORMAT_LONG).' ('.
1540
                                api_format_date($start, TIME_NO_SEC_FORMAT).' '.
1541
                                api_format_date($end, TIME_NO_SEC_FORMAT).')';
1542
                        } else {
1543
                            $date = api_format_date($start, DATE_TIME_FORMAT_LONG_24H).' - '.
1544
                                api_format_date($end, DATE_TIME_FORMAT_LONG_24H);
1545
                        }
1546
1547
                        $sessionName = '';
1548
                        $sessionId = isset($event['session_id']) && !empty($event['session_id']) ? $event['session_id'] : 0;
1549
                        if (!empty($sessionId)) {
1550
                            $sessionName = api_get_session_name($sessionId);
1551
                        }
1552
1553
                        $courseTitle = $courseInfo['title'];
1554
1555
                        // Get the value of the "careerid" extra field of this
1556
                        // session
1557
                        $sessionExtraFieldValue = new ExtraFieldValue('session');
1558
                        $externalCareerIdList = $sessionExtraFieldValue->get_values_by_handler_and_field_variable(
1559
                            $event['session_id'],
1560
                            'careerid'
1561
                        );
1562
                        $externalCareerIdList = $externalCareerIdList['value'];
1563
                        if (substr($externalCareerIdList, 0, 1) === '[') {
1564
                            $externalCareerIdList = substr($externalCareerIdList, 1, -1);
1565
                            $externalCareerIds = preg_split('/,/', $externalCareerIdList);
1566
                        } else {
1567
                            $externalCareerIds = [$externalCareerIdList];
1568
                        }
1569
1570
                        $careerExtraFieldValue = new ExtraFieldValue('career');
1571
                        $career = new Career();
1572
                        $careerName = '';
1573
1574
                        // Concat the names of each career linked to this session
1575
                        foreach ($externalCareerIds as $externalCareerId) {
1576
                            // Using the external_career_id field (from above),
1577
                            // find the career ID
1578
                            $careerValue = $careerExtraFieldValue->get_item_id_from_field_variable_and_field_value(
1579
                                'external_career_id',
1580
                                $externalCareerId
1581
                            );
1582
                            $career = $career->find($careerValue['item_id']);
1583
                            $careerName .= $career['name'].', ';
1584
                        }
1585
                        // Remove trailing comma
1586
                        $careerName = substr($careerName, 0, -2);
1587
                        $subject = sprintf(
1588
                            get_lang('WelcomeToPortalXInCourseSessionX'),
1589
                            api_get_setting('Institution'),
1590
                            $courseInfo['title']
1591
                        );
1592
1593
                        $tpl->assign('course_title', $courseTitle);
1594
                        $tpl->assign('career_name', $careerName);
1595
                        $tpl->assign('first_lesson', $date);
1596
                        $tpl->assign('location', $eventComment);
1597
                        $tpl->assign('session_name', $sessionName);
1598
1599
                        if (empty($sessionId)) {
1600
                            $teachersToString = CourseManager::getTeacherListFromCourseCodeToString(
1601
                                $courseInfo['code'],
1602
                                ','
1603
                            );
1604
                        } else {
1605
                            $teachersToString = SessionManager::getCoachesByCourseSessionToString(
1606
                                $sessionId,
1607
                                $courseInfo['real_id'],
1608
                                ','
1609
                            );
1610
                        }
1611
1612
                        $tpl->assign('teachers', $teachersToString);
1613
1614
                        $templateName = $this->getCustomMailTemplate();
1615
                        $emailBody = $tpl->fetch($templateName);
1616
1617
                        $coaches = SessionManager::getCoachesByCourseSession(
1618
                            $event['session_id'],
1619
                            $courseInfo['real_id']
1620
                        );
1621
1622
                        // Search if an announcement exists:
1623
                        $announcementsWithTitleList = AnnouncementManager::getAnnouncementsByTitle(
1624
                            $subject,
1625
                            $courseInfo['real_id'],
1626
                            $event['session_id'],
1627
                            1
1628
                        );
1629
1630
                        if (count($announcementsWithTitleList) === 0) {
1631
                            $this->logger->addInfo(
1632
                                'Mail to be sent because start date: '.$event['start'].' and no announcement found.'
1633
                            );
1634
1635
                            $senderId = $this->defaultAdminId;
1636
                            if (!empty($coaches) && isset($coaches[0]) && !empty($coaches[0])) {
1637
                                $senderId = $coaches[0];
1638
                            }
1639
1640
                            $announcementId = AnnouncementManager::add_announcement(
1641
                                $courseInfo,
1642
                                $event['session_id'],
1643
                                $subject,
1644
                                $emailBody,
1645
                                [
1646
                                    'everyone',
1647
                                    'users' => $coaches,
1648
                                ],
1649
                                [],
1650
                                null,
1651
                                null,
1652
                                false,
1653
                                $senderId
1654
                            );
1655
1656
                            if ($announcementId) {
1657
                                $this->logger->addInfo("Announcement added: $announcementId in $info");
1658
                                $this->logger->addInfo("<<--SENDING MAIL Sender id: $senderId-->>");
1659
                                $report['mail_sent']++;
1660
                                AnnouncementManager::sendEmail(
1661
                                    $courseInfo,
1662
                                    $event['session_id'],
1663
                                    $announcementId,
1664
                                    false,
1665
                                    false,
1666
                                    $this->logger,
1667
                                    $senderId,
1668
                                    true
1669
                                );
1670
                            } else {
1671
                                $this->logger->addError(
1672
                                    "Error when trying to add announcement with title $subject here: $info and SenderId = $senderId"
1673
                                );
1674
                            }
1675
                        } else {
1676
                            $report['mail_not_sent_announcement_exists']++;
1677
                            $this->logger->addInfo(
1678
                                "Mail NOT sent. An announcement seems to be already saved in '$info'"
1679
                            );
1680
                        }
1681
                    } else {
1682
                        $this->logger->addInfo(
1683
                            "Send Mail: ".intval($sendMail).' - Already added: '.intval($alreadyAdded)
1684
                        );
1685
                        if ($sendMail == false) {
1686
                            $report['mail_not_sent_because_date']++;
1687
                        }
1688
                    }
1689
                } else {
1690
                    $this->logger->addInfo("Announcement not sent because config 'sendmail' in CSV");
1691
                    $report['mail_not_sent_because_setting']++;
1692
                }
1693
1694
                $content = '';
1695
                if ($update && isset($item['item_id'])) {
1696
                    $eventInfo = $agenda->get_event($item['item_id']);
1697
                    if (empty($eventInfo)) {
1698
                        // Means that agenda external id exists but the event doesn't exist
1699
                        $this->logger->addInfo("external event id exists: $externalEventId");
1700
                        $this->logger->addInfo("but Chamilo event doesn't exists: ".$item['item_id']);
1701
1702
                        $eventId = $agenda->addEvent(
1703
                            $event['start'],
1704
                            $event['end'],
1705
                            false,
1706
                            $event['title'],
1707
                            $content,
1708
                            ['everyone'], // $usersToSend
1709
                            false, //$addAsAnnouncement = false
1710
                            null, //  $parentEventId
1711
                            [], //$attachmentArray = array(),
1712
                            [], //$attachmentCommentList
1713
                            $eventComment,
1714
                            $color
1715
                        );
1716
1717
                        if (!empty($eventId)) {
1718
                            $this->logger->addInfo("Chamilo event created: ".$eventId);
1719
                            $extraFieldValueItem = $extraFieldValue->get_values_by_handler_and_field_id(
1720
                                $item['item_id'],
1721
                                $extraFieldInfo['id']
1722
                            );
1723
1724
                            if (!empty($extraFieldValueItem) && isset($extraFieldValueItem['id'])) {
1725
                                $params = [
1726
                                    'id' => $extraFieldValueItem['id'],
1727
                                    'item_id' => $eventId,
1728
                                ];
1729
                                $extraFieldValue->update($params);
1730
                                $this->logger->addInfo(
1731
                                    'Updating calendar extra field #'.$extraFieldValueItem['id'].'
1732
                                    new item_id: '.$eventId.' old item_id: '.$item['item_id']
1733
                                );
1734
                            }
1735
                        } else {
1736
                            $this->logger->addInfo("Error while creating event external id: $externalEventId");
1737
                        }
1738
                    } else {
1739
                        // The event already exists, just update
1740
                        $eventResult = $agenda->editEvent(
1741
                            $item['item_id'],
1742
                            $event['start'],
1743
                            $event['end'],
1744
                            false,
1745
                            $event['title'],
1746
                            $content,
1747
                            ['everyone'], // $usersToSend
1748
                            [], //$attachmentArray = array(),
1749
                            [], //$attachmentCommentList
1750
                            $eventComment,
1751
                            $color,
1752
                            false,
1753
                            false,
1754
                            $this->defaultAdminId
1755
                        );
1756
1757
                        if ($eventResult !== false) {
1758
                            $this->logger->addInfo(
1759
                                "Event updated #".$item['item_id']." External cal Id: (".$externalEventId.") $info"
1760
                            );
1761
                        } else {
1762
                            $this->logger->addInfo(
1763
                                "Error while updating event with external id: $externalEventId"
1764
                            );
1765
                        }
1766
                    }
1767
                } else {
1768
                    // New event. Create it.
1769
                    $eventId = $agenda->addEvent(
1770
                        $event['start'],
1771
                        $event['end'],
1772
                        false,
1773
                        $event['title'],
1774
                        $content,
1775
                        ['everyone'], // $usersToSend
1776
                        false, //$addAsAnnouncement = false
1777
                        null, //  $parentEventId
1778
                        [], //$attachmentArray = array(),
1779
                        [], //$attachmentCommentList
1780
                        $eventComment,
1781
                        $color
1782
                    );
1783
1784
                    if (!empty($eventId)) {
1785
                        $extraFieldValue->save(
1786
                            [
1787
                                'value' => $externalEventId,
1788
                                'field_id' => $extraFieldInfo['id'],
1789
                                'item_id' => $eventId,
1790
                            ]
1791
                        );
1792
                        $this->logger->addInfo(
1793
                            "Event added: #$eventId External cal id: (".$externalEventId.") $info"
1794
                        );
1795
                    } else {
1796
                        $this->logger->addInfo(
1797
                            "Error while creating event external id: $externalEventId"
1798
                        );
1799
                    }
1800
                }
1801
1802
                if (($counter % $batchSize) === 0) {
1803
                    $em->flush();
1804
                    $em->clear(); // Detaches all objects from Doctrine!
1805
                }
1806
                $counter++;
1807
            }
1808
1809
            $em->clear(); // Detaches all objects from Doctrine!
1810
            $this->logger->addInfo('------Summary------');
1811
            foreach ($report as $title => $count) {
1812
                $this->logger->addInfo("$title: $count");
1813
            }
1814
            $this->logger->addInfo('------End Summary------');
1815
        }
1816
1817
        if ($moveFile) {
1818
            $this->moveFile($file);
1819
        }
1820
    }
1821
1822
    private function importSkillset(
1823
        $file,
1824
        $moveFile = true
1825
    ) {
1826
        $this->fixCSVFile($file);
1827
        $data = Import::csvToArray($file);
1828
        if (!empty($data)) {
1829
            $this->logger->addInfo(count($data).' records found.');
1830
            $extraFieldValues = new ExtraFieldValue('skill');
1831
            $em = Database::getManager();
1832
            $repo = $em->getRepository(\Chamilo\CoreBundle\Entity\Skill::class);
1833
            $skillSetList = [];
1834
            $urlId = api_get_current_access_url_id();
1835
1836
            foreach ($data as $row) {
1837
                $skill = $repo->findOneBy(['shortCode' => $row['Code']]);
1838
                $new = false;
1839
                if ($skill === null) {
1840
                    $new = true;
1841
                    $skill = new \Chamilo\CoreBundle\Entity\Skill();
1842
                    $skill
1843
                        ->setShortCode($row['Code'])
1844
                        ->setDescription('')
1845
                        ->setAccessUrlId($urlId)
1846
                        ->setIcon('')
1847
                        ->setStatus(1)
1848
                    ;
1849
                }
1850
1851
                $skill
1852
                    ->setName($row['Tekst'])
1853
                    ->setUpdatedAt(new DateTime())
1854
                ;
1855
                $em->persist($skill);
1856
                $em->flush();
1857
1858
                if ($new) {
1859
                    $skillRelSkill = (new \Chamilo\CoreBundle\Entity\SkillRelSkill())
1860
                        ->setRelationType(0)
1861
                        ->setParentId(0)
1862
                        ->setLevel(0)
1863
                        ->setSkillId($skill->getId())
1864
                    ;
1865
                    $em->persist($skillRelSkill);
1866
                    $em->flush();
1867
                }
1868
1869
                /*
1870
                $params = [
1871
                    'item_id' => $skill->getId(),
1872
                    'variable' => 'skillset',
1873
                    'value' => $row['SkillsetID'],
1874
                ];
1875
                $extraFieldValues->save($params);*/
1876
                $skillSetList[$row['SkillsetID']][] = $skill->getId();
1877
            }
1878
1879
            //$courseRelSkills = [];
1880
            foreach ($skillSetList as $skillSetId => $skillList) {
1881
                $skillList = array_unique($skillList);
1882
                if (empty($skillList)) {
1883
                    continue;
1884
                }
1885
1886
                $sql = "SELECT id FROM course WHERE code LIKE '%$skillSetId' ";
1887
                $result = Database::query($sql);
1888
                while ($row = Database::fetch_array($result, 'ASSOC')) {
1889
                    $courseId = $row['id'];
1890
                    //$courseRelSkills[$courseId] = $skillList;
1891
                    Skill::saveSkillsToCourse($skillList, $courseId, null);
1892
                }
1893
            }
1894
        }
1895
    }
1896
1897
    /**
1898
     * @param string $file
1899
     * @param bool   $moveFile
1900
     * @param array  $teacherBackup
1901
     * @param array  $groupBackup
1902
     */
1903
    private function importCourses(
1904
        $file,
1905
        $moveFile = true,
1906
        &$teacherBackup = [],
1907
        &$groupBackup = []
1908
    ) {
1909
        $this->fixCSVFile($file);
1910
        $data = Import::csvToArray($file);
1911
1912
        if (!empty($data)) {
1913
            $this->logger->addInfo(count($data)." records found.");
1914
1915
            foreach ($data as $row) {
1916
                $row = $this->cleanCourseRow($row);
1917
                $courseId = CourseManager::get_course_id_from_original_id(
1918
                    $row['extra_'.$this->extraFieldIdNameList['course']],
1919
                    $this->extraFieldIdNameList['course']
1920
                );
1921
1922
                $courseInfo = api_get_course_info_by_id($courseId);
1923
1924
                if (empty($courseInfo)) {
1925
                    // Create
1926
                    $params = [];
1927
                    $params['title'] = $row['title'];
1928
                    $params['exemplary_content'] = false;
1929
                    $params['wanted_code'] = $row['course_code'];
1930
                    $params['course_category'] = $row['course_category'];
1931
                    $params['course_language'] = $row['language'];
1932
                    $params['teachers'] = $row['teachers'];
1933
                    $params['visibility'] = $row['visibility'];
1934
1935
                    $courseInfo = CourseManager::create_course(
1936
                        $params,
1937
                        $this->defaultAdminId
1938
                    );
1939
1940
                    if (!empty($courseInfo)) {
1941
                        CourseManager::update_course_extra_field_value(
1942
                            $courseInfo['code'],
1943
                            'external_course_id',
1944
                            $row['extra_'.$this->extraFieldIdNameList['course']]
1945
                        );
1946
1947
                        CourseManager::update_course_extra_field_value(
1948
                            $courseInfo['code'],
1949
                            'skillset',
1950
                            $row['extra_courseskillset']
1951
                        );
1952
1953
                        $this->logger->addInfo("Courses - Course created ".$courseInfo['code']);
1954
                    } else {
1955
                        $this->logger->addError("Courses - Can't create course:".$row['title']);
1956
                    }
1957
                } else {
1958
                    // Update
1959
                    $params = [
1960
                        'title' => $row['title'],
1961
                        'category_code' => $row['course_category'],
1962
                        'visibility' => $row['visibility'],
1963
                    ];
1964
1965
                    $result = CourseManager::update_attributes(
1966
                        $courseInfo['real_id'],
1967
                        $params
1968
                    );
1969
1970
                    $addTeacherToSession = isset($courseInfo['add_teachers_to_sessions_courses']) && !empty($courseInfo['add_teachers_to_sessions_courses']) ? true : false;
1971
1972
                    $teachers = $row['teachers'];
1973
                    if (!is_array($teachers)) {
1974
                        $teachers = [$teachers];
1975
                    }
1976
1977
                    if ($addTeacherToSession) {
1978
                        $this->logger->addInfo("Add teacher to all course sessions");
1979
                        CourseManager::updateTeachers(
1980
                            $courseInfo,
1981
                            $row['teachers'],
1982
                            false,
1983
                            true,
1984
                            false,
1985
                            $teacherBackup,
1986
                            $this->logger
1987
                        );
1988
                    } else {
1989
                        CourseManager::updateTeachers(
1990
                            $courseInfo,
1991
                            $row['teachers'],
1992
                            true,
1993
                            false,
1994
                            false,
1995
                            $teacherBackup,
1996
                            $this->logger
1997
                        );
1998
                    }
1999
2000
                    CourseManager::update_course_extra_field_value(
2001
                        $courseInfo['code'],
2002
                        'skillset',
2003
                        $row['extra_courseskillset']
2004
                    );
2005
2006
                    foreach ($teachers as $teacherId) {
2007
                        if (isset($groupBackup['tutor'][$teacherId]) &&
2008
                            isset($groupBackup['tutor'][$teacherId][$courseInfo['code']])
2009
                        ) {
2010
                            foreach ($groupBackup['tutor'][$teacherId][$courseInfo['code']] as $data) {
2011
                                $groupInfo = GroupManager::get_group_properties($data['group_id']);
2012
                                GroupManager::subscribe_tutors(
2013
                                    [$teacherId],
2014
                                    $groupInfo,
2015
                                    $data['c_id']
2016
                                );
2017
                            }
2018
                        }
2019
2020
                        if (isset($groupBackup['user'][$teacherId]) &&
2021
                            isset($groupBackup['user'][$teacherId][$courseInfo['code']]) &&
2022
                            !empty($groupBackup['user'][$teacherId][$courseInfo['code']])
2023
                        ) {
2024
                            foreach ($groupBackup['user'][$teacherId][$courseInfo['code']] as $data) {
2025
                                $groupInfo = GroupManager::get_group_properties($data['group_id']);
2026
                                GroupManager::subscribe_users(
2027
                                    [$teacherId],
2028
                                    $groupInfo,
2029
                                    $data['c_id']
2030
                                );
2031
                            }
2032
                        }
2033
                    }
2034
2035
                    if ($result) {
2036
                        $this->logger->addInfo("Courses - Course updated ".$courseInfo['code']);
2037
                    } else {
2038
                        $this->logger->addError("Courses - Course NOT updated ".$courseInfo['code']);
2039
                    }
2040
                }
2041
            }
2042
        }
2043
2044
        if ($moveFile) {
2045
            $this->moveFile($file);
2046
        }
2047
    }
2048
2049
    /**
2050
     * Parse filename: encora_subsessionsextid-static_31082016.csv.
2051
     *
2052
     * @param string $file
2053
     */
2054
    private function importSubscribeUserToCourseSessionExtStatic($file, $moveFile = true)
2055
    {
2056
        $data = Import::csv_reader($file);
2057
        if (!empty($data)) {
2058
            $this->logger->addInfo(count($data)." records found.");
2059
            $userIdList = [];
2060
            foreach ($data as $row) {
2061
                $chamiloUserName = $row['UserName'];
2062
                $chamiloCourseCode = $row['CourseCode'];
2063
                $externalSessionId = $row['ExtSessionID'];
2064
                $status = $row['Status'];
2065
2066
                $chamiloSessionId = null;
2067
                if (!empty($externalSessionId)) {
2068
                    $chamiloSessionId = SessionManager::getSessionIdFromOriginalId(
2069
                        $externalSessionId,
2070
                        $this->extraFieldIdNameList['session']
2071
                    );
2072
                }
2073
2074
                $sessionInfo = api_get_session_info($chamiloSessionId);
2075
2076
                if (empty($sessionInfo)) {
2077
                    $this->logger->addError('Session does not exists: '.$chamiloSessionId);
2078
                    continue;
2079
                }
2080
2081
                $courseInfo = api_get_course_info($chamiloCourseCode);
2082
                if (empty($courseInfo)) {
2083
                    $this->logger->addError('Course does not exists: '.$courseInfo);
2084
                    continue;
2085
                }
2086
2087
                $userId = UserManager::get_user_id_from_username($chamiloUserName);
2088
2089
                if (empty($userId)) {
2090
                    $this->logger->addError('User does not exists: '.$chamiloUserName);
2091
                    continue;
2092
                }
2093
2094
                switch ($status) {
2095
                    case 'student':
2096
                        SessionManager::subscribe_users_to_session_course(
2097
                            [$userId],
2098
                            $chamiloSessionId,
2099
                            $courseInfo['code']
2100
                        );
2101
                        break;
2102
                    case 'teacher':
2103
                        SessionManager::set_coach_to_course_session(
2104
                            $userId,
2105
                            $chamiloSessionId,
2106
                            $courseInfo['code']
2107
                        );
2108
                        break;
2109
                    case 'drh':
2110
                        $removeAllSessionsFromUser = true;
2111
                        if (in_array($userId, $userIdList)) {
2112
                            $removeAllSessionsFromUser = false;
2113
                        } else {
2114
                            $userIdList[] = $userId;
2115
                        }
2116
2117
                        $userInfo = api_get_user_info($userId);
2118
                        SessionManager::subscribeSessionsToDrh(
2119
                            $userInfo,
2120
                            [$chamiloSessionId],
2121
                            false,
2122
                            $removeAllSessionsFromUser
2123
                        );
2124
                        break;
2125
                }
2126
2127
                $this->logger->addError(
2128
                    "User '$chamiloUserName' was added as '$status' to Session: #$chamiloSessionId - Course: ".$courseInfo['code']
2129
                );
2130
            }
2131
        }
2132
2133
        if ($moveFile) {
2134
            $this->moveFile($file);
2135
        }
2136
    }
2137
2138
    /**
2139
     * @param $file
2140
     * @param bool $moveFile
2141
     */
2142
    private function importUnsubSessionsExtIdStatic($file, $moveFile = true)
2143
    {
2144
        $data = Import::csv_reader($file);
2145
2146
        if (!empty($data)) {
2147
            $this->logger->addInfo(count($data)." records found.");
2148
            foreach ($data as $row) {
2149
                $chamiloUserName = $row['UserName'];
2150
                $chamiloCourseCode = $row['CourseCode'];
2151
                $externalSessionId = $row['ExtSessionID'];
2152
                $dateStop = $row['DateStop'];
2153
2154
                $chamiloSessionId = null;
2155
                if (!empty($externalSessionId)) {
2156
                    $chamiloSessionId = SessionManager::getSessionIdFromOriginalId(
2157
                        $externalSessionId,
2158
                        $this->extraFieldIdNameList['session']
2159
                    );
2160
                }
2161
2162
                $sessionInfo = api_get_session_info($chamiloSessionId);
2163
2164
                if (empty($sessionInfo)) {
2165
                    $this->logger->addError('Session does not exists: '.$chamiloSessionId);
2166
                    continue;
2167
                }
2168
2169
                $courseInfo = api_get_course_info($chamiloCourseCode);
2170
                if (empty($courseInfo)) {
2171
                    $this->logger->addError('Course does not exists: '.$courseInfo);
2172
                    continue;
2173
                }
2174
2175
                $userId = UserManager::get_user_id_from_username($chamiloUserName);
2176
2177
                if (empty($userId)) {
2178
                    $this->logger->addError('User does not exists: '.$chamiloUserName);
2179
                    continue;
2180
                }
2181
2182
                SessionManager::removeUsersFromCourseSession(
2183
                    [$userId],
2184
                    $chamiloSessionId,
2185
                    $courseInfo
2186
                );
2187
2188
                $this->logger->addError(
2189
                    "User '$chamiloUserName' was remove from Session: #$chamiloSessionId - Course: ".$courseInfo['code']
2190
                );
2191
            }
2192
        }
2193
2194
        if ($moveFile) {
2195
            $this->moveFile($file);
2196
        }
2197
    }
2198
2199
    /**
2200
     * @param string $file
2201
     */
2202
    private function importSessionsExtIdStatic($file, $moveFile = true)
2203
    {
2204
        $data = Import::csv_reader($file);
2205
2206
        if (!empty($data)) {
2207
            $this->logger->addInfo(count($data)." records found.");
2208
            foreach ($data as $row) {
2209
                $chamiloUserName = $row['UserName'];
2210
                $chamiloCourseCode = $row['CourseCode'];
2211
                $externalSessionId = $row['ExtSessionID'];
2212
                $type = $row['Type'];
2213
2214
                $chamiloSessionId = null;
2215
                if (!empty($externalSessionId)) {
2216
                    $chamiloSessionId = SessionManager::getSessionIdFromOriginalId(
2217
                        $externalSessionId,
2218
                        $this->extraFieldIdNameList['session']
2219
                    );
2220
                }
2221
2222
                $sessionInfo = api_get_session_info($chamiloSessionId);
2223
2224
                if (empty($sessionInfo)) {
2225
                    $this->logger->addError('Session does not exists: '.$chamiloSessionId);
2226
                    continue;
2227
                }
2228
2229
                $courseInfo = api_get_course_info($chamiloCourseCode);
2230
                if (empty($courseInfo)) {
2231
                    $this->logger->addError('Course does not exists: '.$courseInfo);
2232
                    continue;
2233
                }
2234
2235
                $userId = UserManager::get_user_id_from_username($chamiloUserName);
2236
2237
                if (empty($userId)) {
2238
                    $this->logger->addError('User does not exists: '.$chamiloUserName);
2239
                    continue;
2240
                }
2241
                switch ($type) {
2242
                    case 'student':
2243
                        SessionManager::subscribe_users_to_session_course(
2244
                            [$userId],
2245
                            $chamiloSessionId,
2246
                            $courseInfo['code'],
2247
                            null,
2248
                            false
2249
                        );
2250
                        break;
2251
                    case 'teacher':
2252
                        SessionManager::set_coach_to_course_session(
2253
                            $userId,
2254
                            $chamiloSessionId,
2255
                            $courseInfo['code']
2256
                        );
2257
                        break;
2258
                }
2259
2260
                $this->logger->addError(
2261
                    "User '$chamiloUserName' with status $type was added to session: #$chamiloSessionId - Course: ".$courseInfo['code']
2262
                );
2263
            }
2264
        }
2265
2266
        if ($moveFile) {
2267
            $this->moveFile($file);
2268
        }
2269
    }
2270
2271
    /**
2272
     * Updates the session synchronize with the csv file.
2273
     *
2274
     * @param bool   $moveFile
2275
     * @param string $file
2276
     */
2277
    private function importSessionsStatic($file, $moveFile = true)
2278
    {
2279
        $content = file($file);
2280
        $sessions = [];
2281
        $tag_names = [];
2282
2283
        foreach ($content as $key => $enreg) {
2284
            $enreg = explode(';', trim($enreg));
2285
            if ($key) {
2286
                foreach ($tag_names as $tag_key => $tag_name) {
2287
                    if (isset($enreg[$tag_key])) {
2288
                        $sessions[$key - 1][$tag_name] = $enreg[$tag_key];
2289
                    }
2290
                }
2291
            } else {
2292
                foreach ($enreg as $tag_name) {
2293
                    $tag_names[] = api_preg_replace(
2294
                        '/[^a-zA-Z0-9_\-]/',
2295
                        '',
2296
                        $tag_name
2297
                    );
2298
                }
2299
                if (!in_array('SessionName', $tag_names) ||
2300
                    !in_array('DateStart', $tag_names) || !in_array('DateEnd', $tag_names)
2301
                ) {
2302
                    $error_message = get_lang('NoNeededData');
2303
                    break;
2304
                }
2305
            }
2306
        }
2307
2308
        if (!empty($sessions)) {
2309
            // Looping the sessions.
2310
            foreach ($sessions as $session) {
2311
                if (!empty($session['SessionID'])) {
2312
                    $sessionId = SessionManager::getSessionIdFromOriginalId(
2313
                        $session['SessionID'],
2314
                        $this->extraFieldIdNameList['session']
2315
                    );
2316
2317
                    $coachUserName = isset($session['Coach']) ? $session['Coach'] : null;
2318
                    $categoryId = isset($session['category_id']) ? $session['category_id'] : null;
2319
2320
                    // 2014-06-30
2321
                    $dateStart = explode('/', $session['DateStart']);
2322
                    $dateEnd = explode('/', $session['DateEnd']);
2323
                    $visibility = $this->defaultSessionVisibility;
2324
2325
                    $coachId = null;
2326
                    if (!empty($coachUserName)) {
2327
                        $coachInfo = api_get_user_info_from_username($coachUserName);
2328
                        $coachId = $coachInfo['user_id'];
2329
                    }
2330
2331
                    $dateStart = $dateStart[0].'-'.$dateStart[1].'-'.$dateStart[2].' 00:00:00';
2332
                    $dateEnd = $dateEnd[0].'-'.$dateEnd[1].'-'.$dateEnd[2].' 23:59:59';
2333
2334
                    $date = new \DateTime($dateStart);
2335
                    $interval = new DateInterval('P'.$this->daysCoachAccessBeforeBeginning.'D');
2336
                    $date->sub($interval);
2337
                    $coachBefore = $date->format('Y-m-d h:i');
2338
2339
                    $date = new \DateTime($dateEnd);
2340
                    $interval = new DateInterval('P'.$this->daysCoachAccessAfterBeginning.'D');
2341
                    $date->add($interval);
2342
                    $coachAfter = $date->format('Y-m-d h:i');
2343
2344
                    /*$dateStart = api_get_utc_datetime($dateStart);
2345
                    $dateEnd = api_get_utc_datetime($dateEnd);
2346
                    $coachBefore = api_get_utc_datetime($coachBefore);
2347
                    $coachAfter = api_get_utc_datetime($coachAfter);*/
2348
2349
                    if (empty($sessionId)) {
2350
                        $result = SessionManager::create_session(
2351
                            $session['SessionName'],
2352
                            $dateStart,
2353
                            $dateEnd,
2354
                            $dateStart,
2355
                            $dateEnd,
2356
                            $coachBefore,
2357
                            $coachAfter,
2358
                            $coachId,
2359
                            $categoryId,
2360
                            $visibility
2361
                        );
2362
2363
                        if (is_numeric($result)) {
2364
                            $sessionId = $result;
2365
                            $this->logger->addInfo("Session #$sessionId created: ".$session['SessionName']);
2366
                            SessionManager::update_session_extra_field_value(
2367
                                $sessionId,
2368
                                $this->extraFieldIdNameList['session'],
2369
                                $session['SessionID']
2370
                            );
2371
                        } else {
2372
                            $this->logger->addInfo("Failed creating session: ".$session['SessionName']);
2373
                        }
2374
                    } else {
2375
                        $sessionInfo = api_get_session_info($sessionId);
2376
                        $accessBefore = null;
2377
                        $accessAfter = null;
2378
2379
                        if (empty($sessionInfo['nb_days_access_before_beginning']) ||
2380
                            (!empty($sessionInfo['nb_days_access_before_beginning']) &&
2381
                                $sessionInfo['nb_days_access_before_beginning'] < $this->daysCoachAccessBeforeBeginning)
2382
                        ) {
2383
                            $accessBefore = $coachBefore;
2384
                        }
2385
2386
                        $accessAfter = null;
2387
                        if (empty($sessionInfo['nb_days_access_after_end']) ||
2388
                            (!empty($sessionInfo['nb_days_access_after_end']) &&
2389
                                $sessionInfo['nb_days_access_after_end'] < $this->daysCoachAccessAfterBeginning)
2390
                        ) {
2391
                            $accessAfter = $coachAfter;
2392
                        }
2393
2394
                        $showDescription = isset($sessionInfo['show_description']) ? $sessionInfo['show_description'] : 1;
2395
2396
                        $result = SessionManager::edit_session(
2397
                            $sessionId,
2398
                            $session['SessionName'],
2399
                            $dateStart,
2400
                            $dateEnd,
2401
                            $dateStart,
2402
                            $dateEnd,
2403
                            $accessBefore,
2404
                            $accessAfter,
2405
                            $coachId,
2406
                            $categoryId,
2407
                            $visibility,
2408
                            null, //$description = null,
2409
                            $showDescription
2410
                        );
2411
2412
                        if (is_numeric($result)) {
2413
                            $this->logger->addInfo("Session #$sessionId updated: ".$session['SessionName']);
2414
                            $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2415
                            $params = [
2416
                                'description' => $session['SessionDescription'],
2417
                            ];
2418
                            Database::update(
2419
                                $tbl_session,
2420
                                $params,
2421
                                ['id = ?' => $sessionId]
2422
                            );
2423
                        }
2424
                    }
2425
2426
                    if (!empty($sessionId)) {
2427
                        // Courses
2428
                        $courses = explode('|', $session['Courses']);
2429
                        $courseList = [];
2430
                        $courseListWithCoach = [];
2431
                        foreach ($courses as $course) {
2432
                            $courseArray = bracketsToArray($course);
2433
                            $courseCode = $courseArray[0];
2434
                            if (CourseManager::course_exists($courseCode)) {
2435
                                $courseInfo = api_get_course_info($courseCode);
2436
                                $courseList[] = $courseInfo['real_id'];
2437
                                // Extracting course coaches
2438
                                $courseCoaches = isset($courseArray[1]) ? $courseArray[1] : null;
2439
                                $courseCoaches = explode(',', $courseCoaches);
2440
2441
                                // Extracting students
2442
                                $courseUsers = isset($courseArray[2]) ? $courseArray[2] : null;
2443
                                $courseUsers = explode(',', $courseUsers);
2444
2445
                                $courseListWithCoach[] = [
2446
                                    'course_info' => $courseInfo,
2447
                                    'coaches' => $courseCoaches,
2448
                                    'course_users' => $courseUsers,
2449
                                ];
2450
                            }
2451
                        }
2452
2453
                        SessionManager::add_courses_to_session(
2454
                            $sessionId,
2455
                            $courseList,
2456
                            true
2457
                        );
2458
2459
                        $this->logger->addInfo("Session #$sessionId: Courses added: '".implode(', ', $courseList)."'");
2460
2461
                        if (empty($courseListWithCoach)) {
2462
                            $this->logger->addInfo("No users/coaches to update");
2463
                            continue;
2464
                        }
2465
2466
                        foreach ($courseListWithCoach as $courseData) {
2467
                            $courseInfo = $courseData['course_info'];
2468
                            $courseCode = $courseInfo['code'];
2469
                            $courseId = $courseInfo['real_id'];
2470
                            $courseCoaches = $courseData['coaches'];
2471
                            $courseUsers = $courseData['course_users'];
2472
2473
                            // Coaches
2474
                            if (!empty($courseCoaches)) {
2475
                                $coachList = [];
2476
                                foreach ($courseCoaches as $courseCoach) {
2477
                                    $courseCoachId = UserManager::get_user_id_from_username(
2478
                                        $courseCoach
2479
                                    );
2480
                                    if ($courseCoachId !== false) {
2481
                                        // Just insert new coaches
2482
                                        $coachList[] = $courseCoachId;
2483
                                    }
2484
                                }
2485
2486
                                $this->logger->addInfo("Session #$sessionId: course '$courseCode' coaches added: '".implode(', ', $coachList)."'");
2487
2488
                                SessionManager::updateCoaches(
2489
                                    $sessionId,
2490
                                    $courseId,
2491
                                    $coachList,
2492
                                    true
2493
                                );
2494
                            } else {
2495
                                $this->logger->addInfo("No coaches added");
2496
                            }
2497
2498
                            // Students
2499
                            if (!empty($courseUsers)) {
2500
                                $userList = [];
2501
                                foreach ($courseUsers as $username) {
2502
                                    $userInfo = api_get_user_info_from_username(trim($username));
2503
                                    if (!empty($userInfo)) {
2504
                                        $userList[] = $userInfo['user_id'];
2505
                                    }
2506
                                }
2507
2508
                                $this->logger->addInfo("Session #$sessionId: course '$courseCode': Students added '".implode(', ', $userList)."'");
2509
                                SessionManager::subscribe_users_to_session_course(
2510
                                    $userList,
2511
                                    $sessionId,
2512
                                    $courseCode,
2513
                                    SESSION_VISIBLE_READ_ONLY,
2514
                                    true
2515
                                );
2516
                            } else {
2517
                                $this->logger->addInfo("No users to register.");
2518
                            }
2519
                        }
2520
                    } else {
2521
                        $this->logger->addInfo(
2522
                            'SessionID not found in system.'
2523
                        );
2524
                    }
2525
                } else {
2526
                    $this->logger->addInfo('SessionID does not exists');
2527
                }
2528
            }
2529
        } else {
2530
            $this->logger->addInfo($error_message);
2531
        }
2532
2533
        if ($moveFile) {
2534
            $this->moveFile($file);
2535
        }
2536
    }
2537
2538
    /**
2539
     * @param $file
2540
     * @param bool  $moveFile
2541
     * @param array $teacherBackup
2542
     * @param array $groupBackup
2543
     */
2544
    private function importOpenSessions(
2545
        $file,
2546
        $moveFile = true,
2547
        &$teacherBackup = [],
2548
        &$groupBackup = []
2549
    ) {
2550
        $this->importSessions($file, $moveFile, $teacherBackup, $groupBackup);
2551
    }
2552
2553
    private function importSessionsUsersCareers(
2554
        $file,
2555
        $moveFile = false,
2556
        &$teacherBackup = [],
2557
        &$groupBackup = []
2558
    ) {
2559
        $data = Import::csvToArray($file);
2560
        if (!empty($data)) {
2561
            $extraFieldValueCareer = new ExtraFieldValue('career');
2562
            $sessionExtraFieldValue = new ExtraFieldValue('session');
2563
            $career = new Career();
2564
2565
            $this->logger->addInfo(count($data)." records found.");
2566
            foreach ($data as $row) {
2567
                $users = $row['Users'];
2568
                if (empty($users)) {
2569
                    $this->logger->addError('No users found');
2570
                    continue;
2571
                }
2572
2573
                $users = explode('|', $users);
2574
                $careerList = str_replace(['[', ']'], '', $row['extra_careerid']);
2575
                $careerList = explode(',', $careerList);
2576
2577
                $finalCareerIdList = [];
2578
                $careerListValidated = [];
2579
                foreach ($careerList as $careerId) {
2580
                    $realCareerIdList = $extraFieldValueCareer->get_item_id_from_field_variable_and_field_value(
2581
                        'external_career_id',
2582
                        $careerId
2583
                    );
2584
                    if (isset($realCareerIdList['item_id'])) {
2585
                        $careerListValidated[] = $careerId;
2586
                        $finalCareerIdList[] = $realCareerIdList['item_id'];
2587
                    }
2588
                }
2589
2590
                if (empty($finalCareerIdList)) {
2591
                    $this->logger->addError('Careers not found: '.print_r($finalCareerIdList, 1));
2592
                    continue;
2593
                }
2594
2595
                //$chamiloSessionId = $row['SessionID'];
2596
2597
                $chamiloSessionId = SessionManager::getSessionIdFromOriginalId(
2598
                    $row['SessionID'],
2599
                    $this->extraFieldIdNameList['session']
2600
                );
2601
2602
                $sessionInfo = api_get_session_info($chamiloSessionId);
2603
2604
                if (empty($sessionInfo)) {
2605
                    $this->logger->addError('Session does not exists: '.$chamiloSessionId);
2606
                    continue;
2607
                } else {
2608
                    $this->logger->addInfo("Session id: ".$sessionInfo['id']);
2609
                }
2610
2611
                $sessionId = $sessionInfo['id'];
2612
2613
                // Add career to session.
2614
                $externalCareerIdList = $sessionExtraFieldValue->get_values_by_handler_and_field_variable(
2615
                    $sessionId,
2616
                    'careerid'
2617
                );
2618
2619
                if (empty($externalCareerIdList) ||
2620
                    (isset($externalCareerIdList['value']) && empty($externalCareerIdList['value']))
2621
                ) {
2622
                    $careerItem = '['.implode(',', $careerListValidated).']';
2623
                    $params = ['item_id' => $sessionId, 'extra_careerid' => $careerItem];
2624
                    $this->logger->addInfo("Saving career: $careerItem to session: $sessionId");
2625
                    $sessionExtraFieldValue->saveFieldValues($params, true);
2626
                } else {
2627
                    /*foreach ($finalCareerIdList as $careerId) {
2628
                        if (empty($externalCareerIdList)) {
2629
                            $params = ['item_id' => $sessionId, 'extra_careerid' => $careerId];
2630
                            $sessionExtraFieldValue->saveFieldValues($params, true);
2631
                        }
2632
                    }*/
2633
                }
2634
2635
                // Add career to users.
2636
                foreach ($users as $username) {
2637
                    $userInfo = api_get_user_info_from_username($username);
2638
                    if (empty($userInfo)) {
2639
                        $this->logger->addError('username not found: '.$username);
2640
                        continue;
2641
                    }
2642
2643
                    foreach ($finalCareerIdList as $careerId) {
2644
                        $this->logger->addInfo("Adding Career $careerId: To user $username");
2645
                        UserManager::addUserCareer($userInfo['id'], $careerId);
2646
                    }
2647
                }
2648
            }
2649
        }
2650
    }
2651
2652
    /**
2653
     * @param string $file
2654
     * @param bool   $moveFile
2655
     * @param array  $teacherBackup
2656
     * @param array  $groupBackup
2657
     */
2658
    private function importSessions(
2659
        $file,
2660
        $moveFile = true,
2661
        &$teacherBackup = [],
2662
        &$groupBackup = []
2663
    ) {
2664
        $avoid = null;
2665
        if (isset($this->conditions['importSessions']) &&
2666
            isset($this->conditions['importSessions']['update'])
2667
        ) {
2668
            $avoid = $this->conditions['importSessions']['update'];
2669
        }
2670
        $result = SessionManager::importCSV(
2671
            $file,
2672
            true,
2673
            $this->defaultAdminId,
2674
            $this->logger,
2675
            [
2676
                'SessionID' => 'extra_'.$this->extraFieldIdNameList['session'],
2677
                'CareerId' => 'extra_'.$this->extraFieldIdNameList['session_career'],
2678
            ],
2679
            $this->extraFieldIdNameList['session'],
2680
            $this->daysCoachAccessBeforeBeginning,
2681
            $this->daysCoachAccessAfterBeginning,
2682
            $this->defaultSessionVisibility,
2683
            $avoid,
2684
            false, // deleteUsersNotInList
2685
            false, // updateCourseCoaches
2686
            true, // sessionWithCoursesModifier
2687
            true, //$addOriginalCourseTeachersAsCourseSessionCoaches
2688
            false, //$removeAllTeachersFromCourse
2689
            1, // $showDescription,
2690
            $teacherBackup,
2691
            $groupBackup
2692
        );
2693
2694
        if (!empty($result['error_message'])) {
2695
            $this->logger->addError($result['error_message']);
2696
        }
2697
        $this->logger->addInfo("Sessions - Sessions parsed: ".$result['session_counter']);
2698
2699
        if ($moveFile) {
2700
            $this->moveFile($file);
2701
        }
2702
    }
2703
2704
    /**
2705
     * @param string $file
2706
     * @param bool   $moveFile
2707
     */
2708
    private function importSubscribeStatic($file, $moveFile = true)
2709
    {
2710
        $data = Import::csv_reader($file);
2711
2712
        if (!empty($data)) {
2713
            $this->logger->addInfo(count($data)." records found.");
2714
            foreach ($data as $row) {
2715
                $chamiloUserName = $row['UserName'];
2716
                $chamiloCourseCode = $row['CourseCode'];
2717
                $chamiloSessionId = $row['SessionID'];
2718
                $type = $row['Type'];
2719
2720
                $sessionInfo = api_get_session_info($chamiloSessionId);
2721
2722
                if (empty($sessionInfo)) {
2723
                    $this->logger->addError('Session does not exists: '.$chamiloSessionId);
2724
                    continue;
2725
                }
2726
2727
                $courseInfo = api_get_course_info($chamiloCourseCode);
2728
                if (empty($courseInfo)) {
2729
                    $this->logger->addError('Course does not exists: '.$courseInfo);
2730
                    continue;
2731
                }
2732
2733
                $userId = UserManager::get_user_id_from_username($chamiloUserName);
2734
2735
                if (empty($userId)) {
2736
                    $this->logger->addError('User does not exists: '.$chamiloUserName);
2737
                    continue;
2738
                }
2739
2740
                switch ($type) {
2741
                    case 'student':
2742
                        SessionManager::subscribe_users_to_session_course(
2743
                            [$userId],
2744
                            $chamiloSessionId,
2745
                            $courseInfo['code'],
2746
                            null,
2747
                            false
2748
                        );
2749
                        break;
2750
                    case 'teacher':
2751
                        SessionManager::set_coach_to_course_session(
2752
                            $userId,
2753
                            $chamiloSessionId,
2754
                            $courseInfo['real_id']
2755
                        );
2756
                        break;
2757
                }
2758
2759
                $this->logger->addError(
2760
                    "User '$chamiloUserName' with status $type was added to session: #$chamiloSessionId - Course: ".$courseInfo['code']
2761
                );
2762
            }
2763
        }
2764
2765
        if ($moveFile) {
2766
            $this->moveFile($file);
2767
        }
2768
    }
2769
2770
    /**
2771
     * @param $file
2772
     * @param bool $moveFile
2773
     */
2774
    private function importSubscribeUserToCourse($file, $moveFile = false, &$teacherBackup = [])
2775
    {
2776
        $data = Import::csv_reader($file);
2777
2778
        if (!empty($data)) {
2779
            $this->logger->addInfo(count($data)." records found.");
2780
            foreach ($data as $row) {
2781
                $chamiloUserName = $row['UserName'];
2782
                $chamiloCourseCode = $row['CourseCode'];
2783
                $status = $row['Status'];
2784
2785
                $courseInfo = api_get_course_info($chamiloCourseCode);
2786
2787
                if (empty($courseInfo)) {
2788
                    $this->logger->addError(
2789
                        'Course does not exists: '.$chamiloCourseCode
2790
                    );
2791
                    continue;
2792
                }
2793
2794
                $userId = UserManager::get_user_id_from_username(
2795
                    $chamiloUserName
2796
                );
2797
2798
                if (empty($userId)) {
2799
                    $this->logger->addError(
2800
                        'User does not exists: '.$chamiloUserName
2801
                    );
2802
                    continue;
2803
                }
2804
2805
                $userCourseCategory = '';
2806
                if (isset($teacherBackup[$userId]) &&
2807
                    isset($teacherBackup[$userId][$courseInfo['code']])
2808
                ) {
2809
                    $courseUserData = $teacherBackup[$userId][$courseInfo['code']];
2810
                    $userCourseCategory = $courseUserData['user_course_cat'];
2811
                }
2812
2813
                $result = CourseManager::subscribeUser(
2814
                    $userId,
2815
                    $courseInfo['code'],
2816
                    $status,
2817
                    0,
2818
                    $userCourseCategory
2819
                );
2820
2821
                if ($result) {
2822
                    $this->logger->addInfo(
2823
                        "User $userId added to course ".$courseInfo['code']." with status '$status' with course category: '$userCourseCategory'"
2824
                    );
2825
                } else {
2826
                    $this->logger->addInfo(
2827
                        "User $userId was NOT ADDED to course ".$courseInfo['code']." with status '$status' with course category: '$userCourseCategory'"
2828
                    );
2829
                }
2830
            }
2831
        }
2832
2833
        if ($moveFile) {
2834
            $this->moveFile($file);
2835
        }
2836
    }
2837
2838
    /**
2839
     * 23/4/2017 to datetime.
2840
     *
2841
     * @param $string
2842
     *
2843
     * @return mixed
2844
     */
2845
    private function createDateTime($string)
2846
    {
2847
        if (empty($string)) {
2848
            return null;
2849
        }
2850
2851
        $date = DateTime::createFromFormat('j/m/Y', $string);
2852
        if ($date) {
2853
            return $date;
2854
        }
2855
2856
        return null;
2857
    }
2858
2859
    /**
2860
     * @param $file
2861
     * @param bool  $moveFile
2862
     * @param array $teacherBackup
2863
     * @param array $groupBackup
2864
     *
2865
     * @return bool
2866
     */
2867
    private function importCareers(
2868
        $file,
2869
        $moveFile = false,
2870
        &$teacherBackup = [],
2871
        &$groupBackup = []
2872
    ) {
2873
        $data = Import::csv_reader($file);
2874
2875
        if (!empty($data)) {
2876
            $this->logger->addInfo(count($data).' records found.');
2877
            $extraFieldValue = new ExtraFieldValue('career');
2878
            $extraFieldName = $this->extraFieldIdNameList['career'];
2879
            $externalEventId = null;
2880
2881
            $extraField = new ExtraField('career');
2882
            $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable($extraFieldName);
2883
2884
            if (empty($extraFieldInfo)) {
2885
                $this->logger->addInfo("Extra field doesn't exists: $extraFieldName");
2886
2887
                return false;
2888
            }
2889
2890
            foreach ($data as $row) {
2891
                foreach ($row as $key => $value) {
2892
                    $key = (string) trim($key);
2893
                    // Remove utf8 bom
2894
                    $key = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $key);
2895
                    $row[$key] = $value;
2896
                }
2897
2898
                $itemId = $row['CareerId'];
2899
                $item = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
2900
                    $extraFieldName,
2901
                    $itemId,
2902
                    false,
2903
                    false,
2904
                    false
2905
                );
2906
2907
                $career = new Career();
2908
                if (empty($item)) {
2909
                    $params = [
2910
                        'status' => 1,
2911
                        'name' => $row['CareerName'],
2912
                    ];
2913
                    $careerId = $career->save($params);
2914
                    if ($careerId) {
2915
                        $this->logger->addInfo('Career saved: '.print_r($params, 1));
2916
                        $params = [
2917
                            'item_id' => $careerId,
2918
                            'extra_'.$extraFieldName => $itemId,
2919
                        ];
2920
                        $links = isset($row['HLinks']) ? $row['HLinks'] : [];
2921
                        if (!empty($links)) {
2922
                            $extraFieldUrlName = $this->extraFieldIdNameList['career_urls'];
2923
                            $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable(
2924
                                $extraFieldUrlName
2925
                            );
2926
                            if (!empty($extraFieldInfo)) {
2927
                                $params['extra_'.$extraFieldUrlName] = $links;
2928
                            }
2929
                        }
2930
                        $extraFieldValue->saveFieldValues($params);
2931
                    }
2932
                } else {
2933
                    if (isset($item['item_id'])) {
2934
                        $params = [
2935
                            'id' => $item['item_id'],
2936
                            'name' => $row['CareerName'],
2937
                        ];
2938
                        $career->update($params);
2939
                        $this->logger->addInfo('Career updated: '.print_r($params, 1));
2940
                        $links = isset($row['HLinks']) ? $row['HLinks'] : [];
2941
2942
                        if (!empty($links)) {
2943
                            $extraFieldUrlName = $this->extraFieldIdNameList['career_urls'];
2944
                            $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable(
2945
                                $extraFieldUrlName
2946
                            );
2947
                            if (!empty($extraFieldInfo)) {
2948
                                $params = [
2949
                                    'item_id' => $item['item_id'],
2950
                                    'extra_'.$extraFieldName => $itemId,
2951
                                    'extra_'.$extraFieldUrlName => $links,
2952
                                ];
2953
                                $extraFieldValue->saveFieldValues($params);
2954
                            }
2955
                        }
2956
                    }
2957
                }
2958
            }
2959
        }
2960
2961
        if ($moveFile) {
2962
            $this->moveFile($file);
2963
        }
2964
    }
2965
2966
    /**
2967
     * @param $file
2968
     * @param bool  $moveFile
2969
     * @param array $teacherBackup
2970
     * @param array $groupBackup
2971
     */
2972
    private function importCareersResultsRemoveStatic(
2973
        $file,
2974
        $moveFile = false
2975
    ) {
2976
        $data = Import::csv_reader($file);
2977
2978
        $careerIdList = [];
2979
        $userIdList = [];
2980
2981
        if (!empty($data)) {
2982
            $totalCount = count($data);
2983
            $this->logger->addInfo($totalCount.' records found.');
2984
2985
            $extraFieldValue = new ExtraFieldValue('career');
2986
            $extraFieldName = $this->extraFieldIdNameList['career'];
2987
            $rowCounter = 0;
2988
            foreach ($data as $row) {
2989
                $this->logger->addInfo("---------- Row: # $rowCounter");
2990
                $rowCounter++;
2991
                if (empty($row)) {
2992
                    continue;
2993
                }
2994
2995
                foreach ($row as $key => $value) {
2996
                    $key = (string) trim($key);
2997
                    // Remove utf8 bom
2998
                    $key = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $key);
2999
                    $row[$key] = $value;
3000
                }
3001
3002
                $rowStudentId = $row['StudentId'];
3003
3004
                if (isset($userIdList[$rowStudentId])) {
3005
                    $studentId = $userIdList[$rowStudentId];
3006
                } else {
3007
                    $studentId = UserManager::get_user_id_from_original_id(
3008
                        $rowStudentId,
3009
                        $this->extraFieldIdNameList['user']
3010
                    );
3011
                    $userIdList[$rowStudentId] = $studentId;
3012
                }
3013
3014
                $careerId = $row['CareerId'];
3015
                if (isset($careerIdList[$careerId])) {
3016
                    $careerChamiloId = $careerIdList[$careerId];
3017
                } else {
3018
                    $item = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
3019
                        $extraFieldName,
3020
                        $careerId
3021
                    );
3022
3023
                    if (empty($item)) {
3024
                        $careerIdList[$careerId] = 0;
3025
                        continue;
3026
                    } else {
3027
                        if (isset($item['item_id'])) {
3028
                            $careerChamiloId = $item['item_id'];
3029
                            $careerIdList[$careerId] = $careerChamiloId;
3030
                        } else {
3031
                            $careerIdList[$careerId] = 0;
3032
                            continue;
3033
                        }
3034
                    }
3035
                }
3036
3037
                if (empty($careerChamiloId)) {
3038
                    $this->logger->addInfo("Career not found: $careerId ");
3039
                    continue;
3040
                }
3041
3042
                $userCareerData = UserManager::getUserCareer($studentId, $careerChamiloId);
3043
3044
                if (empty($userCareerData)) {
3045
                    $this->logger->addInfo(
3046
                        "User chamilo id # $studentId (".$row['StudentId'].") has no career #$careerChamiloId (ext #$careerId)"
3047
                    );
3048
                    continue;
3049
                }
3050
3051
                $extraData = isset($userCareerData['extra_data']) && !empty($userCareerData['extra_data']) ? unserialize($userCareerData['extra_data']) : [];
3052
                unset($extraData[$row['CourseId']][$row['ResultId']]);
3053
                $serializedValue = serialize($extraData);
3054
3055
                UserManager::updateUserCareer($userCareerData['id'], $serializedValue);
3056
3057
                $this->logger->addInfo('Deleting: result id'.$row['ResultId']);
3058
                $this->logger->addInfo(
3059
                    "Saving graph for user chamilo # $studentId (".$row['StudentId'].") with career #$careerChamiloId (ext #$careerId)"
3060
                );
3061
            }
3062
        }
3063
3064
        if ($moveFile) {
3065
            $this->moveFile($file);
3066
        }
3067
    }
3068
3069
    /**
3070
     * @param $file
3071
     * @param bool  $moveFile
3072
     * @param array $teacherBackup
3073
     * @param array $groupBackup
3074
     */
3075
    private function importCareersResults(
3076
        $file,
3077
        $moveFile = false,
3078
        &$teacherBackup = [],
3079
        &$groupBackup = []
3080
    ) {
3081
        $data = Import::csv_reader($file);
3082
3083
        $userTable = Database::get_main_table(TABLE_MAIN_USER);
3084
        $careerIdList = [];
3085
        $userIdList = [];
3086
        if (!empty($data)) {
3087
            $totalCount = count($data);
3088
            $this->logger->addInfo($totalCount.' records found.');
3089
3090
            $extraFieldValue = new ExtraFieldValue('career');
3091
            $extraFieldName = $this->extraFieldIdNameList['career'];
3092
            $rowCounter = 0;
3093
            foreach ($data as $row) {
3094
                $this->logger->addInfo("---------- Row: # $rowCounter");
3095
                $rowCounter++;
3096
                if (empty($row)) {
3097
                    continue;
3098
                }
3099
3100
                foreach ($row as $key => $value) {
3101
                    $key = (string) trim($key);
3102
                    // Remove utf8 bom
3103
                    $key = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $key);
3104
                    $row[$key] = $value;
3105
                }
3106
3107
                $rowStudentId = $row['StudentId'];
3108
3109
                if (isset($userIdList[$rowStudentId])) {
3110
                    $studentId = $userIdList[$rowStudentId];
3111
                } else {
3112
                    $studentId = UserManager::get_user_id_from_original_id(
3113
                        $rowStudentId,
3114
                        $this->extraFieldIdNameList['user']
3115
                    );
3116
3117
                    $userIdList[$rowStudentId] = $studentId;
3118
                }
3119
3120
                $careerId = $row['CareerId'];
3121
                if (isset($careerIdList[$careerId])) {
3122
                    $careerChamiloId = $careerIdList[$careerId];
3123
                } else {
3124
                    $item = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
3125
                        $extraFieldName,
3126
                        $careerId
3127
                    );
3128
3129
                    if (empty($item)) {
3130
                        //$this->logger->addInfo("Career not found: $careerId case 1");
3131
                        $careerIdList[$careerId] = 0;
3132
                        continue;
3133
                    } else {
3134
                        if (isset($item['item_id'])) {
3135
                            $careerChamiloId = $item['item_id'];
3136
                            $careerIdList[$careerId] = $careerChamiloId;
3137
                        } else {
3138
                            $careerIdList[$careerId] = 0;
3139
                            //$this->logger->addInfo("Career not found: $careerId case 2");
3140
                            continue;
3141
                        }
3142
                    }
3143
                }
3144
3145
                if (empty($careerChamiloId)) {
3146
                    $this->logger->addInfo("Career not found: $careerId ");
3147
                    continue;
3148
                }
3149
3150
                $userCareerData = UserManager::getUserCareer($studentId, $careerChamiloId);
3151
3152
                if (empty($userCareerData)) {
3153
                    $this->logger->addInfo(
3154
                        "User chamilo id # $studentId (".$row['StudentId'].") has no career #$careerChamiloId (ext #$careerId)"
3155
                    );
3156
                    continue;
3157
                }
3158
3159
                $extraData = isset($userCareerData['extra_data']) && !empty($userCareerData['extra_data']) ? unserialize($userCareerData['extra_data']) : [];
3160
3161
                $sql = "SELECT firstname, lastname FROM $userTable
3162
                        WHERE username='".Database::escape_string($row['TeacherUsername'])."'";
3163
                $result = Database::query($sql);
3164
3165
                $teacherName = $row['TeacherUsername'];
3166
                if (Database::num_rows($result)) {
3167
                    $teacherInfo = Database::fetch_array($result);
3168
                    $teacherName = $teacherInfo['firstname'].' '.$teacherInfo['lastname'];
3169
                }
3170
3171
                $extraData[$row['CourseId']][$row['ResultId']] = [
3172
                    'Description' => $row['Description'],
3173
                    'Period' => $row['Period'],
3174
                    'TeacherText' => $row['TeacherText'],
3175
                    'TeacherUsername' => $teacherName,
3176
                    'ScoreText' => $row['ScoreText'],
3177
                    'ScoreValue' => $row['ScoreValue'],
3178
                    'Info' => $row['Info'],
3179
                    'BgColor' => $row['BgColor'],
3180
                    'Color' => $row['Color'],
3181
                    'BorderColor' => $row['BorderColor'],
3182
                    'Icon' => $row['Icon'],
3183
                    'IconColor' => $row['IconColor'],
3184
                    'SortDate' => $row['SortDate'] ?? '',
3185
                ];
3186
                $serializedValue = serialize($extraData);
3187
3188
                UserManager::updateUserCareer($userCareerData['id'], $serializedValue);
3189
3190
                $this->logger->addInfo(
3191
                    "Saving graph for user chamilo # $studentId (".$row['StudentId'].") with career #$careerChamiloId (ext #$careerId)"
3192
                );
3193
            }
3194
        }
3195
3196
        if ($moveFile) {
3197
            $this->moveFile($file);
3198
        }
3199
    }
3200
3201
    /**
3202
     * @param $file
3203
     * @param bool  $moveFile
3204
     * @param array $teacherBackup
3205
     * @param array $groupBackup
3206
     */
3207
    private function importCareersDiagram(
3208
        $file,
3209
        $moveFile = false,
3210
        &$teacherBackup = [],
3211
        &$groupBackup = []
3212
    ) {
3213
        $data = Import::csv_reader($file);
3214
3215
        $extraFieldValue = new ExtraFieldValue('career');
3216
        $extraFieldName = $this->extraFieldIdNameList['career'];
3217
3218
        $extraField = new ExtraField('career');
3219
        $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable($extraFieldName);
3220
3221
        $careerDiagramExtraFieldName = $this->extraFieldIdNameList['career_diagram'];
3222
        $extraFieldDiagramInfo = $extraField->get_handler_field_info_by_field_variable(
3223
            $careerDiagramExtraFieldName
3224
        );
3225
3226
        if (empty($extraFieldInfo) || empty($extraFieldDiagramInfo)) {
3227
            return false;
3228
        }
3229
3230
        if (!empty($data)) {
3231
            $this->logger->addInfo(count($data).' records found.');
3232
            $values = [];
3233
            foreach ($data as $row) {
3234
                if (empty($row)) {
3235
                    continue;
3236
                }
3237
                foreach ($row as $key => $value) {
3238
                    $key = (string) trim($key);
3239
                    // Remove utf8 bom
3240
                    $key = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $key);
3241
                    $row[$key] = $value;
3242
                }
3243
                $values[$row['Column']][] = $row;
3244
            }
3245
3246
            $careerList = [];
3247
            $careerNameList = [];
3248
            ksort($values);
3249
            $careerChamiloIdList = [];
3250
            // 1. First create all items
3251
            foreach ($values as $column => $rowList) {
3252
                foreach ($rowList as $row) {
3253
                    $careerId = $row['CareerId'];
3254
                    $item = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
3255
                        $extraFieldName,
3256
                        $careerId,
3257
                        false,
3258
                        false,
3259
                        false
3260
                    );
3261
3262
                    if (empty($item)) {
3263
                        $this->logger->addInfo("Career not found: $careerId");
3264
                        continue;
3265
                    } else {
3266
                        if (isset($item['item_id'])) {
3267
                            $careerChamiloId = $item['item_id'];
3268
                            $career = new Career();
3269
                            $career = $career->find($careerChamiloId);
3270
                            $chamiloCareerName = $career['name'];
3271
                            $careerNameList[$careerId] = $chamiloCareerName;
3272
                            $careerChamiloIdList[$careerId] = $careerChamiloId;
3273
                        } else {
3274
                            continue;
3275
                        }
3276
                    }
3277
3278
                    if (empty($chamiloCareerName)) {
3279
                        $this->logger->addInfo("Career not found: $careerId");
3280
                        continue;
3281
                    }
3282
3283
                    if (isset($careerList[$careerId])) {
3284
                        $graph = $careerList[$careerId];
3285
                    } else {
3286
                        $graph = new Graph($careerId);
3287
                        $graph->setAttribute('graphviz.graph.rankdir', 'LR');
3288
                        $careerList[$careerId] = $graph;
3289
                    }
3290
3291
                    $currentCourseId = $row['CourseId'];
3292
                    $name = $row['CourseName'];
3293
                    $notes = $row['Notes'];
3294
                    $groupValue = $row['Group'];
3295
                    $boxColumn = $row['Column'];
3296
                    $rowValue = $row['Row'];
3297
                    $color = isset($row['DefinedColor']) ? $row['DefinedColor'] : '';
3298
                    $arrow = isset($row['DrawArrowFrom']) ? $row['DrawArrowFrom'] : '';
3299
                    $subGroup = isset($row['SubGroup']) ? $row['SubGroup'] : '';
3300
                    $connections = isset($row['Connections']) ? $row['Connections'] : '';
3301
                    $linkedElement = isset($row['LinkedElement']) ? $row['LinkedElement'] : '';
3302
3303
                    if ($graph->hasVertex($currentCourseId)) {
3304
                        // Avoid double insertion
3305
                        continue;
3306
                    } else {
3307
                        $current = $graph->createVertex($currentCourseId);
3308
                        $current->setAttribute('graphviz.label', $name);
3309
                        $current->setAttribute('DefinedColor', $color);
3310
                        $current->setAttribute('Notes', $notes);
3311
                        $current->setAttribute('Row', $rowValue);
3312
                        $current->setAttribute('Group', $groupValue);
3313
                        $current->setAttribute('Column', $boxColumn);
3314
                        $current->setAttribute('DrawArrowFrom', $arrow);
3315
                        $current->setAttribute('SubGroup', $subGroup);
3316
                        $current->setAttribute('Connections', $connections);
3317
                        $current->setAttribute('LinkedElement', $linkedElement);
3318
                        $current->setAttribute('graphviz.shape', 'box');
3319
                        $current->setGroup($column);
3320
                    }
3321
                }
3322
            }
3323
3324
            // 2. Create connections
3325
            // $column start with 1 (depending in Column row)
3326
            foreach ($values as $column => $rowList) {
3327
                foreach ($rowList as $row) {
3328
                    $careerId = $row['CareerId'];
3329
                    if (isset($careerList[$careerId])) {
3330
                        $graph = $careerList[$careerId];
3331
                    } else {
3332
                        continue;
3333
                    }
3334
3335
                    $currentCourseId = $row['CourseId'];
3336
                    if ($graph->hasVertex($currentCourseId)) {
3337
                        $current = $graph->getVertex($currentCourseId);
3338
                    } else {
3339
                        continue;
3340
                    }
3341
3342
                    if (isset($row['DependedOn']) && !empty($row['DependedOn'])) {
3343
                        $parentList = explode(',', $row['DependedOn']);
3344
                        foreach ($parentList as $parentId) {
3345
                            $parentId = (int) $parentId;
3346
                            if ($graph->hasVertex($parentId)) {
3347
                                /** @var Vertex $parent */
3348
                                $parent = $graph->getVertex($parentId);
3349
                                /*$parent->setAttribute('graphviz.color', 'red');
3350
                                $parent->setAttribute('graphviz.label', $name);
3351
                                $parent->setAttribute('graphviz.shape', 'square');*/
3352
                                $parent->createEdgeTo($current);
3353
                            }
3354
                        }
3355
                    }
3356
                }
3357
            }
3358
3359
            /** @var Graph $graph */
3360
            foreach ($careerList as $id => $graph) {
3361
                if (isset($careerChamiloIdList[$id])) {
3362
                    $params = [
3363
                        'item_id' => $careerChamiloIdList[$id],
3364
                        'extra_'.$careerDiagramExtraFieldName => serialize($graph),
3365
                        'extra_'.$extraFieldName => $id,
3366
                    ];
3367
                    $extraFieldValue->saveFieldValues($params, true);
3368
                }
3369
            }
3370
        }
3371
3372
        if ($moveFile) {
3373
            $this->moveFile($file);
3374
        }
3375
    }
3376
3377
    /**
3378
     * @param string $file
3379
     * @param bool   $moveFile
3380
     * @param array  $teacherBackup
3381
     * @param array  $groupBackup
3382
     */
3383
    private function importUnsubscribeStatic(
3384
        $file,
3385
        $moveFile = false,
3386
        &$teacherBackup = [],
3387
        &$groupBackup = []
3388
    ) {
3389
        $data = Import::csv_reader($file);
3390
3391
        if (!empty($data)) {
3392
            $this->logger->addInfo(count($data)." records found.");
3393
            foreach ($data as $row) {
3394
                $chamiloUserName = $row['UserName'];
3395
                $chamiloCourseCode = $row['CourseCode'];
3396
                $chamiloSessionId = $row['SessionID'];
3397
3398
                $sessionInfo = api_get_session_info($chamiloSessionId);
3399
3400
                if (empty($sessionInfo)) {
3401
                    $this->logger->addError('Session does not exists: '.$chamiloSessionId);
3402
                    continue;
3403
                }
3404
3405
                $courseInfo = api_get_course_info($chamiloCourseCode);
3406
                if (empty($courseInfo)) {
3407
                    $this->logger->addError('Course does not exists: '.$courseInfo);
3408
                    continue;
3409
                }
3410
3411
                $userId = UserManager::get_user_id_from_username($chamiloUserName);
3412
3413
                if (empty($userId)) {
3414
                    $this->logger->addError('User does not exists: '.$chamiloUserName);
3415
                    continue;
3416
                }
3417
3418
                $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
3419
                        WHERE
3420
                            user_id = ".$userId." AND
3421
                            c_id = '".$courseInfo['real_id']."'
3422
                        ";
3423
                $result = Database::query($sql);
3424
                $rows = Database::num_rows($result);
3425
                if ($rows > 0) {
3426
                    $userCourseData = Database::fetch_array($result, 'ASSOC');
3427
                    if (!empty($userCourseData)) {
3428
                        $teacherBackup[$userId][$courseInfo['code']] = $userCourseData;
3429
                    }
3430
                }
3431
3432
                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
3433
                        WHERE
3434
                            user_id = ".$userId." AND
3435
                            c_id = '".$courseInfo['real_id']."'
3436
                        ";
3437
3438
                $result = Database::query($sql);
3439
                while ($groupData = Database::fetch_array($result, 'ASSOC')) {
3440
                    $groupBackup['user'][$userId][$courseInfo['code']][$groupData['group_id']] = $groupData;
3441
                }
3442
3443
                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
3444
                        WHERE
3445
                            user_id = ".$userId." AND
3446
                            c_id = '".$courseInfo['real_id']."'
3447
                        ";
3448
3449
                $result = Database::query($sql);
3450
                while ($groupData = Database::fetch_array($result, 'ASSOC')) {
3451
                    $groupBackup['tutor'][$userId][$courseInfo['code']][$groupData['group_id']] = $groupData;
3452
                }
3453
3454
                CourseManager::unsubscribe_user(
3455
                    $userId,
3456
                    $courseInfo['code'],
3457
                    $chamiloSessionId
3458
                );
3459
3460
                $this->logger->addError(
3461
                    "User '$chamiloUserName' was removed from session: #$chamiloSessionId, Course: ".$courseInfo['code']
3462
                );
3463
            }
3464
        }
3465
3466
        if ($moveFile) {
3467
            $this->moveFile($file);
3468
        }
3469
    }
3470
3471
    /**
3472
     *  Dump database tables.
3473
     */
3474
    private function dumpDatabaseTables()
3475
    {
3476
        echo 'Dumping tables'.PHP_EOL;
3477
3478
        // User
3479
        $table = Database::get_main_table(TABLE_MAIN_USER);
3480
        $tableAdmin = Database::get_main_table(TABLE_MAIN_ADMIN);
3481
        $sql = "DELETE FROM $table
3482
                WHERE user_id not in (select user_id from $tableAdmin) and status <> ".ANONYMOUS;
3483
        Database::query($sql);
3484
        echo $sql.PHP_EOL;
3485
3486
        // Truncate tables
3487
        $truncateTables = [
3488
            Database::get_main_table(TABLE_MAIN_COURSE),
3489
            Database::get_main_table(TABLE_MAIN_COURSE_USER),
3490
            Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE),
3491
            Database::get_main_table(TABLE_MAIN_CATEGORY),
3492
            Database::get_main_table(TABLE_MAIN_COURSE_MODULE),
3493
            Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER),
3494
            Database::get_main_table(TABLE_MAIN_SESSION),
3495
            Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY),
3496
            Database::get_main_table(TABLE_MAIN_SESSION_COURSE),
3497
            Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER),
3498
            Database::get_main_table(TABLE_MAIN_SESSION_USER),
3499
            Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION),
3500
            Database::get_main_table(TABLE_MAIN_SESSION_FIELD_VALUES),
3501
            Database::get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES),
3502
            Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES),
3503
            Database::get_main_table(TABLE_MAIN_USER_FIELD),
3504
            Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS),
3505
            Database::get_main_table(TABLE_MAIN_COURSE_FIELD),
3506
            Database::get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES),
3507
            Database::get_main_table(TABLE_MAIN_SESSION_FIELD),
3508
            Database::get_main_table(TABLE_MAIN_SESSION_FIELD_VALUES),
3509
            Database::get_course_table(TABLE_AGENDA),
3510
            Database::get_course_table(TABLE_AGENDA_ATTACHMENT),
3511
            Database::get_course_table(TABLE_AGENDA_REPEAT),
3512
            Database::get_course_table(TABLE_AGENDA_REPEAT_NOT),
3513
            Database::get_main_table(TABLE_PERSONAL_AGENDA),
3514
            Database::get_main_table(TABLE_PERSONAL_AGENDA_REPEAT_NOT),
3515
            Database::get_main_table(TABLE_PERSONAL_AGENDA_REPEAT),
3516
            Database::get_main_table(TABLE_MAIN_CALENDAR_EVENT_VALUES),
3517
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS),
3518
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS),
3519
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN),
3520
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_DOWNLOADS),
3521
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCICES),
3522
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT),
3523
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING),
3524
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT),
3525
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_UPLOADS),
3526
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT),
3527
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_ITEM_PROPERTY),
3528
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY),
3529
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION),
3530
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINKEVAL_LOG),
3531
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT),
3532
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT_LOG),
3533
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK),
3534
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_SCORE_DISPLAY),
3535
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE),
3536
            Database::get_course_table(TABLE_STUDENT_PUBLICATION),
3537
            Database::get_course_table(TABLE_QUIZ_QUESTION),
3538
            Database::get_course_table(TABLE_QUIZ_TEST),
3539
            Database::get_course_table(TABLE_QUIZ_ORDER),
3540
            Database::get_course_table(TABLE_QUIZ_ANSWER),
3541
            Database::get_course_table(TABLE_QUIZ_TEST_QUESTION),
3542
            Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION),
3543
            Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY),
3544
            Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY),
3545
            Database::get_course_table(TABLE_LP_MAIN),
3546
            Database::get_course_table(TABLE_LP_ITEM),
3547
            Database::get_course_table(TABLE_LP_VIEW),
3548
            Database::get_course_table(TABLE_LP_ITEM_VIEW),
3549
            Database::get_course_table(TABLE_DOCUMENT),
3550
            Database::get_course_table(TABLE_ITEM_PROPERTY),
3551
            Database::get_course_table(TABLE_TOOL_LIST),
3552
            Database::get_course_table(TABLE_TOOL_INTRO),
3553
            Database::get_course_table(TABLE_COURSE_SETTING),
3554
            Database::get_course_table(TABLE_SURVEY),
3555
            Database::get_course_table(TABLE_SURVEY_QUESTION),
3556
            Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION),
3557
            Database::get_course_table(TABLE_SURVEY_INVITATION),
3558
            Database::get_course_table(TABLE_SURVEY_ANSWER),
3559
            Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP),
3560
            Database::get_course_table(TABLE_SURVEY_REPORT),
3561
            Database::get_course_table(TABLE_GLOSSARY),
3562
            Database::get_course_table(TABLE_LINK),
3563
            Database::get_course_table(TABLE_LINK_CATEGORY),
3564
            Database::get_course_table(TABLE_GROUP),
3565
            Database::get_course_table(TABLE_GROUP_USER),
3566
            Database::get_course_table(TABLE_GROUP_TUTOR),
3567
            Database::get_course_table(TABLE_GROUP_CATEGORY),
3568
            Database::get_course_table(TABLE_DROPBOX_CATEGORY),
3569
            Database::get_course_table(TABLE_DROPBOX_FEEDBACK),
3570
            Database::get_course_table(TABLE_DROPBOX_POST),
3571
            Database::get_course_table(TABLE_DROPBOX_FILE),
3572
            Database::get_course_table(TABLE_DROPBOX_PERSON),
3573
        ];
3574
3575
        foreach ($truncateTables as $table) {
3576
            $sql = "TRUNCATE $table";
3577
            Database::query($sql);
3578
            echo $sql.PHP_EOL;
3579
        }
3580
3581
        $table = Database::get_course_table(TABLE_ITEM_PROPERTY);
3582
        $sql = "DELETE FROM $table WHERE tool = 'calendar_event'";
3583
        Database::query($sql);
3584
        echo $sql.PHP_EOL;
3585
    }
3586
3587
    /**
3588
     * If csv file ends with '"' character then a '";' is added.
3589
     *
3590
     * @param string $file
3591
     */
3592
    private function fixCSVFile($file)
3593
    {
3594
        /*$f = fopen($file, 'r+');
3595
        $cursor = -1;
3596
3597
        fseek($f, $cursor, SEEK_END);
3598
        $char = fgetc($f);
3599
        while ($char === "\n" || $char === "\r") {
3600
            fseek($f, $cursor--, SEEK_END);
3601
            $char = fgetc($f);
3602
        }
3603
3604
        if ($char === "\"") {
3605
            fseek($f, -1, SEEK_CUR);
3606
            fwrite($f, '";');
3607
        }*/
3608
    }
3609
3610
    /**
3611
     * Get custom tpl for mail welcome.
3612
     */
3613
    private function getCustomMailTemplate(): string
3614
    {
3615
        $name = 'mail/custom_calendar_welcome.tpl';
3616
        $sysTemplatePath = api_get_path(SYS_TEMPLATE_PATH);
3617
        if (is_readable($sysTemplatePath.'overrides/'.$name)) {
3618
            return 'overrides/'.$name;
3619
        }
3620
        $customThemeFolder = api_get_configuration_value('default_template');
3621
        if (is_readable($sysTemplatePath.$customThemeFolder.'/'.$name)) {
3622
            return $customThemeFolder.'/'.$name;
3623
        }
3624
        if (is_readable($sysTemplatePath.'default/'.$name)) {
3625
            return 'default/'.$name;
3626
        }
3627
        // If none has been found, it means we don't have a custom mail
3628
        // welcome message, so use the .dist version
3629
        $alternateName = 'mail/custom_calendar_welcome.dist.tpl';
3630
3631
        return 'default/'.$alternateName;
3632
    }
3633
}
3634
3635
$logger = new Logger('cron');
3636
$emails = isset($_configuration['cron_notification_mails']) ? $_configuration['cron_notification_mails'] : null;
3637
3638
$minLevel = Logger::DEBUG;
3639
3640
if (!is_array($emails)) {
3641
    $emails = [$emails];
3642
}
3643
$subject = "Cron main/cron/import_csv.php ".date('Y-m-d h:i:s');
3644
$from = api_get_setting('emailAdministrator');
3645
/*
3646
if (!empty($emails)) {
3647
    foreach ($emails as $email) {
3648
        $stream = new NativeMailerHandler($email, $subject, $from, $minLevel);
3649
        $logger->pushHandler(new BufferHandler($stream, 0, $minLevel));
3650
    }
3651
}*/
3652
3653
$stream = new StreamHandler(
3654
    api_get_path(SYS_ARCHIVE_PATH).'import_csv.log',
3655
    $minLevel
3656
);
3657
$logger->pushHandler(new BufferHandler($stream, 0, $minLevel));
3658
$logger->pushHandler(new RotatingFileHandler('import_csv', 5, $minLevel));
3659
3660
$verbose = false;
3661
if (isset($argv[1]) && $argv[1] === '--verbose') {
3662
    $verbose = true;
3663
}
3664
if ($verbose) {
3665
    $logger->pushHandler(new ErrorLogHandler());
3666
}
3667
3668
$cronImportCSVConditions = isset($_configuration['cron_import_csv_conditions']) ? $_configuration['cron_import_csv_conditions'] : null;
3669
3670
echo 'See the error log here: '.api_get_path(SYS_ARCHIVE_PATH).'import_csv.log'."\n";
3671
3672
$import = new ImportCsv($logger, $cronImportCSVConditions);
3673
3674
if (isset($_configuration['default_admin_user_id_for_cron'])) {
3675
    $import->defaultAdminId = $_configuration['default_admin_user_id_for_cron'];
3676
}
3677
// @todo in production disable the dump option
3678
$dump = false;
3679
if (isset($argv[1]) && $argv[1] === '--dump') {
3680
    $dump = true;
3681
}
3682
3683
if (isset($_configuration['import_csv_disable_dump']) &&
3684
    $_configuration['import_csv_disable_dump'] == true
3685
) {
3686
    $import->setDumpValues(false);
3687
} else {
3688
    $import->setDumpValues($dump);
3689
}
3690
3691
$import->setUpdateEmailToDummy(api_get_configuration_value('update_users_email_to_dummy_except_admins'));
3692
3693
// Do not moves the files to treated
3694
if (isset($_configuration['import_csv_test'])) {
3695
    $import->test = $_configuration['import_csv_test'];
3696
} else {
3697
    $import->test = true;
3698
}
3699
3700
$languageFilesToLoad = api_get_language_files_to_load($import->defaultLanguage);
3701
3702
foreach ($languageFilesToLoad as $languageFile) {
3703
    include $languageFile;
3704
}
3705
3706
// Set default language to be loaded
3707
$language = $import->defaultLanguage;
3708
global $language_interface;
3709
$language_interface = $language;
3710
global $language_interface_initial_value;
3711
$language_interface_initial_value = $language;
3712
3713
$timeStart = microtime(true);
3714
$import->run();
3715
$timeEnd = microtime(true);
3716
$executionTime = round(($timeEnd - $timeStart) / 60, 2);
3717
$logger->addInfo("Total execution Time $executionTime Min");
3718
3719
if (isset($_configuration['import_csv_fix_permissions']) &&
3720
    $_configuration['import_csv_fix_permissions'] == true
3721
) {
3722
    $command = "sudo find ".api_get_path(SYS_COURSE_PATH)." -type d -exec chmod 777 {} \; ";
3723
    echo "Executing: ".$command.PHP_EOL;
3724
    system($command);
3725
3726
    $command = "sudo find ".api_get_path(SYS_CODE_PATH)."upload/users  -type d -exec chmod 777 {} \;";
3727
    echo "Executing: ".$command.PHP_EOL;
3728
    system($command);
3729
}
3730