Passed
Push — master ( eba669...1a8a38 )
by Julito
10:56
created

importSubscribeUserToCourseSessionExtStatic()   C

Complexity

Conditions 12
Paths 4

Size

Total Lines 81
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 56
nc 4
nop 2
dl 0
loc 81
rs 6.5333
c 0
b 0
f 0

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