Passed
Push — 1.11.x ( df5809...b0c39f )
by Julito
10:58
created

ImportCsv::getDumpValues()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
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
                    $interval = new \DateInterval('P7D');
1267
                    $date->sub($interval);
1268
                    if ($date->getTimestamp() > time()) {
1269
                        $this->logger->addInfo(
1270
                            "Calendar event # ".$row['external_calendar_itemID']."
1271
                            in session [$externalSessionId] was not added
1272
                            because the startdate is more than 7 days in the future: ".$sessionInfo['access_start_date']
1273
                        );
1274
                        $errorFound = true;
1275
                    }
1276
                }
1277
1278
                $sendAnnouncement = false;
1279
                if (isset($row['sendmail']) && 1 === (int) $row['sendmail']) {
1280
                    $sendAnnouncement = true;
1281
                }
1282
1283
                // New condition.
1284
                if ($errorFound == false) {
1285
                    $eventsToCreate[] = [
1286
                        'start' => $startDate,
1287
                        'end' => $endDate,
1288
                        'title' => $title,
1289
                        'sender_id' => $teacherId,
1290
                        'course_id' => $courseInfo['real_id'],
1291
                        'session_id' => $sessionId,
1292
                        'comment' => $comment,
1293
                        'color' => $color,
1294
                        'send_announcement' => $sendAnnouncement,
1295
                        $this->extraFieldIdNameList['calendar_event'] => $row['external_calendar_itemID'],
1296
                    ];
1297
                }
1298
                $errorFound = false;
1299
            }
1300
1301
            if (empty($eventsToCreate)) {
1302
                $this->logger->addInfo('No events to add');
1303
1304
                return 0;
1305
            }
1306
1307
            $extraFieldValue = new ExtraFieldValue('calendar_event');
1308
            $extraFieldName = $this->extraFieldIdNameList['calendar_event'];
1309
            $externalEventId = null;
1310
1311
            $extraField = new ExtraField('calendar_event');
1312
            $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable($extraFieldName);
1313
1314
            if (empty($extraFieldInfo)) {
1315
                $this->logger->addInfo(
1316
                    "No calendar event extra field created: $extraFieldName"
1317
                );
1318
1319
                return 0;
1320
            }
1321
1322
            $this->logger->addInfo('Ready to insert # '.count($eventsToCreate).' events');
1323
            $batchSize = $this->batchSize;
1324
            $counter = 1;
1325
            $em = Database::getManager();
1326
            $eventStartDateList = [];
1327
            $eventEndDateList = [];
1328
            $report = [
1329
                'mail_sent' => 0,
1330
                'mail_not_sent_announcement_exists' => 0,
1331
                'mail_not_sent_because_date' => 0,
1332
                'mail_not_sent_because_setting' => 0,
1333
            ];
1334
1335
            $eventsToCreateFinal = [];
1336
            foreach ($eventsToCreate as $event) {
1337
                $update = false;
1338
                $item = null;
1339
                if (!isset($event[$extraFieldName])) {
1340
                    $this->logger->addInfo('No external_calendar_itemID found. Skipping ...');
1341
                    continue;
1342
                } else {
1343
                    $externalEventId = $event[$extraFieldName];
1344
                    if (empty($externalEventId)) {
1345
                        $this->logger->addInfo('external_calendar_itemID was set but empty. Skipping ...');
1346
                        continue;
1347
                    }
1348
1349
                    $item = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
1350
                        $extraFieldName,
1351
                        $externalEventId,
1352
                        false,
1353
                        false,
1354
                        false
1355
                    );
1356
1357
                    if (!empty($item)) {
1358
                        $update = true;
1359
                    }
1360
                }
1361
1362
                $courseInfo = api_get_course_info_by_id($event['course_id']);
1363
                $event['course_info'] = $courseInfo;
1364
                $event['update'] = $update;
1365
                $event['item'] = $item;
1366
1367
                $calendarEvent = null;
1368
                /* Check if event changed of course code */
1369
                if (!empty($item) && isset($item['item_id']) && !empty($item['item_id'])) {
1370
                    /** @var CCalendarEvent $calendarEvent */
1371
                    $calendarEvent = $em->getRepository('ChamiloCourseBundle:CCalendarEvent')->find($item['item_id']);
1372
                }
1373
1374
                if ($calendarEvent) {
1375
                    $this->logger->addInfo('Calendar event found '.$item['item_id']);
1376
                    if ($calendarEvent->getCId() != $courseInfo['real_id']) {
1377
                        $this->logger->addInfo('Move from course #'.$calendarEvent->getCId().' to #'.$courseInfo['real_id']);
1378
                        // Seems that the course id changed in the csv
1379
                        $calendarEvent->setCId($courseInfo['real_id']);
1380
                        $em->persist($calendarEvent);
1381
                        $em->flush();
1382
1383
                        $criteria = [
1384
                            'tool' => 'calendar_event',
1385
                            'ref' => $item['item_id'],
1386
                        ];
1387
                        /** @var CItemProperty $itemProperty */
1388
                        $itemProperty = $em->getRepository('ChamiloCourseBundle:CItemProperty')->findOneBy($criteria);
1389
                        $courseEntity = $em->getRepository('ChamiloCoreBundle:Course')->find($courseInfo['real_id']);
1390
                        if ($itemProperty && $courseEntity) {
1391
                            $itemProperty->setCourse($courseEntity);
1392
                            $em->persist($itemProperty);
1393
                            $em->flush();
1394
                        }
1395
                    }
1396
1397
                    // Checking if session still exists
1398
                    $calendarSessionId = (int) $calendarEvent->getSessionId();
1399
                    if (!empty($calendarSessionId)) {
1400
                        $calendarSessionInfo = api_get_session_info($calendarSessionId);
1401
                        if (empty($calendarSessionInfo)) {
1402
                            $calendarId = (int) $calendarEvent->getIid();
1403
1404
                            // Delete calendar events because the session was deleted!
1405
                            $this->logger->addInfo(
1406
                                "Delete event # $calendarId because session # $calendarSessionId doesn't exist"
1407
                            );
1408
1409
                            $sql = "DELETE FROM c_calendar_event
1410
                                    WHERE iid = $calendarId AND session_id = $calendarSessionId";
1411
                            Database::query($sql);
1412
                            $this->logger->addInfo($sql);
1413
1414
                            $sql = "DELETE FROM c_item_property
1415
                                    WHERE
1416
                                        tool = 'calendar_event' AND
1417
                                        ref = $calendarSessionId AND
1418
                                        session_id = $calendarSessionId";
1419
                            Database::query($sql);
1420
                            $this->logger->addInfo($sql);
1421
                        }
1422
                    }
1423
                } else {
1424
                    $this->logger->addInfo('Calendar event not found '.$item['item_id']);
1425
                }
1426
1427
                $event['external_event_id'] = $externalEventId;
1428
                if (isset($eventStartDateList[$courseInfo['real_id']]) &&
1429
                    isset($eventStartDateList[$courseInfo['real_id']][$event['session_id']])
1430
                ) {
1431
                    $currentItemDate = api_strtotime($event['start']);
1432
                    $firstDate = $eventStartDateList[$courseInfo['real_id']][$event['session_id']];
1433
                    if ($currentItemDate < api_strtotime($firstDate)) {
1434
                        $eventStartDateList[$courseInfo['real_id']][$event['session_id']] = $event['start'];
1435
                        $eventEndDateList[$courseInfo['real_id']][$event['session_id']] = $event['end'];
1436
                    }
1437
                } else {
1438
                    // First time
1439
                    $eventStartDateList[$courseInfo['real_id']][$event['session_id']] = $event['start'];
1440
                    $eventEndDateList[$courseInfo['real_id']][$event['session_id']] = $event['end'];
1441
                }
1442
                $eventsToCreateFinal[] = $event;
1443
            }
1444
1445
            $eventAlreadySent = [];
1446
1447
            $tpl = new Template(null, false, false, false, false, false, false);
1448
1449
            foreach ($eventsToCreateFinal as $event) {
1450
                $courseInfo = $event['course_info'];
1451
                $item = $event['item'];
1452
                $update = $event['update'];
1453
                $externalEventId = $event['external_event_id'];
1454
                $info = 'Course: '.$courseInfo['real_id'].' ('.$courseInfo['code'].') - Session: '.$event['session_id'].' external event id: '.$externalEventId;
1455
1456
                $agenda = new Agenda(
1457
                    'course',
1458
                    $event['sender_id'],
1459
                    $courseInfo['real_id'],
1460
                    $event['session_id']
1461
                );
1462
                $agenda->set_course($courseInfo);
1463
                $agenda->setSessionId($event['session_id']);
1464
                $agenda->setSenderId($event['sender_id']);
1465
                $agenda->setIsAllowedToEdit(true);
1466
                $eventComment = $event['comment'];
1467
                $color = $event['color'];
1468
1469
                // To use the event comment you need
1470
                // ALTER TABLE c_calendar_event ADD COLUMN comment TEXT;
1471
                // add in configuration.php allow_agenda_event_comment = true
1472
                if (empty($courseInfo)) {
1473
                    $this->logger->addInfo(
1474
                        "No course found for event #$externalEventId Course #".$event['course_id']." Skipping ..."
1475
                    );
1476
                    continue;
1477
                }
1478
1479
                if (empty($event['sender_id'])) {
1480
                    $this->logger->addInfo(
1481
                        "No sender found for event #$externalEventId Send #".$event['sender_id']." Skipping ..."
1482
                    );
1483
                    continue;
1484
                }
1485
1486
                // Taking first element of course-session event
1487
                $alreadyAdded = false;
1488
                $firstDate = $eventStartDateList[$courseInfo['real_id']][$event['session_id']];
1489
                $firstEndDate = $eventEndDateList[$courseInfo['real_id']][$event['session_id']];
1490
1491
                if (isset($eventAlreadySent[$courseInfo['real_id']]) &&
1492
                    isset($eventAlreadySent[$courseInfo['real_id']][$event['session_id']])
1493
                ) {
1494
                    $alreadyAdded = true;
1495
                } else {
1496
                    $eventAlreadySent[$courseInfo['real_id']][$event['session_id']] = true;
1497
                }
1498
1499
                // Working days (Mon-Fri) see BT#12156#note-16
1500
                $days = 3;
1501
                $startDatePlusDays = api_strtotime("$days weekdays");
1502
1503
                /*
1504
                $timePart = date('H:i:s', api_strtotime('now'));
1505
                $datePart = date('Y-m-d', api_strtotime("$days weekdays"));
1506
                $startDatePlusDays = "$timePart $datePart";
1507
                */
1508
                $this->logger->addInfo(
1509
                    'startDatePlusDays: '.api_get_utc_datetime($startDatePlusDays).' - First date: '.$firstDate
1510
                );
1511
1512
                // Send.
1513
                $sendMail = false;
1514
                if ($startDatePlusDays > api_strtotime($firstDate)) {
1515
                    $sendMail = true;
1516
                }
1517
1518
                $allowAnnouncementSendEmail = false;
1519
                if ($event['send_announcement']) {
1520
                    $allowAnnouncementSendEmail = true;
1521
                }
1522
1523
                // Send announcement to users
1524
                if ($allowAnnouncementSendEmail) {
1525
                    if ($sendMail && $alreadyAdded == false) {
1526
                        $start = $firstDate;
1527
                        $end = $firstEndDate;
1528
1529
                        if (!empty($end) &&
1530
                            api_format_date($start, DATE_FORMAT_LONG) ==
1531
                            api_format_date($end, DATE_FORMAT_LONG)
1532
                        ) {
1533
                            $date = api_format_date($start, DATE_FORMAT_LONG).' ('.
1534
                                api_format_date($start, TIME_NO_SEC_FORMAT).' '.
1535
                                api_format_date($end, TIME_NO_SEC_FORMAT).')';
1536
                        } else {
1537
                            $date = api_format_date($start, DATE_TIME_FORMAT_LONG_24H).' - '.
1538
                                api_format_date($end, DATE_TIME_FORMAT_LONG_24H);
1539
                        }
1540
1541
                        $sessionName = '';
1542
                        $sessionId = isset($event['session_id']) && !empty($event['session_id']) ? $event['session_id'] : 0;
1543
                        if (!empty($sessionId)) {
1544
                            $sessionName = api_get_session_name($sessionId);
1545
                        }
1546
1547
                        $courseTitle = $courseInfo['title'];
1548
1549
                        // Get the value of the "careerid" extra field of this
1550
                        // session
1551
                        $sessionExtraFieldValue = new ExtraFieldValue('session');
1552
                        $externalCareerIdList = $sessionExtraFieldValue->get_values_by_handler_and_field_variable(
1553
                            $event['session_id'],
1554
                            'careerid'
1555
                        );
1556
                        $externalCareerIdList = $externalCareerIdList['value'];
1557
                        if (substr($externalCareerIdList, 0, 1) === '[') {
1558
                            $externalCareerIdList = substr($externalCareerIdList, 1, -1);
1559
                            $externalCareerIds = preg_split('/,/', $externalCareerIdList);
1560
                        } else {
1561
                            $externalCareerIds = [$externalCareerIdList];
1562
                        }
1563
1564
                        $careerExtraFieldValue = new ExtraFieldValue('career');
1565
                        $career = new Career();
1566
                        $careerName = '';
1567
1568
                        // Concat the names of each career linked to this session
1569
                        foreach ($externalCareerIds as $externalCareerId) {
1570
                            // Using the external_career_id field (from above),
1571
                            // find the career ID
1572
                            $careerValue = $careerExtraFieldValue->get_item_id_from_field_variable_and_field_value(
1573
                                'external_career_id',
1574
                                $externalCareerId
1575
                            );
1576
                            $career = $career->find($careerValue['item_id']);
1577
                            $careerName .= $career['name'].', ';
1578
                        }
1579
                        // Remove trailing comma
1580
                        $careerName = substr($careerName, 0, -2);
1581
                        $subject = sprintf(
1582
                            get_lang('WelcomeToPortalXInCourseSessionX'),
1583
                            api_get_setting('Institution'),
1584
                            $courseInfo['title']
1585
                        );
1586
1587
                        $tpl->assign('course_title', $courseTitle);
1588
                        $tpl->assign('career_name', $careerName);
1589
                        $tpl->assign('first_lesson', $date);
1590
                        $tpl->assign('location', $eventComment);
1591
                        $tpl->assign('session_name', $sessionName);
1592
1593
                        if (empty($sessionId)) {
1594
                            $teachersToString = CourseManager::getTeacherListFromCourseCodeToString(
1595
                                $courseInfo['code'],
1596
                                ','
1597
                            );
1598
                        } else {
1599
                            $teachersToString = SessionManager::getCoachesByCourseSessionToString(
1600
                                $sessionId,
1601
                                $courseInfo['real_id'],
1602
                                ','
1603
                            );
1604
                        }
1605
1606
                        $tpl->assign('teachers', $teachersToString);
1607
1608
                        $templateName = $tpl->get_template('mail/custom_calendar_welcome.tpl');
1609
                        $emailBody = $tpl->fetch($templateName);
1610
1611
                        $coaches = SessionManager::getCoachesByCourseSession(
1612
                            $event['session_id'],
1613
                            $courseInfo['real_id']
1614
                        );
1615
1616
                        // Search if an announcement exists:
1617
                        $announcementsWithTitleList = AnnouncementManager::getAnnouncementsByTitle(
1618
                            $subject,
1619
                            $courseInfo['real_id'],
1620
                            $event['session_id'],
1621
                            1
1622
                        );
1623
1624
                        if (count($announcementsWithTitleList) === 0) {
1625
                            $this->logger->addInfo(
1626
                                'Mail to be sent because start date: '.$event['start'].' and no announcement found.'
1627
                            );
1628
1629
                            $senderId = $this->defaultAdminId;
1630
                            if (!empty($coaches) && isset($coaches[0]) && !empty($coaches[0])) {
1631
                                $senderId = $coaches[0];
1632
                            }
1633
1634
                            $announcementId = AnnouncementManager::add_announcement(
1635
                                $courseInfo,
1636
                                $event['session_id'],
1637
                                $subject,
1638
                                $emailBody,
1639
                                [
1640
                                    'everyone',
1641
                                    'users' => $coaches,
1642
                                ],
1643
                                [],
1644
                                null,
1645
                                null,
1646
                                false,
1647
                                $senderId
1648
                            );
1649
1650
                            if ($announcementId) {
1651
                                $this->logger->addInfo("Announcement added: $announcementId in $info");
1652
                                $this->logger->addInfo("<<--SENDING MAIL Sender id: $senderId-->>");
1653
                                $report['mail_sent']++;
1654
                                AnnouncementManager::sendEmail(
1655
                                    $courseInfo,
1656
                                    $event['session_id'],
1657
                                    $announcementId,
1658
                                    false,
1659
                                    false,
1660
                                    $this->logger,
1661
                                    $senderId,
1662
                                    true
1663
                                );
1664
                            } else {
1665
                                $this->logger->addError(
1666
                                    "Error when trying to add announcement with title $subject here: $info and SenderId = $senderId"
1667
                                );
1668
                            }
1669
                        } else {
1670
                            $report['mail_not_sent_announcement_exists']++;
1671
                            $this->logger->addInfo(
1672
                                "Mail NOT sent. An announcement seems to be already saved in '$info'"
1673
                            );
1674
                        }
1675
                    } else {
1676
                        $this->logger->addInfo(
1677
                            "Send Mail: ".intval($sendMail).' - Already added: '.intval($alreadyAdded)
1678
                        );
1679
                        if ($sendMail == false) {
1680
                            $report['mail_not_sent_because_date']++;
1681
                        }
1682
                    }
1683
                } else {
1684
                    $this->logger->addInfo("Announcement not sent because config 'sendmail' in CSV");
1685
                    $report['mail_not_sent_because_setting']++;
1686
                }
1687
1688
                $content = '';
1689
                if ($update && isset($item['item_id'])) {
1690
                    $eventInfo = $agenda->get_event($item['item_id']);
1691
                    if (empty($eventInfo)) {
1692
                        // Means that agenda external id exists but the event doesn't exist
1693
                        $this->logger->addInfo("external event id exists: $externalEventId");
1694
                        $this->logger->addInfo("but Chamilo event doesn't exists: ".$item['item_id']);
1695
1696
                        $eventId = $agenda->addEvent(
1697
                            $event['start'],
1698
                            $event['end'],
1699
                            false,
1700
                            $event['title'],
1701
                            $content,
1702
                            ['everyone'], // $usersToSend
1703
                            false, //$addAsAnnouncement = false
1704
                            null, //  $parentEventId
1705
                            [], //$attachmentArray = array(),
1706
                            [], //$attachmentCommentList
1707
                            $eventComment,
1708
                            $color
1709
                        );
1710
1711
                        if (!empty($eventId)) {
1712
                            $this->logger->addInfo("Chamilo event created: ".$eventId);
1713
                            $extraFieldValueItem = $extraFieldValue->get_values_by_handler_and_field_id(
1714
                                $item['item_id'],
1715
                                $extraFieldInfo['id']
1716
                            );
1717
1718
                            if (!empty($extraFieldValueItem) && isset($extraFieldValueItem['id'])) {
1719
                                $params = [
1720
                                    'id' => $extraFieldValueItem['id'],
1721
                                    'item_id' => $eventId,
1722
                                ];
1723
                                $extraFieldValue->update($params);
1724
                                $this->logger->addInfo(
1725
                                    'Updating calendar extra field #'.$extraFieldValueItem['id'].'
1726
                                    new item_id: '.$eventId.' old item_id: '.$item['item_id']
1727
                                );
1728
                            }
1729
                        } else {
1730
                            $this->logger->addInfo("Error while creating event external id: $externalEventId");
1731
                        }
1732
                    } else {
1733
                        // The event already exists, just update
1734
                        $eventResult = $agenda->editEvent(
1735
                            $item['item_id'],
1736
                            $event['start'],
1737
                            $event['end'],
1738
                            false,
1739
                            $event['title'],
1740
                            $content,
1741
                            ['everyone'], // $usersToSend
1742
                            [], //$attachmentArray = array(),
1743
                            [], //$attachmentCommentList
1744
                            $eventComment,
1745
                            $color,
1746
                            false,
1747
                            false,
1748
                            $this->defaultAdminId
1749
                        );
1750
1751
                        if ($eventResult !== false) {
1752
                            $this->logger->addInfo(
1753
                                "Event updated #".$item['item_id']." External cal Id: (".$externalEventId.") $info"
1754
                            );
1755
                        } else {
1756
                            $this->logger->addInfo(
1757
                                "Error while updating event with external id: $externalEventId"
1758
                            );
1759
                        }
1760
                    }
1761
                } else {
1762
                    // New event. Create it.
1763
                    $eventId = $agenda->addEvent(
1764
                        $event['start'],
1765
                        $event['end'],
1766
                        false,
1767
                        $event['title'],
1768
                        $content,
1769
                        ['everyone'], // $usersToSend
1770
                        false, //$addAsAnnouncement = false
1771
                        null, //  $parentEventId
1772
                        [], //$attachmentArray = array(),
1773
                        [], //$attachmentCommentList
1774
                        $eventComment,
1775
                        $color
1776
                    );
1777
1778
                    if (!empty($eventId)) {
1779
                        $extraFieldValue->save(
1780
                            [
1781
                                'value' => $externalEventId,
1782
                                'field_id' => $extraFieldInfo['id'],
1783
                                'item_id' => $eventId,
1784
                            ]
1785
                        );
1786
                        $this->logger->addInfo(
1787
                            "Event added: #$eventId External cal id: (".$externalEventId.") $info"
1788
                        );
1789
                    } else {
1790
                        $this->logger->addInfo(
1791
                            "Error while creating event external id: $externalEventId"
1792
                        );
1793
                    }
1794
                }
1795
1796
                if (($counter % $batchSize) === 0) {
1797
                    $em->flush();
1798
                    $em->clear(); // Detaches all objects from Doctrine!
1799
                }
1800
                $counter++;
1801
            }
1802
1803
            $em->clear(); // Detaches all objects from Doctrine!
1804
            $this->logger->addInfo('------Summary------');
1805
            foreach ($report as $title => $count) {
1806
                $this->logger->addInfo("$title: $count");
1807
            }
1808
            $this->logger->addInfo('------End Summary------');
1809
        }
1810
1811
        if ($moveFile) {
1812
            $this->moveFile($file);
1813
        }
1814
    }
1815
1816
    private function importSkillset(
1817
        $file,
1818
        $moveFile = true
1819
    ) {
1820
        $this->fixCSVFile($file);
1821
        $data = Import::csvToArray($file);
1822
        if (!empty($data)) {
1823
            $this->logger->addInfo(count($data).' records found.');
1824
            $extraFieldValues = new ExtraFieldValue('skill');
1825
            $em = Database::getManager();
1826
            $repo = $em->getRepository(\Chamilo\CoreBundle\Entity\Skill::class);
1827
            $skillSetList = [];
1828
            $urlId = api_get_current_access_url_id();
1829
1830
            foreach ($data as $row) {
1831
                $skill = $repo->findOneBy(['shortCode' => $row['Code']]);
1832
                $new = false;
1833
                if ($skill === null) {
1834
                    $new = true;
1835
                    $skill = new \Chamilo\CoreBundle\Entity\Skill();
1836
                    $skill
1837
                        ->setShortCode($row['Code'])
1838
                        ->setDescription('')
1839
                        ->setAccessUrlId($urlId)
1840
                        ->setIcon('')
1841
                        ->setStatus(1)
1842
                    ;
1843
                }
1844
1845
                $skill
1846
                    ->setName($row['Tekst'])
1847
                    ->setUpdatedAt(new DateTime())
1848
                ;
1849
                $em->persist($skill);
1850
                $em->flush();
1851
1852
                if ($new) {
1853
                    $skillRelSkill = (new \Chamilo\CoreBundle\Entity\SkillRelSkill())
1854
                        ->setRelationType(0)
1855
                        ->setParentId(0)
1856
                        ->setLevel(0)
1857
                        ->setSkillId($skill->getId())
1858
                    ;
1859
                    $em->persist($skillRelSkill);
1860
                    $em->flush();
1861
                }
1862
1863
                /*
1864
                $params = [
1865
                    'item_id' => $skill->getId(),
1866
                    'variable' => 'skillset',
1867
                    'value' => $row['SkillsetID'],
1868
                ];
1869
                $extraFieldValues->save($params);*/
1870
                $skillSetList[$row['SkillsetID']][] = $skill->getId();                
1871
            }
1872
1873
            //$courseRelSkills = [];
1874
            foreach ($skillSetList as $skillSetId => $skillList) {
1875
                $skillList = array_unique($skillList);
1876
                if (empty($skillList)) {
1877
                    continue;
1878
                }
1879
1880
                $sql = "SELECT id FROM course WHERE code LIKE '%$skillSetId' ";
1881
                $result = Database::query($sql);
1882
                while ($row = Database::fetch_array($result, 'ASSOC')) {
1883
                    $courseId = $row['id'];
1884
                    //$courseRelSkills[$courseId] = $skillList;
1885
                    Skill::saveSkillsToCourse($skillList, $courseId, null);
1886
                }
1887
            }
1888
        }
1889
    }
1890
1891
    /**
1892
     * @param string $file
1893
     * @param bool   $moveFile
1894
     * @param array  $teacherBackup
1895
     * @param array  $groupBackup
1896
     */
1897
    private function importCourses(
1898
        $file,
1899
        $moveFile = true,
1900
        &$teacherBackup = [],
1901
        &$groupBackup = []
1902
    ) {
1903
        $this->fixCSVFile($file);
1904
        $data = Import::csvToArray($file);
1905
1906
        if (!empty($data)) {
1907
            $this->logger->addInfo(count($data)." records found.");
1908
1909
            foreach ($data as $row) {
1910
                $row = $this->cleanCourseRow($row);
1911
                $courseId = CourseManager::get_course_id_from_original_id(
1912
                    $row['extra_'.$this->extraFieldIdNameList['course']],
1913
                    $this->extraFieldIdNameList['course']
1914
                );
1915
1916
                $courseInfo = api_get_course_info_by_id($courseId);
1917
1918
                if (empty($courseInfo)) {
1919
                    // Create
1920
                    $params = [];
1921
                    $params['title'] = $row['title'];
1922
                    $params['exemplary_content'] = false;
1923
                    $params['wanted_code'] = $row['course_code'];
1924
                    $params['course_category'] = $row['course_category'];
1925
                    $params['course_language'] = $row['language'];
1926
                    $params['teachers'] = $row['teachers'];
1927
                    $params['visibility'] = $row['visibility'];
1928
1929
                    $courseInfo = CourseManager::create_course(
1930
                        $params,
1931
                        $this->defaultAdminId
1932
                    );
1933
1934
                    if (!empty($courseInfo)) {
1935
                        CourseManager::update_course_extra_field_value(
1936
                            $courseInfo['code'],
1937
                            'external_course_id',
1938
                            $row['extra_'.$this->extraFieldIdNameList['course']]
1939
                        );
1940
1941
                        CourseManager::update_course_extra_field_value(
1942
                            $courseInfo['code'],
1943
                            'skillset',
1944
                            $row['extra_courseskillset']
1945
                        );
1946
1947
                        $this->logger->addInfo("Courses - Course created ".$courseInfo['code']);
1948
                    } else {
1949
                        $this->logger->addError("Courses - Can't create course:".$row['title']);
1950
                    }
1951
                } else {
1952
                    // Update
1953
                    $params = [
1954
                        'title' => $row['title'],
1955
                        'category_code' => $row['course_category'],
1956
                        'visibility' => $row['visibility'],
1957
                    ];
1958
1959
                    $result = CourseManager::update_attributes(
1960
                        $courseInfo['real_id'],
1961
                        $params
1962
                    );
1963
1964
                    $addTeacherToSession = isset($courseInfo['add_teachers_to_sessions_courses']) && !empty($courseInfo['add_teachers_to_sessions_courses']) ? true : false;
1965
1966
                    $teachers = $row['teachers'];
1967
                    if (!is_array($teachers)) {
1968
                        $teachers = [$teachers];
1969
                    }
1970
1971
                    if ($addTeacherToSession) {
1972
                        $this->logger->addInfo("Add teacher to all course sessions");
1973
                        CourseManager::updateTeachers(
1974
                            $courseInfo,
1975
                            $row['teachers'],
1976
                            false,
1977
                            true,
1978
                            false,
1979
                            $teacherBackup,
1980
                            $this->logger
1981
                        );
1982
                    } else {
1983
                        CourseManager::updateTeachers(
1984
                            $courseInfo,
1985
                            $row['teachers'],
1986
                            true,
1987
                            false,
1988
                            false,
1989
                            $teacherBackup,
1990
                            $this->logger
1991
                        );
1992
                    }
1993
1994
                    CourseManager::update_course_extra_field_value(
1995
                        $courseInfo['code'],
1996
                        'skillset',
1997
                        $row['extra_courseskillset']
1998
                    );
1999
2000
                    foreach ($teachers as $teacherId) {
2001
                        if (isset($groupBackup['tutor'][$teacherId]) &&
2002
                            isset($groupBackup['tutor'][$teacherId][$courseInfo['code']])
2003
                        ) {
2004
                            foreach ($groupBackup['tutor'][$teacherId][$courseInfo['code']] as $data) {
2005
                                $groupInfo = GroupManager::get_group_properties($data['group_id']);
2006
                                GroupManager::subscribe_tutors(
2007
                                    [$teacherId],
2008
                                    $groupInfo,
2009
                                    $data['c_id']
2010
                                );
2011
                            }
2012
                        }
2013
2014
                        if (isset($groupBackup['user'][$teacherId]) &&
2015
                            isset($groupBackup['user'][$teacherId][$courseInfo['code']]) &&
2016
                            !empty($groupBackup['user'][$teacherId][$courseInfo['code']])
2017
                        ) {
2018
                            foreach ($groupBackup['user'][$teacherId][$courseInfo['code']] as $data) {
2019
                                $groupInfo = GroupManager::get_group_properties($data['group_id']);
2020
                                GroupManager::subscribe_users(
2021
                                    [$teacherId],
2022
                                    $groupInfo,
2023
                                    $data['c_id']
2024
                                );
2025
                            }
2026
                        }
2027
                    }
2028
2029
                    if ($result) {
2030
                        $this->logger->addInfo("Courses - Course updated ".$courseInfo['code']);
2031
                    } else {
2032
                        $this->logger->addError("Courses - Course NOT updated ".$courseInfo['code']);
2033
                    }
2034
                }
2035
            }
2036
        }
2037
2038
        if ($moveFile) {
2039
            $this->moveFile($file);
2040
        }
2041
    }
2042
2043
    /**
2044
     * Parse filename: encora_subsessionsextid-static_31082016.csv.
2045
     *
2046
     * @param string $file
2047
     */
2048
    private function importSubscribeUserToCourseSessionExtStatic($file, $moveFile = true)
2049
    {
2050
        $data = Import::csv_reader($file);
2051
        if (!empty($data)) {
2052
            $this->logger->addInfo(count($data)." records found.");
2053
            $userIdList = [];
2054
            foreach ($data as $row) {
2055
                $chamiloUserName = $row['UserName'];
2056
                $chamiloCourseCode = $row['CourseCode'];
2057
                $externalSessionId = $row['ExtSessionID'];
2058
                $status = $row['Status'];
2059
2060
                $chamiloSessionId = null;
2061
                if (!empty($externalSessionId)) {
2062
                    $chamiloSessionId = SessionManager::getSessionIdFromOriginalId(
2063
                        $externalSessionId,
2064
                        $this->extraFieldIdNameList['session']
2065
                    );
2066
                }
2067
2068
                $sessionInfo = api_get_session_info($chamiloSessionId);
2069
2070
                if (empty($sessionInfo)) {
2071
                    $this->logger->addError('Session does not exists: '.$chamiloSessionId);
2072
                    continue;
2073
                }
2074
2075
                $courseInfo = api_get_course_info($chamiloCourseCode);
2076
                if (empty($courseInfo)) {
2077
                    $this->logger->addError('Course does not exists: '.$courseInfo);
2078
                    continue;
2079
                }
2080
2081
                $userId = UserManager::get_user_id_from_username($chamiloUserName);
2082
2083
                if (empty($userId)) {
2084
                    $this->logger->addError('User does not exists: '.$chamiloUserName);
2085
                    continue;
2086
                }
2087
2088
                switch ($status) {
2089
                    case 'student':
2090
                        SessionManager::subscribe_users_to_session_course(
2091
                            [$userId],
2092
                            $chamiloSessionId,
2093
                            $courseInfo['code']
2094
                        );
2095
                        break;
2096
                    case 'teacher':
2097
                        SessionManager::set_coach_to_course_session(
2098
                            $userId,
2099
                            $chamiloSessionId,
2100
                            $courseInfo['code']
2101
                        );
2102
                        break;
2103
                    case 'drh':
2104
                        $removeAllSessionsFromUser = true;
2105
                        if (in_array($userId, $userIdList)) {
2106
                            $removeAllSessionsFromUser = false;
2107
                        } else {
2108
                            $userIdList[] = $userId;
2109
                        }
2110
2111
                        $userInfo = api_get_user_info($userId);
2112
                        SessionManager::subscribeSessionsToDrh(
2113
                            $userInfo,
2114
                            [$chamiloSessionId],
2115
                            false,
2116
                            $removeAllSessionsFromUser
2117
                        );
2118
                        break;
2119
                }
2120
2121
                $this->logger->addError(
2122
                    "User '$chamiloUserName' was added as '$status' to Session: #$chamiloSessionId - Course: ".$courseInfo['code']
2123
                );
2124
            }
2125
        }
2126
2127
        if ($moveFile) {
2128
            $this->moveFile($file);
2129
        }
2130
    }
2131
2132
    /**
2133
     * @param $file
2134
     * @param bool $moveFile
2135
     */
2136
    private function importUnsubSessionsExtIdStatic($file, $moveFile = true)
2137
    {
2138
        $data = Import::csv_reader($file);
2139
2140
        if (!empty($data)) {
2141
            $this->logger->addInfo(count($data)." records found.");
2142
            foreach ($data as $row) {
2143
                $chamiloUserName = $row['UserName'];
2144
                $chamiloCourseCode = $row['CourseCode'];
2145
                $externalSessionId = $row['ExtSessionID'];
2146
                $dateStop = $row['DateStop'];
2147
2148
                $chamiloSessionId = null;
2149
                if (!empty($externalSessionId)) {
2150
                    $chamiloSessionId = SessionManager::getSessionIdFromOriginalId(
2151
                        $externalSessionId,
2152
                        $this->extraFieldIdNameList['session']
2153
                    );
2154
                }
2155
2156
                $sessionInfo = api_get_session_info($chamiloSessionId);
2157
2158
                if (empty($sessionInfo)) {
2159
                    $this->logger->addError('Session does not exists: '.$chamiloSessionId);
2160
                    continue;
2161
                }
2162
2163
                $courseInfo = api_get_course_info($chamiloCourseCode);
2164
                if (empty($courseInfo)) {
2165
                    $this->logger->addError('Course does not exists: '.$courseInfo);
2166
                    continue;
2167
                }
2168
2169
                $userId = UserManager::get_user_id_from_username($chamiloUserName);
2170
2171
                if (empty($userId)) {
2172
                    $this->logger->addError('User does not exists: '.$chamiloUserName);
2173
                    continue;
2174
                }
2175
2176
                SessionManager::removeUsersFromCourseSession(
2177
                    [$userId],
2178
                    $chamiloSessionId,
2179
                    $courseInfo
2180
                );
2181
2182
                $this->logger->addError(
2183
                    "User '$chamiloUserName' was remove from Session: #$chamiloSessionId - Course: ".$courseInfo['code']
2184
                );
2185
            }
2186
        }
2187
2188
        if ($moveFile) {
2189
            $this->moveFile($file);
2190
        }
2191
    }
2192
2193
    /**
2194
     * @param string $file
2195
     */
2196
    private function importSessionsExtIdStatic($file, $moveFile = true)
2197
    {
2198
        $data = Import::csv_reader($file);
2199
2200
        if (!empty($data)) {
2201
            $this->logger->addInfo(count($data)." records found.");
2202
            foreach ($data as $row) {
2203
                $chamiloUserName = $row['UserName'];
2204
                $chamiloCourseCode = $row['CourseCode'];
2205
                $externalSessionId = $row['ExtSessionID'];
2206
                $type = $row['Type'];
2207
2208
                $chamiloSessionId = null;
2209
                if (!empty($externalSessionId)) {
2210
                    $chamiloSessionId = SessionManager::getSessionIdFromOriginalId(
2211
                        $externalSessionId,
2212
                        $this->extraFieldIdNameList['session']
2213
                    );
2214
                }
2215
2216
                $sessionInfo = api_get_session_info($chamiloSessionId);
2217
2218
                if (empty($sessionInfo)) {
2219
                    $this->logger->addError('Session does not exists: '.$chamiloSessionId);
2220
                    continue;
2221
                }
2222
2223
                $courseInfo = api_get_course_info($chamiloCourseCode);
2224
                if (empty($courseInfo)) {
2225
                    $this->logger->addError('Course does not exists: '.$courseInfo);
2226
                    continue;
2227
                }
2228
2229
                $userId = UserManager::get_user_id_from_username($chamiloUserName);
2230
2231
                if (empty($userId)) {
2232
                    $this->logger->addError('User does not exists: '.$chamiloUserName);
2233
                    continue;
2234
                }
2235
                switch ($type) {
2236
                    case 'student':
2237
                        SessionManager::subscribe_users_to_session_course(
2238
                            [$userId],
2239
                            $chamiloSessionId,
2240
                            $courseInfo['code'],
2241
                            null,
2242
                            false
2243
                        );
2244
                        break;
2245
                    case 'teacher':
2246
                        SessionManager::set_coach_to_course_session(
2247
                            $userId,
2248
                            $chamiloSessionId,
2249
                            $courseInfo['code']
2250
                        );
2251
                        break;
2252
                }
2253
2254
                $this->logger->addError(
2255
                    "User '$chamiloUserName' with status $type was added to session: #$chamiloSessionId - Course: ".$courseInfo['code']
2256
                );
2257
            }
2258
        }
2259
2260
        if ($moveFile) {
2261
            $this->moveFile($file);
2262
        }
2263
    }
2264
2265
    /**
2266
     * Updates the session synchronize with the csv file.
2267
     *
2268
     * @param bool   $moveFile
2269
     * @param string $file
2270
     */
2271
    private function importSessionsStatic($file, $moveFile = true)
2272
    {
2273
        $content = file($file);
2274
        $sessions = [];
2275
        $tag_names = [];
2276
2277
        foreach ($content as $key => $enreg) {
2278
            $enreg = explode(';', trim($enreg));
2279
            if ($key) {
2280
                foreach ($tag_names as $tag_key => $tag_name) {
2281
                    if (isset($enreg[$tag_key])) {
2282
                        $sessions[$key - 1][$tag_name] = $enreg[$tag_key];
2283
                    }
2284
                }
2285
            } else {
2286
                foreach ($enreg as $tag_name) {
2287
                    $tag_names[] = api_preg_replace(
2288
                        '/[^a-zA-Z0-9_\-]/',
2289
                        '',
2290
                        $tag_name
2291
                    );
2292
                }
2293
                if (!in_array('SessionName', $tag_names) ||
2294
                    !in_array('DateStart', $tag_names) || !in_array('DateEnd', $tag_names)
2295
                ) {
2296
                    $error_message = get_lang('NoNeededData');
2297
                    break;
2298
                }
2299
            }
2300
        }
2301
2302
        if (!empty($sessions)) {
2303
            // Looping the sessions.
2304
            foreach ($sessions as $session) {
2305
                if (!empty($session['SessionID'])) {
2306
                    $sessionId = SessionManager::getSessionIdFromOriginalId(
2307
                        $session['SessionID'],
2308
                        $this->extraFieldIdNameList['session']
2309
                    );
2310
2311
                    $coachUserName = isset($session['Coach']) ? $session['Coach'] : null;
2312
                    $categoryId = isset($session['category_id']) ? $session['category_id'] : null;
2313
2314
                    // 2014-06-30
2315
                    $dateStart = explode('/', $session['DateStart']);
2316
                    $dateEnd = explode('/', $session['DateEnd']);
2317
                    $visibility = $this->defaultSessionVisibility;
2318
2319
                    $coachId = null;
2320
                    if (!empty($coachUserName)) {
2321
                        $coachInfo = api_get_user_info_from_username($coachUserName);
2322
                        $coachId = $coachInfo['user_id'];
2323
                    }
2324
2325
                    $dateStart = $dateStart[0].'-'.$dateStart[1].'-'.$dateStart[2].' 00:00:00';
2326
                    $dateEnd = $dateEnd[0].'-'.$dateEnd[1].'-'.$dateEnd[2].' 23:59:59';
2327
2328
                    $date = new \DateTime($dateStart);
2329
                    $interval = new DateInterval('P'.$this->daysCoachAccessBeforeBeginning.'D');
2330
                    $date->sub($interval);
2331
                    $coachBefore = $date->format('Y-m-d h:i');
2332
2333
                    $date = new \DateTime($dateEnd);
2334
                    $interval = new DateInterval('P'.$this->daysCoachAccessAfterBeginning.'D');
2335
                    $date->add($interval);
2336
                    $coachAfter = $date->format('Y-m-d h:i');
2337
2338
                    /*$dateStart = api_get_utc_datetime($dateStart);
2339
                    $dateEnd = api_get_utc_datetime($dateEnd);
2340
                    $coachBefore = api_get_utc_datetime($coachBefore);
2341
                    $coachAfter = api_get_utc_datetime($coachAfter);*/
2342
2343
                    if (empty($sessionId)) {
2344
                        $result = SessionManager::create_session(
2345
                            $session['SessionName'],
2346
                            $dateStart,
2347
                            $dateEnd,
2348
                            $dateStart,
2349
                            $dateEnd,
2350
                            $coachBefore,
2351
                            $coachAfter,
2352
                            $coachId,
2353
                            $categoryId,
2354
                            $visibility
2355
                        );
2356
2357
                        if (is_numeric($result)) {
2358
                            $sessionId = $result;
2359
                            $this->logger->addInfo("Session #$sessionId created: ".$session['SessionName']);
2360
                            SessionManager::update_session_extra_field_value(
2361
                                $sessionId,
2362
                                $this->extraFieldIdNameList['session'],
2363
                                $session['SessionID']
2364
                            );
2365
                        } else {
2366
                            $this->logger->addInfo("Failed creating session: ".$session['SessionName']);
2367
                        }
2368
                    } else {
2369
                        $sessionInfo = api_get_session_info($sessionId);
2370
                        $accessBefore = null;
2371
                        $accessAfter = null;
2372
2373
                        if (empty($sessionInfo['nb_days_access_before_beginning']) ||
2374
                            (!empty($sessionInfo['nb_days_access_before_beginning']) &&
2375
                                $sessionInfo['nb_days_access_before_beginning'] < $this->daysCoachAccessBeforeBeginning)
2376
                        ) {
2377
                            $accessBefore = $coachBefore;
2378
                        }
2379
2380
                        $accessAfter = null;
2381
                        if (empty($sessionInfo['nb_days_access_after_end']) ||
2382
                            (!empty($sessionInfo['nb_days_access_after_end']) &&
2383
                                $sessionInfo['nb_days_access_after_end'] < $this->daysCoachAccessAfterBeginning)
2384
                        ) {
2385
                            $accessAfter = $coachAfter;
2386
                        }
2387
2388
                        $showDescription = isset($sessionInfo['show_description']) ? $sessionInfo['show_description'] : 1;
2389
2390
                        $result = SessionManager::edit_session(
2391
                            $sessionId,
2392
                            $session['SessionName'],
2393
                            $dateStart,
2394
                            $dateEnd,
2395
                            $dateStart,
2396
                            $dateEnd,
2397
                            $accessBefore,
2398
                            $accessAfter,
2399
                            $coachId,
2400
                            $categoryId,
2401
                            $visibility,
2402
                            null, //$description = null,
2403
                            $showDescription
2404
                        );
2405
2406
                        if (is_numeric($result)) {
2407
                            $this->logger->addInfo("Session #$sessionId updated: ".$session['SessionName']);
2408
                            $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2409
                            $params = [
2410
                                'description' => $session['SessionDescription'],
2411
                            ];
2412
                            Database::update(
2413
                                $tbl_session,
2414
                                $params,
2415
                                ['id = ?' => $sessionId]
2416
                            );
2417
                        }
2418
                    }
2419
2420
                    if (!empty($sessionId)) {
2421
                        // Courses
2422
                        $courses = explode('|', $session['Courses']);
2423
                        $courseList = [];
2424
                        $courseListWithCoach = [];
2425
                        foreach ($courses as $course) {
2426
                            $courseArray = bracketsToArray($course);
2427
                            $courseCode = $courseArray[0];
2428
                            if (CourseManager::course_exists($courseCode)) {
2429
                                $courseInfo = api_get_course_info($courseCode);
2430
                                $courseList[] = $courseInfo['real_id'];
2431
                                // Extracting course coaches
2432
                                $courseCoaches = isset($courseArray[1]) ? $courseArray[1] : null;
2433
                                $courseCoaches = explode(',', $courseCoaches);
2434
2435
                                // Extracting students
2436
                                $courseUsers = isset($courseArray[2]) ? $courseArray[2] : null;
2437
                                $courseUsers = explode(',', $courseUsers);
2438
2439
                                $courseListWithCoach[] = [
2440
                                    'course_info' => $courseInfo,
2441
                                    'coaches' => $courseCoaches,
2442
                                    'course_users' => $courseUsers,
2443
                                ];
2444
                            }
2445
                        }
2446
2447
                        SessionManager::add_courses_to_session(
2448
                            $sessionId,
2449
                            $courseList,
2450
                            true
2451
                        );
2452
2453
                        $this->logger->addInfo("Session #$sessionId: Courses added: '".implode(', ', $courseList)."'");
2454
2455
                        if (empty($courseListWithCoach)) {
2456
                            $this->logger->addInfo("No users/coaches to update");
2457
                            continue;
2458
                        }
2459
2460
                        foreach ($courseListWithCoach as $courseData) {
2461
                            $courseInfo = $courseData['course_info'];
2462
                            $courseCode = $courseInfo['code'];
2463
                            $courseId = $courseInfo['real_id'];
2464
                            $courseCoaches = $courseData['coaches'];
2465
                            $courseUsers = $courseData['course_users'];
2466
2467
                            // Coaches
2468
                            if (!empty($courseCoaches)) {
2469
                                $coachList = [];
2470
                                foreach ($courseCoaches as $courseCoach) {
2471
                                    $courseCoachId = UserManager::get_user_id_from_username(
2472
                                        $courseCoach
2473
                                    );
2474
                                    if ($courseCoachId !== false) {
2475
                                        // Just insert new coaches
2476
                                        $coachList[] = $courseCoachId;
2477
                                    }
2478
                                }
2479
2480
                                $this->logger->addInfo("Session #$sessionId: course '$courseCode' coaches added: '".implode(', ', $coachList)."'");
2481
2482
                                SessionManager::updateCoaches(
2483
                                    $sessionId,
2484
                                    $courseId,
2485
                                    $coachList,
2486
                                    true
2487
                                );
2488
                            } else {
2489
                                $this->logger->addInfo("No coaches added");
2490
                            }
2491
2492
                            // Students
2493
                            if (!empty($courseUsers)) {
2494
                                $userList = [];
2495
                                foreach ($courseUsers as $username) {
2496
                                    $userInfo = api_get_user_info_from_username(trim($username));
2497
                                    if (!empty($userInfo)) {
2498
                                        $userList[] = $userInfo['user_id'];
2499
                                    }
2500
                                }
2501
2502
                                $this->logger->addInfo("Session #$sessionId: course '$courseCode': Students added '".implode(', ', $userList)."'");
2503
                                SessionManager::subscribe_users_to_session_course(
2504
                                    $userList,
2505
                                    $sessionId,
2506
                                    $courseCode,
2507
                                    SESSION_VISIBLE_READ_ONLY,
2508
                                    true
2509
                                );
2510
                            } else {
2511
                                $this->logger->addInfo("No users to register.");
2512
                            }
2513
                        }
2514
                    } else {
2515
                        $this->logger->addInfo(
2516
                            'SessionID not found in system.'
2517
                        );
2518
                    }
2519
                } else {
2520
                    $this->logger->addInfo('SessionID does not exists');
2521
                }
2522
            }
2523
        } else {
2524
            $this->logger->addInfo($error_message);
2525
        }
2526
2527
        if ($moveFile) {
2528
            $this->moveFile($file);
2529
        }
2530
    }
2531
2532
    /**
2533
     * @param $file
2534
     * @param bool  $moveFile
2535
     * @param array $teacherBackup
2536
     * @param array $groupBackup
2537
     */
2538
    private function importOpenSessions(
2539
        $file,
2540
        $moveFile = true,
2541
        &$teacherBackup = [],
2542
        &$groupBackup = []
2543
    ) {
2544
        $this->importSessions($file, $moveFile, $teacherBackup, $groupBackup);
2545
    }
2546
2547
    private function importSessionsUsersCareers(
2548
        $file,
2549
        $moveFile = false,
2550
        &$teacherBackup = [],
2551
        &$groupBackup = []
2552
    ) {
2553
        $data = Import::csvToArray($file);
2554
        if (!empty($data)) {
2555
            $extraFieldValueCareer = new ExtraFieldValue('career');
2556
            $sessionExtraFieldValue = new ExtraFieldValue('session');
2557
            $career = new Career();
2558
2559
            $this->logger->addInfo(count($data)." records found.");
2560
            foreach ($data as $row) {
2561
                $users = $row['Users'];
2562
                if (empty($users)) {
2563
                    $this->logger->addError('No users found');
2564
                    continue;
2565
                }
2566
2567
                $users = explode('|', $users);
2568
                $careerList = str_replace(['[', ']'], '', $row['extra_careerid']);
2569
                $careerList = explode(',', $careerList);
2570
2571
                $finalCareerIdList = [];
2572
                $careerListValidated = [];
2573
                foreach ($careerList as $careerId) {
2574
                    $realCareerIdList = $extraFieldValueCareer->get_item_id_from_field_variable_and_field_value(
2575
                        'external_career_id',
2576
                        $careerId
2577
                    );
2578
                    if (isset($realCareerIdList['item_id'])) {
2579
                        $careerListValidated[] = $careerId;
2580
                        $finalCareerIdList[] = $realCareerIdList['item_id'];
2581
                    }
2582
                }
2583
2584
                if (empty($finalCareerIdList)) {
2585
                    $this->logger->addError('Careers not found: '.print_r($finalCareerIdList, 1));
2586
                    continue;
2587
                }
2588
2589
                //$chamiloSessionId = $row['SessionID'];
2590
2591
                $chamiloSessionId = SessionManager::getSessionIdFromOriginalId(
2592
                    $row['SessionID'],
2593
                    $this->extraFieldIdNameList['session']
2594
                );
2595
2596
                $sessionInfo = api_get_session_info($chamiloSessionId);
2597
2598
                if (empty($sessionInfo)) {
2599
                    $this->logger->addError('Session does not exists: '.$chamiloSessionId);
2600
                    continue;
2601
                } else {
2602
                    $this->logger->addInfo("Session id: ".$sessionInfo['id']);
2603
                }
2604
2605
                $sessionId = $sessionInfo['id'];
2606
2607
                // Add career to session.
2608
                $externalCareerIdList = $sessionExtraFieldValue->get_values_by_handler_and_field_variable(
2609
                    $sessionId,
2610
                    'careerid'
2611
                );
2612
2613
                if (empty($externalCareerIdList) ||
2614
                    (isset($externalCareerIdList['value']) && empty($externalCareerIdList['value']))
2615
                ) {
2616
                    $careerItem = '['.implode(',', $careerListValidated).']';
2617
                    $params = ['item_id' => $sessionId, 'extra_careerid' => $careerItem];
2618
                    $this->logger->addInfo("Saving career: $careerItem to session: $sessionId");
2619
                    $sessionExtraFieldValue->saveFieldValues($params, true);
2620
                } else {
2621
                    /*foreach ($finalCareerIdList as $careerId) {
2622
                        if (empty($externalCareerIdList)) {
2623
                            $params = ['item_id' => $sessionId, 'extra_careerid' => $careerId];
2624
                            $sessionExtraFieldValue->saveFieldValues($params, true);
2625
                        }
2626
                    }*/
2627
                }
2628
2629
                // Add career to users.
2630
                foreach ($users as $username) {
2631
                    $userInfo = api_get_user_info_from_username($username);
2632
                    if (empty($userInfo)) {
2633
                        $this->logger->addError('username not found: '.$username);
2634
                        continue;
2635
                    }
2636
2637
                    foreach ($finalCareerIdList as $careerId) {
2638
                        $this->logger->addInfo("Adding Career $careerId: To user $username");
2639
                        UserManager::addUserCareer($userInfo['id'], $careerId);
2640
                    }
2641
                }
2642
            }
2643
        }
2644
    }
2645
2646
    /**
2647
     * @param string $file
2648
     * @param bool   $moveFile
2649
     * @param array  $teacherBackup
2650
     * @param array  $groupBackup
2651
     */
2652
    private function importSessions(
2653
        $file,
2654
        $moveFile = true,
2655
        &$teacherBackup = [],
2656
        &$groupBackup = []
2657
    ) {
2658
        $avoid = null;
2659
        if (isset($this->conditions['importSessions']) &&
2660
            isset($this->conditions['importSessions']['update'])
2661
        ) {
2662
            $avoid = $this->conditions['importSessions']['update'];
2663
        }
2664
        $result = SessionManager::importCSV(
2665
            $file,
2666
            true,
2667
            $this->defaultAdminId,
2668
            $this->logger,
2669
            [
2670
                'SessionID' => 'extra_'.$this->extraFieldIdNameList['session'],
2671
                'CareerId' => 'extra_'.$this->extraFieldIdNameList['session_career'],
2672
            ],
2673
            $this->extraFieldIdNameList['session'],
2674
            $this->daysCoachAccessBeforeBeginning,
2675
            $this->daysCoachAccessAfterBeginning,
2676
            $this->defaultSessionVisibility,
2677
            $avoid,
2678
            false, // deleteUsersNotInList
2679
            false, // updateCourseCoaches
2680
            true, // sessionWithCoursesModifier
2681
            true, //$addOriginalCourseTeachersAsCourseSessionCoaches
2682
            false, //$removeAllTeachersFromCourse
2683
            1, // $showDescription,
2684
            $teacherBackup,
2685
            $groupBackup
2686
        );
2687
2688
        if (!empty($result['error_message'])) {
2689
            $this->logger->addError($result['error_message']);
2690
        }
2691
        $this->logger->addInfo("Sessions - Sessions parsed: ".$result['session_counter']);
2692
2693
        if ($moveFile) {
2694
            $this->moveFile($file);
2695
        }
2696
    }
2697
2698
    /**
2699
     * @param string $file
2700
     * @param bool   $moveFile
2701
     */
2702
    private function importSubscribeStatic($file, $moveFile = true)
2703
    {
2704
        $data = Import::csv_reader($file);
2705
2706
        if (!empty($data)) {
2707
            $this->logger->addInfo(count($data)." records found.");
2708
            foreach ($data as $row) {
2709
                $chamiloUserName = $row['UserName'];
2710
                $chamiloCourseCode = $row['CourseCode'];
2711
                $chamiloSessionId = $row['SessionID'];
2712
                $type = $row['Type'];
2713
2714
                $sessionInfo = api_get_session_info($chamiloSessionId);
2715
2716
                if (empty($sessionInfo)) {
2717
                    $this->logger->addError('Session does not exists: '.$chamiloSessionId);
2718
                    continue;
2719
                }
2720
2721
                $courseInfo = api_get_course_info($chamiloCourseCode);
2722
                if (empty($courseInfo)) {
2723
                    $this->logger->addError('Course does not exists: '.$courseInfo);
2724
                    continue;
2725
                }
2726
2727
                $userId = UserManager::get_user_id_from_username($chamiloUserName);
2728
2729
                if (empty($userId)) {
2730
                    $this->logger->addError('User does not exists: '.$chamiloUserName);
2731
                    continue;
2732
                }
2733
2734
                switch ($type) {
2735
                    case 'student':
2736
                        SessionManager::subscribe_users_to_session_course(
2737
                            [$userId],
2738
                            $chamiloSessionId,
2739
                            $courseInfo['code'],
2740
                            null,
2741
                            false
2742
                        );
2743
                        break;
2744
                    case 'teacher':
2745
                        SessionManager::set_coach_to_course_session(
2746
                            $userId,
2747
                            $chamiloSessionId,
2748
                            $courseInfo['real_id']
2749
                        );
2750
                        break;
2751
                }
2752
2753
                $this->logger->addError(
2754
                    "User '$chamiloUserName' with status $type was added to session: #$chamiloSessionId - Course: ".$courseInfo['code']
2755
                );
2756
            }
2757
        }
2758
2759
        if ($moveFile) {
2760
            $this->moveFile($file);
2761
        }
2762
    }
2763
2764
    /**
2765
     * @param $file
2766
     * @param bool $moveFile
2767
     */
2768
    private function importSubscribeUserToCourse($file, $moveFile = false, &$teacherBackup = [])
2769
    {
2770
        $data = Import::csv_reader($file);
2771
2772
        if (!empty($data)) {
2773
            $this->logger->addInfo(count($data)." records found.");
2774
            foreach ($data as $row) {
2775
                $chamiloUserName = $row['UserName'];
2776
                $chamiloCourseCode = $row['CourseCode'];
2777
                $status = $row['Status'];
2778
2779
                $courseInfo = api_get_course_info($chamiloCourseCode);
2780
2781
                if (empty($courseInfo)) {
2782
                    $this->logger->addError(
2783
                        'Course does not exists: '.$chamiloCourseCode
2784
                    );
2785
                    continue;
2786
                }
2787
2788
                $userId = UserManager::get_user_id_from_username(
2789
                    $chamiloUserName
2790
                );
2791
2792
                if (empty($userId)) {
2793
                    $this->logger->addError(
2794
                        'User does not exists: '.$chamiloUserName
2795
                    );
2796
                    continue;
2797
                }
2798
2799
                $userCourseCategory = '';
2800
                if (isset($teacherBackup[$userId]) &&
2801
                    isset($teacherBackup[$userId][$courseInfo['code']])
2802
                ) {
2803
                    $courseUserData = $teacherBackup[$userId][$courseInfo['code']];
2804
                    $userCourseCategory = $courseUserData['user_course_cat'];
2805
                }
2806
2807
                $result = CourseManager::subscribeUser(
2808
                    $userId,
2809
                    $courseInfo['code'],
2810
                    $status,
2811
                    0,
2812
                    $userCourseCategory
2813
                );
2814
2815
                if ($result) {
2816
                    $this->logger->addInfo(
2817
                        "User $userId added to course ".$courseInfo['code']." with status '$status' with course category: '$userCourseCategory'"
2818
                    );
2819
                } else {
2820
                    $this->logger->addInfo(
2821
                        "User $userId was NOT ADDED to course ".$courseInfo['code']." with status '$status' with course category: '$userCourseCategory'"
2822
                    );
2823
                }
2824
            }
2825
        }
2826
2827
        if ($moveFile) {
2828
            $this->moveFile($file);
2829
        }
2830
    }
2831
2832
    /**
2833
     * 23/4/2017 to datetime.
2834
     *
2835
     * @param $string
2836
     *
2837
     * @return mixed
2838
     */
2839
    private function createDateTime($string)
2840
    {
2841
        if (empty($string)) {
2842
            return null;
2843
        }
2844
2845
        $date = DateTime::createFromFormat('j/m/Y', $string);
2846
        if ($date) {
2847
            return $date;
2848
        }
2849
2850
        return null;
2851
    }
2852
2853
    /**
2854
     * @param $file
2855
     * @param bool  $moveFile
2856
     * @param array $teacherBackup
2857
     * @param array $groupBackup
2858
     *
2859
     * @return bool
2860
     */
2861
    private function importCareers(
2862
        $file,
2863
        $moveFile = false,
2864
        &$teacherBackup = [],
2865
        &$groupBackup = []
2866
    ) {
2867
        $data = Import::csv_reader($file);
2868
2869
        if (!empty($data)) {
2870
            $this->logger->addInfo(count($data).' records found.');
2871
            $extraFieldValue = new ExtraFieldValue('career');
2872
            $extraFieldName = $this->extraFieldIdNameList['career'];
2873
            $externalEventId = null;
2874
2875
            $extraField = new ExtraField('career');
2876
            $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable($extraFieldName);
2877
2878
            if (empty($extraFieldInfo)) {
2879
                $this->logger->addInfo("Extra field doesn't exists: $extraFieldName");
2880
2881
                return false;
2882
            }
2883
2884
            foreach ($data as $row) {
2885
                foreach ($row as $key => $value) {
2886
                    $key = (string) trim($key);
2887
                    // Remove utf8 bom
2888
                    $key = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $key);
2889
                    $row[$key] = $value;
2890
                }
2891
2892
                $itemId = $row['CareerId'];
2893
                $item = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
2894
                    $extraFieldName,
2895
                    $itemId,
2896
                    false,
2897
                    false,
2898
                    false
2899
                );
2900
2901
                $career = new Career();
2902
                if (empty($item)) {
2903
                    $params = [
2904
                        'status' => 1,
2905
                        'name' => $row['CareerName'],
2906
                    ];
2907
                    $careerId = $career->save($params);
2908
                    if ($careerId) {
2909
                        $this->logger->addInfo('Career saved: '.print_r($params, 1));
2910
                        $params = [
2911
                            'item_id' => $careerId,
2912
                            'extra_'.$extraFieldName => $itemId,
2913
                        ];
2914
                        $links = isset($row['HLinks']) ? $row['HLinks'] : [];
2915
                        if (!empty($links)) {
2916
                            $extraFieldUrlName = $this->extraFieldIdNameList['career_urls'];
2917
                            $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable(
2918
                                $extraFieldUrlName
2919
                            );
2920
                            if (!empty($extraFieldInfo)) {
2921
                                $params['extra_'.$extraFieldUrlName] = $links;
2922
                            }
2923
                        }
2924
                        $extraFieldValue->saveFieldValues($params);
2925
                    }
2926
                } else {
2927
                    if (isset($item['item_id'])) {
2928
                        $params = [
2929
                            'id' => $item['item_id'],
2930
                            'name' => $row['CareerName'],
2931
                        ];
2932
                        $career->update($params);
2933
                        $this->logger->addInfo('Career updated: '.print_r($params, 1));
2934
                        $links = isset($row['HLinks']) ? $row['HLinks'] : [];
2935
2936
                        if (!empty($links)) {
2937
                            $extraFieldUrlName = $this->extraFieldIdNameList['career_urls'];
2938
                            $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable(
2939
                                $extraFieldUrlName
2940
                            );
2941
                            if (!empty($extraFieldInfo)) {
2942
                                $params = [
2943
                                    'item_id' => $item['item_id'],
2944
                                    'extra_'.$extraFieldName => $itemId,
2945
                                    'extra_'.$extraFieldUrlName => $links,
2946
                                ];
2947
                                $extraFieldValue->saveFieldValues($params);
2948
                            }
2949
                        }
2950
                    }
2951
                }
2952
            }
2953
        }
2954
2955
        if ($moveFile) {
2956
            $this->moveFile($file);
2957
        }
2958
    }
2959
2960
    /**
2961
     * @param $file
2962
     * @param bool  $moveFile
2963
     * @param array $teacherBackup
2964
     * @param array $groupBackup
2965
     */
2966
    private function importCareersResultsRemoveStatic(
2967
        $file,
2968
        $moveFile = false
2969
    ) {
2970
        $data = Import::csv_reader($file);
2971
2972
        $careerIdList = [];
2973
        $userIdList = [];
2974
2975
        if (!empty($data)) {
2976
            $totalCount = count($data);
2977
            $this->logger->addInfo($totalCount.' records found.');
2978
2979
            $extraFieldValue = new ExtraFieldValue('career');
2980
            $extraFieldName = $this->extraFieldIdNameList['career'];
2981
            $rowCounter = 0;
2982
            foreach ($data as $row) {
2983
                $this->logger->addInfo("---------- Row: # $rowCounter");
2984
                $rowCounter++;
2985
                if (empty($row)) {
2986
                    continue;
2987
                }
2988
2989
                foreach ($row as $key => $value) {
2990
                    $key = (string) trim($key);
2991
                    // Remove utf8 bom
2992
                    $key = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $key);
2993
                    $row[$key] = $value;
2994
                }
2995
2996
                $rowStudentId = $row['StudentId'];
2997
2998
                if (isset($userIdList[$rowStudentId])) {
2999
                    $studentId = $userIdList[$rowStudentId];
3000
                } else {
3001
                    $studentId = UserManager::get_user_id_from_original_id(
3002
                        $rowStudentId,
3003
                        $this->extraFieldIdNameList['user']
3004
                    );
3005
                    $userIdList[$rowStudentId] = $studentId;
3006
                }
3007
3008
                $careerId = $row['CareerId'];
3009
                if (isset($careerIdList[$careerId])) {
3010
                    $careerChamiloId = $careerIdList[$careerId];
3011
                } else {
3012
                    $item = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
3013
                        $extraFieldName,
3014
                        $careerId
3015
                    );
3016
3017
                    if (empty($item)) {
3018
                        $careerIdList[$careerId] = 0;
3019
                        continue;
3020
                    } else {
3021
                        if (isset($item['item_id'])) {
3022
                            $careerChamiloId = $item['item_id'];
3023
                            $careerIdList[$careerId] = $careerChamiloId;
3024
                        } else {
3025
                            $careerIdList[$careerId] = 0;
3026
                            continue;
3027
                        }
3028
                    }
3029
                }
3030
3031
                if (empty($careerChamiloId)) {
3032
                    $this->logger->addInfo("Career not found: $careerId ");
3033
                    continue;
3034
                }
3035
3036
                $userCareerData = UserManager::getUserCareer($studentId, $careerChamiloId);
3037
3038
                if (empty($userCareerData)) {
3039
                    $this->logger->addInfo(
3040
                        "User chamilo id # $studentId (".$row['StudentId'].") has no career #$careerChamiloId (ext #$careerId)"
3041
                    );
3042
                    continue;
3043
                }
3044
3045
                $extraData = isset($userCareerData['extra_data']) && !empty($userCareerData['extra_data']) ? unserialize($userCareerData['extra_data']) : [];
3046
                unset($extraData[$row['CourseId']][$row['ResultId']]);
3047
                $serializedValue = serialize($extraData);
3048
3049
                UserManager::updateUserCareer($userCareerData['id'], $serializedValue);
3050
3051
                $this->logger->addInfo('Deleting: result id'.$row['ResultId']);
3052
                $this->logger->addInfo(
3053
                    "Saving graph for user chamilo # $studentId (".$row['StudentId'].") with career #$careerChamiloId (ext #$careerId)"
3054
                );
3055
            }
3056
        }
3057
3058
        if ($moveFile) {
3059
            $this->moveFile($file);
3060
        }
3061
    }
3062
3063
    /**
3064
     * @param $file
3065
     * @param bool  $moveFile
3066
     * @param array $teacherBackup
3067
     * @param array $groupBackup
3068
     */
3069
    private function importCareersResults(
3070
        $file,
3071
        $moveFile = false,
3072
        &$teacherBackup = [],
3073
        &$groupBackup = []
3074
    ) {
3075
        $data = Import::csv_reader($file);
3076
3077
        $userTable = Database::get_main_table(TABLE_MAIN_USER);
3078
        $careerIdList = [];
3079
        $userIdList = [];
3080
        if (!empty($data)) {
3081
            $totalCount = count($data);
3082
            $this->logger->addInfo($totalCount.' records found.');
3083
3084
            $extraFieldValue = new ExtraFieldValue('career');
3085
            $extraFieldName = $this->extraFieldIdNameList['career'];
3086
            $rowCounter = 0;
3087
            foreach ($data as $row) {
3088
                $this->logger->addInfo("---------- Row: # $rowCounter");
3089
                $rowCounter++;
3090
                if (empty($row)) {
3091
                    continue;
3092
                }
3093
3094
                foreach ($row as $key => $value) {
3095
                    $key = (string) trim($key);
3096
                    // Remove utf8 bom
3097
                    $key = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $key);
3098
                    $row[$key] = $value;
3099
                }
3100
3101
                $rowStudentId = $row['StudentId'];
3102
3103
                if (isset($userIdList[$rowStudentId])) {
3104
                    $studentId = $userIdList[$rowStudentId];
3105
                } else {
3106
                    $studentId = UserManager::get_user_id_from_original_id(
3107
                        $rowStudentId,
3108
                        $this->extraFieldIdNameList['user']
3109
                    );
3110
3111
                    $userIdList[$rowStudentId] = $studentId;
3112
                }
3113
3114
                $careerId = $row['CareerId'];
3115
                if (isset($careerIdList[$careerId])) {
3116
                    $careerChamiloId = $careerIdList[$careerId];
3117
                } else {
3118
                    $item = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
3119
                        $extraFieldName,
3120
                        $careerId
3121
                    );
3122
3123
                    if (empty($item)) {
3124
                        //$this->logger->addInfo("Career not found: $careerId case 1");
3125
                        $careerIdList[$careerId] = 0;
3126
                        continue;
3127
                    } else {
3128
                        if (isset($item['item_id'])) {
3129
                            $careerChamiloId = $item['item_id'];
3130
                            $careerIdList[$careerId] = $careerChamiloId;
3131
                        } else {
3132
                            $careerIdList[$careerId] = 0;
3133
                            //$this->logger->addInfo("Career not found: $careerId case 2");
3134
                            continue;
3135
                        }
3136
                    }
3137
                }
3138
3139
                if (empty($careerChamiloId)) {
3140
                    $this->logger->addInfo("Career not found: $careerId ");
3141
                    continue;
3142
                }
3143
3144
                $userCareerData = UserManager::getUserCareer($studentId, $careerChamiloId);
3145
3146
                if (empty($userCareerData)) {
3147
                    $this->logger->addInfo(
3148
                        "User chamilo id # $studentId (".$row['StudentId'].") has no career #$careerChamiloId (ext #$careerId)"
3149
                    );
3150
                    continue;
3151
                }
3152
3153
                $extraData = isset($userCareerData['extra_data']) && !empty($userCareerData['extra_data']) ? unserialize($userCareerData['extra_data']) : [];
3154
3155
                $sql = "SELECT firstname, lastname FROM $userTable
3156
                        WHERE username='".Database::escape_string($row['TeacherUsername'])."'";
3157
                $result = Database::query($sql);
3158
3159
                $teacherName = $row['TeacherUsername'];
3160
                if (Database::num_rows($result)) {
3161
                    $teacherInfo = Database::fetch_array($result);
3162
                    $teacherName = $teacherInfo['firstname'].' '.$teacherInfo['lastname'];
3163
                }
3164
3165
                $extraData[$row['CourseId']][$row['ResultId']] = [
3166
                    'Description' => $row['Description'],
3167
                    'Period' => $row['Period'],
3168
                    'TeacherText' => $row['TeacherText'],
3169
                    'TeacherUsername' => $teacherName,
3170
                    'ScoreText' => $row['ScoreText'],
3171
                    'ScoreValue' => $row['ScoreValue'],
3172
                    'Info' => $row['Info'],
3173
                    'BgColor' => $row['BgColor'],
3174
                    'Color' => $row['Color'],
3175
                    'BorderColor' => $row['BorderColor'],
3176
                    'Icon' => $row['Icon'],
3177
                    'IconColor' => $row['IconColor'],
3178
                    'SortDate' => $row['SortDate'] ?? '',
3179
                ];
3180
                $serializedValue = serialize($extraData);
3181
3182
                UserManager::updateUserCareer($userCareerData['id'], $serializedValue);
3183
3184
                $this->logger->addInfo(
3185
                    "Saving graph for user chamilo # $studentId (".$row['StudentId'].") with career #$careerChamiloId (ext #$careerId)"
3186
                );
3187
            }
3188
        }
3189
3190
        if ($moveFile) {
3191
            $this->moveFile($file);
3192
        }
3193
    }
3194
3195
    /**
3196
     * @param $file
3197
     * @param bool  $moveFile
3198
     * @param array $teacherBackup
3199
     * @param array $groupBackup
3200
     */
3201
    private function importCareersDiagram(
3202
        $file,
3203
        $moveFile = false,
3204
        &$teacherBackup = [],
3205
        &$groupBackup = []
3206
    ) {
3207
        $data = Import::csv_reader($file);
3208
3209
        $extraFieldValue = new ExtraFieldValue('career');
3210
        $extraFieldName = $this->extraFieldIdNameList['career'];
3211
3212
        $extraField = new ExtraField('career');
3213
        $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable($extraFieldName);
3214
3215
        $careerDiagramExtraFieldName = $this->extraFieldIdNameList['career_diagram'];
3216
        $extraFieldDiagramInfo = $extraField->get_handler_field_info_by_field_variable(
3217
            $careerDiagramExtraFieldName
3218
        );
3219
3220
        if (empty($extraFieldInfo) || empty($extraFieldDiagramInfo)) {
3221
            return false;
3222
        }
3223
3224
        if (!empty($data)) {
3225
            $this->logger->addInfo(count($data).' records found.');
3226
            $values = [];
3227
            foreach ($data as $row) {
3228
                if (empty($row)) {
3229
                    continue;
3230
                }
3231
                foreach ($row as $key => $value) {
3232
                    $key = (string) trim($key);
3233
                    // Remove utf8 bom
3234
                    $key = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $key);
3235
                    $row[$key] = $value;
3236
                }
3237
                $values[$row['Column']][] = $row;
3238
            }
3239
3240
            $careerList = [];
3241
            $careerNameList = [];
3242
            ksort($values);
3243
            $careerChamiloIdList = [];
3244
            // 1. First create all items
3245
            foreach ($values as $column => $rowList) {
3246
                foreach ($rowList as $row) {
3247
                    $careerId = $row['CareerId'];
3248
                    $item = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
3249
                        $extraFieldName,
3250
                        $careerId,
3251
                        false,
3252
                        false,
3253
                        false
3254
                    );
3255
3256
                    if (empty($item)) {
3257
                        $this->logger->addInfo("Career not found: $careerId");
3258
                        continue;
3259
                    } else {
3260
                        if (isset($item['item_id'])) {
3261
                            $careerChamiloId = $item['item_id'];
3262
                            $career = new Career();
3263
                            $career = $career->find($careerChamiloId);
3264
                            $chamiloCareerName = $career['name'];
3265
                            $careerNameList[$careerId] = $chamiloCareerName;
3266
                            $careerChamiloIdList[$careerId] = $careerChamiloId;
3267
                        } else {
3268
                            continue;
3269
                        }
3270
                    }
3271
3272
                    if (empty($chamiloCareerName)) {
3273
                        $this->logger->addInfo("Career not found: $careerId");
3274
                        continue;
3275
                    }
3276
3277
                    if (isset($careerList[$careerId])) {
3278
                        $graph = $careerList[$careerId];
3279
                    } else {
3280
                        $graph = new Graph($careerId);
3281
                        $graph->setAttribute('graphviz.graph.rankdir', 'LR');
3282
                        $careerList[$careerId] = $graph;
3283
                    }
3284
3285
                    $currentCourseId = $row['CourseId'];
3286
                    $name = $row['CourseName'];
3287
                    $notes = $row['Notes'];
3288
                    $groupValue = $row['Group'];
3289
                    $boxColumn = $row['Column'];
3290
                    $rowValue = $row['Row'];
3291
                    $color = isset($row['DefinedColor']) ? $row['DefinedColor'] : '';
3292
                    $arrow = isset($row['DrawArrowFrom']) ? $row['DrawArrowFrom'] : '';
3293
                    $subGroup = isset($row['SubGroup']) ? $row['SubGroup'] : '';
3294
                    $connections = isset($row['Connections']) ? $row['Connections'] : '';
3295
                    $linkedElement = isset($row['LinkedElement']) ? $row['LinkedElement'] : '';
3296
3297
                    if ($graph->hasVertex($currentCourseId)) {
3298
                        // Avoid double insertion
3299
                        continue;
3300
                    } else {
3301
                        $current = $graph->createVertex($currentCourseId);
3302
                        $current->setAttribute('graphviz.label', $name);
3303
                        $current->setAttribute('DefinedColor', $color);
3304
                        $current->setAttribute('Notes', $notes);
3305
                        $current->setAttribute('Row', $rowValue);
3306
                        $current->setAttribute('Group', $groupValue);
3307
                        $current->setAttribute('Column', $boxColumn);
3308
                        $current->setAttribute('DrawArrowFrom', $arrow);
3309
                        $current->setAttribute('SubGroup', $subGroup);
3310
                        $current->setAttribute('Connections', $connections);
3311
                        $current->setAttribute('LinkedElement', $linkedElement);
3312
                        $current->setAttribute('graphviz.shape', 'box');
3313
                        $current->setGroup($column);
3314
                    }
3315
                }
3316
            }
3317
3318
            // 2. Create connections
3319
            // $column start with 1 (depending in Column row)
3320
            foreach ($values as $column => $rowList) {
3321
                foreach ($rowList as $row) {
3322
                    $careerId = $row['CareerId'];
3323
                    if (isset($careerList[$careerId])) {
3324
                        $graph = $careerList[$careerId];
3325
                    } else {
3326
                        continue;
3327
                    }
3328
3329
                    $currentCourseId = $row['CourseId'];
3330
                    if ($graph->hasVertex($currentCourseId)) {
3331
                        $current = $graph->getVertex($currentCourseId);
3332
                    } else {
3333
                        continue;
3334
                    }
3335
3336
                    if (isset($row['DependedOn']) && !empty($row['DependedOn'])) {
3337
                        $parentList = explode(',', $row['DependedOn']);
3338
                        foreach ($parentList as $parentId) {
3339
                            $parentId = (int) $parentId;
3340
                            if ($graph->hasVertex($parentId)) {
3341
                                /** @var Vertex $parent */
3342
                                $parent = $graph->getVertex($parentId);
3343
                                /*$parent->setAttribute('graphviz.color', 'red');
3344
                                $parent->setAttribute('graphviz.label', $name);
3345
                                $parent->setAttribute('graphviz.shape', 'square');*/
3346
                                $parent->createEdgeTo($current);
3347
                            }
3348
                        }
3349
                    }
3350
                }
3351
            }
3352
3353
            /** @var Graph $graph */
3354
            foreach ($careerList as $id => $graph) {
3355
                if (isset($careerChamiloIdList[$id])) {
3356
                    $params = [
3357
                        'item_id' => $careerChamiloIdList[$id],
3358
                        'extra_'.$careerDiagramExtraFieldName => serialize($graph),
3359
                        'extra_'.$extraFieldName => $id,
3360
                    ];
3361
                    $extraFieldValue->saveFieldValues($params, true);
3362
                }
3363
            }
3364
        }
3365
3366
        if ($moveFile) {
3367
            $this->moveFile($file);
3368
        }
3369
    }
3370
3371
    /**
3372
     * @param string $file
3373
     * @param bool   $moveFile
3374
     * @param array  $teacherBackup
3375
     * @param array  $groupBackup
3376
     */
3377
    private function importUnsubscribeStatic(
3378
        $file,
3379
        $moveFile = false,
3380
        &$teacherBackup = [],
3381
        &$groupBackup = []
3382
    ) {
3383
        $data = Import::csv_reader($file);
3384
3385
        if (!empty($data)) {
3386
            $this->logger->addInfo(count($data)." records found.");
3387
            foreach ($data as $row) {
3388
                $chamiloUserName = $row['UserName'];
3389
                $chamiloCourseCode = $row['CourseCode'];
3390
                $chamiloSessionId = $row['SessionID'];
3391
3392
                $sessionInfo = api_get_session_info($chamiloSessionId);
3393
3394
                if (empty($sessionInfo)) {
3395
                    $this->logger->addError('Session does not exists: '.$chamiloSessionId);
3396
                    continue;
3397
                }
3398
3399
                $courseInfo = api_get_course_info($chamiloCourseCode);
3400
                if (empty($courseInfo)) {
3401
                    $this->logger->addError('Course does not exists: '.$courseInfo);
3402
                    continue;
3403
                }
3404
3405
                $userId = UserManager::get_user_id_from_username($chamiloUserName);
3406
3407
                if (empty($userId)) {
3408
                    $this->logger->addError('User does not exists: '.$chamiloUserName);
3409
                    continue;
3410
                }
3411
3412
                $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
3413
                        WHERE
3414
                            user_id = ".$userId." AND
3415
                            c_id = '".$courseInfo['real_id']."'
3416
                        ";
3417
                $result = Database::query($sql);
3418
                $rows = Database::num_rows($result);
3419
                if ($rows > 0) {
3420
                    $userCourseData = Database::fetch_array($result, 'ASSOC');
3421
                    if (!empty($userCourseData)) {
3422
                        $teacherBackup[$userId][$courseInfo['code']] = $userCourseData;
3423
                    }
3424
                }
3425
3426
                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
3427
                        WHERE
3428
                            user_id = ".$userId." AND
3429
                            c_id = '".$courseInfo['real_id']."'
3430
                        ";
3431
3432
                $result = Database::query($sql);
3433
                while ($groupData = Database::fetch_array($result, 'ASSOC')) {
3434
                    $groupBackup['user'][$userId][$courseInfo['code']][$groupData['group_id']] = $groupData;
3435
                }
3436
3437
                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
3438
                        WHERE
3439
                            user_id = ".$userId." AND
3440
                            c_id = '".$courseInfo['real_id']."'
3441
                        ";
3442
3443
                $result = Database::query($sql);
3444
                while ($groupData = Database::fetch_array($result, 'ASSOC')) {
3445
                    $groupBackup['tutor'][$userId][$courseInfo['code']][$groupData['group_id']] = $groupData;
3446
                }
3447
3448
                CourseManager::unsubscribe_user(
3449
                    $userId,
3450
                    $courseInfo['code'],
3451
                    $chamiloSessionId
3452
                );
3453
3454
                $this->logger->addError(
3455
                    "User '$chamiloUserName' was removed from session: #$chamiloSessionId, Course: ".$courseInfo['code']
3456
                );
3457
            }
3458
        }
3459
3460
        if ($moveFile) {
3461
            $this->moveFile($file);
3462
        }
3463
    }
3464
3465
    /**
3466
     *  Dump database tables.
3467
     */
3468
    private function dumpDatabaseTables()
3469
    {
3470
        echo 'Dumping tables'.PHP_EOL;
3471
3472
        // User
3473
        $table = Database::get_main_table(TABLE_MAIN_USER);
3474
        $tableAdmin = Database::get_main_table(TABLE_MAIN_ADMIN);
3475
        $sql = "DELETE FROM $table
3476
                WHERE user_id not in (select user_id from $tableAdmin) and status <> ".ANONYMOUS;
3477
        Database::query($sql);
3478
        echo $sql.PHP_EOL;
3479
3480
        // Truncate tables
3481
        $truncateTables = [
3482
            Database::get_main_table(TABLE_MAIN_COURSE),
3483
            Database::get_main_table(TABLE_MAIN_COURSE_USER),
3484
            Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE),
3485
            Database::get_main_table(TABLE_MAIN_CATEGORY),
3486
            Database::get_main_table(TABLE_MAIN_COURSE_MODULE),
3487
            Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER),
3488
            Database::get_main_table(TABLE_MAIN_SESSION),
3489
            Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY),
3490
            Database::get_main_table(TABLE_MAIN_SESSION_COURSE),
3491
            Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER),
3492
            Database::get_main_table(TABLE_MAIN_SESSION_USER),
3493
            Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION),
3494
            Database::get_main_table(TABLE_MAIN_SESSION_FIELD_VALUES),
3495
            Database::get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES),
3496
            Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES),
3497
            Database::get_main_table(TABLE_MAIN_USER_FIELD),
3498
            Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS),
3499
            Database::get_main_table(TABLE_MAIN_COURSE_FIELD),
3500
            Database::get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES),
3501
            Database::get_main_table(TABLE_MAIN_SESSION_FIELD),
3502
            Database::get_main_table(TABLE_MAIN_SESSION_FIELD_VALUES),
3503
            Database::get_course_table(TABLE_AGENDA),
3504
            Database::get_course_table(TABLE_AGENDA_ATTACHMENT),
3505
            Database::get_course_table(TABLE_AGENDA_REPEAT),
3506
            Database::get_course_table(TABLE_AGENDA_REPEAT_NOT),
3507
            Database::get_main_table(TABLE_PERSONAL_AGENDA),
3508
            Database::get_main_table(TABLE_PERSONAL_AGENDA_REPEAT_NOT),
3509
            Database::get_main_table(TABLE_PERSONAL_AGENDA_REPEAT),
3510
            Database::get_main_table(TABLE_MAIN_CALENDAR_EVENT_VALUES),
3511
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS),
3512
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS),
3513
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN),
3514
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_DOWNLOADS),
3515
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCICES),
3516
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT),
3517
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING),
3518
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT),
3519
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_UPLOADS),
3520
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT),
3521
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_ITEM_PROPERTY),
3522
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY),
3523
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION),
3524
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINKEVAL_LOG),
3525
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT),
3526
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT_LOG),
3527
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK),
3528
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_SCORE_DISPLAY),
3529
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE),
3530
            Database::get_course_table(TABLE_STUDENT_PUBLICATION),
3531
            Database::get_course_table(TABLE_QUIZ_QUESTION),
3532
            Database::get_course_table(TABLE_QUIZ_TEST),
3533
            Database::get_course_table(TABLE_QUIZ_ORDER),
3534
            Database::get_course_table(TABLE_QUIZ_ANSWER),
3535
            Database::get_course_table(TABLE_QUIZ_TEST_QUESTION),
3536
            Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION),
3537
            Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY),
3538
            Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY),
3539
            Database::get_course_table(TABLE_LP_MAIN),
3540
            Database::get_course_table(TABLE_LP_ITEM),
3541
            Database::get_course_table(TABLE_LP_VIEW),
3542
            Database::get_course_table(TABLE_LP_ITEM_VIEW),
3543
            Database::get_course_table(TABLE_DOCUMENT),
3544
            Database::get_course_table(TABLE_ITEM_PROPERTY),
3545
            Database::get_course_table(TABLE_TOOL_LIST),
3546
            Database::get_course_table(TABLE_TOOL_INTRO),
3547
            Database::get_course_table(TABLE_COURSE_SETTING),
3548
            Database::get_course_table(TABLE_SURVEY),
3549
            Database::get_course_table(TABLE_SURVEY_QUESTION),
3550
            Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION),
3551
            Database::get_course_table(TABLE_SURVEY_INVITATION),
3552
            Database::get_course_table(TABLE_SURVEY_ANSWER),
3553
            Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP),
3554
            Database::get_course_table(TABLE_SURVEY_REPORT),
3555
            Database::get_course_table(TABLE_GLOSSARY),
3556
            Database::get_course_table(TABLE_LINK),
3557
            Database::get_course_table(TABLE_LINK_CATEGORY),
3558
            Database::get_course_table(TABLE_GROUP),
3559
            Database::get_course_table(TABLE_GROUP_USER),
3560
            Database::get_course_table(TABLE_GROUP_TUTOR),
3561
            Database::get_course_table(TABLE_GROUP_CATEGORY),
3562
            Database::get_course_table(TABLE_DROPBOX_CATEGORY),
3563
            Database::get_course_table(TABLE_DROPBOX_FEEDBACK),
3564
            Database::get_course_table(TABLE_DROPBOX_POST),
3565
            Database::get_course_table(TABLE_DROPBOX_FILE),
3566
            Database::get_course_table(TABLE_DROPBOX_PERSON),
3567
        ];
3568
3569
        foreach ($truncateTables as $table) {
3570
            $sql = "TRUNCATE $table";
3571
            Database::query($sql);
3572
            echo $sql.PHP_EOL;
3573
        }
3574
3575
        $table = Database::get_course_table(TABLE_ITEM_PROPERTY);
3576
        $sql = "DELETE FROM $table WHERE tool = 'calendar_event'";
3577
        Database::query($sql);
3578
        echo $sql.PHP_EOL;
3579
    }
3580
3581
    /**
3582
     * If csv file ends with '"' character then a '";' is added.
3583
     *
3584
     * @param string $file
3585
     */
3586
    private function fixCSVFile($file)
3587
    {
3588
        /*$f = fopen($file, 'r+');
3589
        $cursor = -1;
3590
3591
        fseek($f, $cursor, SEEK_END);
3592
        $char = fgetc($f);
3593
        while ($char === "\n" || $char === "\r") {
3594
            fseek($f, $cursor--, SEEK_END);
3595
            $char = fgetc($f);
3596
        }
3597
3598
        if ($char === "\"") {
3599
            fseek($f, -1, SEEK_CUR);
3600
            fwrite($f, '";');
3601
        }*/
3602
    }
3603
}
3604
3605
$logger = new Logger('cron');
3606
$emails = isset($_configuration['cron_notification_mails']) ? $_configuration['cron_notification_mails'] : null;
3607
3608
$minLevel = Logger::DEBUG;
3609
3610
if (!is_array($emails)) {
3611
    $emails = [$emails];
3612
}
3613
$subject = "Cron main/cron/import_csv.php ".date('Y-m-d h:i:s');
3614
$from = api_get_setting('emailAdministrator');
3615
/*
3616
if (!empty($emails)) {
3617
    foreach ($emails as $email) {
3618
        $stream = new NativeMailerHandler($email, $subject, $from, $minLevel);
3619
        $logger->pushHandler(new BufferHandler($stream, 0, $minLevel));
3620
    }
3621
}*/
3622
3623
$stream = new StreamHandler(
3624
    api_get_path(SYS_ARCHIVE_PATH).'import_csv.log',
3625
    $minLevel
3626
);
3627
$logger->pushHandler(new BufferHandler($stream, 0, $minLevel));
3628
$logger->pushHandler(new RotatingFileHandler('import_csv', 5, $minLevel));
3629
3630
$verbose = false;
3631
if (isset($argv[1]) && $argv[1] === '--verbose') {
3632
    $verbose = true;
3633
}
3634
if ($verbose) {
3635
    $logger->pushHandler(new ErrorLogHandler());
3636
}
3637
3638
$cronImportCSVConditions = isset($_configuration['cron_import_csv_conditions']) ? $_configuration['cron_import_csv_conditions'] : null;
3639
3640
echo 'See the error log here: '.api_get_path(SYS_ARCHIVE_PATH).'import_csv.log'."\n";
3641
3642
$import = new ImportCsv($logger, $cronImportCSVConditions);
3643
3644
if (isset($_configuration['default_admin_user_id_for_cron'])) {
3645
    $import->defaultAdminId = $_configuration['default_admin_user_id_for_cron'];
3646
}
3647
// @todo in production disable the dump option
3648
$dump = false;
3649
if (isset($argv[1]) && $argv[1] === '--dump') {
3650
    $dump = true;
3651
}
3652
3653
if (isset($_configuration['import_csv_disable_dump']) &&
3654
    $_configuration['import_csv_disable_dump'] == true
3655
) {
3656
    $import->setDumpValues(false);
3657
} else {
3658
    $import->setDumpValues($dump);
3659
}
3660
3661
$import->setUpdateEmailToDummy(api_get_configuration_value('update_users_email_to_dummy_except_admins'));
3662
3663
// Do not moves the files to treated
3664
if (isset($_configuration['import_csv_test'])) {
3665
    $import->test = $_configuration['import_csv_test'];
3666
} else {
3667
    $import->test = true;
3668
}
3669
3670
$languageFilesToLoad = api_get_language_files_to_load($import->defaultLanguage);
3671
3672
foreach ($languageFilesToLoad as $languageFile) {
3673
    include $languageFile;
3674
}
3675
3676
// Set default language to be loaded
3677
$language = $import->defaultLanguage;
3678
global $language_interface;
3679
$language_interface = $language;
3680
global $language_interface_initial_value;
3681
$language_interface_initial_value = $language;
3682
3683
$timeStart = microtime(true);
3684
$import->run();
3685
$timeEnd = microtime(true);
3686
$executionTime = round(($timeEnd - $timeStart) / 60, 2);
3687
$logger->addInfo("Total execution Time $executionTime Min");
3688
3689
if (isset($_configuration['import_csv_fix_permissions']) &&
3690
    $_configuration['import_csv_fix_permissions'] == true
3691
) {
3692
    $command = "sudo find ".api_get_path(SYS_COURSE_PATH)." -type d -exec chmod 777 {} \; ";
3693
    echo "Executing: ".$command.PHP_EOL;
3694
    system($command);
3695
3696
    $command = "sudo find ".api_get_path(SYS_CODE_PATH)."upload/users  -type d -exec chmod 777 {} \;";
3697
    echo "Executing: ".$command.PHP_EOL;
3698
    system($command);
3699
}
3700