Passed
Push — 1.11.x ( f75818...53b8ef )
by Julito
12:39
created

ImportCsv::importCareers()   C

Complexity

Conditions 15
Paths 5

Size

Total Lines 96
Code Lines 62

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 15
eloc 62
c 1
b 0
f 0
nc 5
nop 4
dl 0
loc 96
rs 5.9166

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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