Completed
Push — master ( 395485...bbad3a )
by Julito
43:12
created

importSubscribeUserToCourseSessionExtStatic()   C

Complexity

Conditions 12
Paths 4

Size

Total Lines 84
Code Lines 57

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 57
nc 4
nop 2
dl 0
loc 84
rs 5.034
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
if (PHP_SAPI != 'cli') {
5
    die('Run this script through the command line or comment this line in the code');
6
}
7
8
if (file_exists('multiple_url_fix.php')) {
9
    require 'multiple_url_fix.php';
10
}
11
12
require_once __DIR__.'/../inc/global.inc.php';
13
14
ini_set('memory_limit', -1);
15
ini_set('max_execution_time', 0);
16
17
/**
18
 * Class ImportCsv
19
 */
20
class ImportCsv
21
{
22
    private $logger;
23
    private $dumpValues;
24
    public $test;
25
    public $defaultLanguage = 'dutch';
26
    public $extraFieldIdNameList = array(
27
        'session' => 'external_session_id',
28
        'course' => 'external_course_id',
29
        'user' => 'external_user_id',
30
        'calendar_event' => 'external_calendar_event_id',
31
    );
32
    public $defaultAdminId = 1;
33
    public $defaultSessionVisibility = 1;
34
35
    /**
36
     * When creating a user the expiration date is set to registration date + this value
37
     * @var int number of years
38
     */
39
    public $expirationDateInUserCreation = 1;
40
41
    public $batchSize = 20;
42
43
    /**
44
     * When updating a user the expiration date is set to update date + this value
45
     * @var int number of years
46
     */
47
    public $expirationDateInUserUpdate = 1;
48
    public $daysCoachAccessBeforeBeginning = 14;
49
    public $daysCoachAccessAfterBeginning = 14;
50
    public $conditions;
51
52
    /**
53
     * @param Monolog\Logger $logger
54
     * @param array
55
     */
56
    public function __construct($logger, $conditions)
57
    {
58
        $this->logger = $logger;
59
        $this->conditions = $conditions;
60
    }
61
62
    /**
63
     * @param bool $dump
64
     */
65
    public function setDumpValues($dump)
66
    {
67
        $this->dumpValues = $dump;
68
    }
69
70
    /**
71
     * @return boolean
72
     */
73
    public function getDumpValues()
74
    {
75
        return $this->dumpValues;
76
    }
77
78
    /**
79
     * Runs the import process
80
     */
81
    public function run()
82
    {
83
        global $_configuration;
84
85
        $value = api_get_configuration_value('import_csv_custom_url_id');
86
        if (!empty($value)) {
87
            $_configuration['access_url'] = $value;
88
        }
89
90
        $path = api_get_path(SYS_CODE_PATH).'cron/incoming/';
91
        if (!is_dir($path)) {
92
            echo "The folder! $path does not exits";
93
94
            return 0;
95
        }
96
97
        if ($this->getDumpValues()) {
98
            $this->dumpDatabaseTables();
99
        }
100
101
        echo "Reading files: ".PHP_EOL.PHP_EOL;
102
103
        $files = scandir($path);
104
        $fileToProcess = array();
105
        $fileToProcessStatic = array();
106
        $teacherBackup = array();
107
        $groupBackup = array();
108
109
        if (!empty($files)) {
110
            foreach ($files as $file) {
111
                $fileInfo = pathinfo($file);
112
                if (isset($fileInfo['extension']) && $fileInfo['extension'] === 'csv') {
113
                    // Checking teachers_yyyymmdd.csv, courses_yyyymmdd.csv, students_yyyymmdd.csv and sessions_yyyymmdd.csv
114
                    $parts = explode('_', $fileInfo['filename']);
115
                    $preMethod = ucwords($parts[1]);
116
                    $preMethod = str_replace('-static', 'Static', $preMethod);
117
                    $method = 'import'.$preMethod;
118
119
                    $isStatic = strpos($method, 'Static');
120
121
                    if ($method == 'importSessionsextidStatic') {
122
                        $method = 'importSessionsExtIdStatic';
123
                    }
124
125
                    if ($method == 'importCourseinsertStatic') {
126
                        $method = 'importSubscribeUserToCourse';
127
                    }
128
129
                    if ($method == 'importUnsubsessionsextidStatic') {
130
                        $method = 'importUnsubsessionsExtidStatic';
131
                    }
132
133
                    if ($method == 'importSubsessionsextidStatic') {
134
                        $method = 'importSubscribeUserToCourseSessionExtStatic';
135
                    }
136
137
                    if (method_exists($this, $method)) {
138
                        if (
139
                            (
140
                                $method == 'importSubscribeStatic' ||
141
                                $method == 'importSubscribeUserToCourse'
142
                            ) ||
143
                            empty($isStatic)
144
                        ) {
145
                            $fileToProcess[$parts[1]][] = array(
146
                                'method' => $method,
147
                                'file' => $path.$fileInfo['basename']
148
                            );
149
                        } else {
150
                            $fileToProcessStatic[$parts[1]][] = array(
151
                                'method' => $method,
152
                                'file' => $path.$fileInfo['basename']
153
                            );
154
                        }
155
                    } else {
156
                        echo "Error - This file '$file' can't be processed.".PHP_EOL;
157
                        echo "Trying to call $method".PHP_EOL;
158
159
                        echo "The file have to has this format:".PHP_EOL;
160
                        echo "prefix_students_ddmmyyyy.csv, prefix_teachers_ddmmyyyy.csv, prefix_courses_ddmmyyyy.csv, prefix_sessions_ddmmyyyy.csv ".PHP_EOL;
161
                        exit;
162
                    }
163
                }
164
            }
165
166
            if (empty($fileToProcess) && empty($fileToProcessStatic)) {
167
                echo 'Error - no files to process.';
168
169
                return 0;
170
            }
171
172
            $this->prepareImport();
173
174
            $sections = array(
175
                'students',
176
                'teachers',
177
                'courses',
178
                'sessions',
179
                'subscribe-static',
180
                'courseinsert-static',
181
                'unsubscribe-static'
182
            );
183
184
            foreach ($sections as $section) {
185
                $this->logger->addInfo("-- Import $section --");
186
187
                if (isset($fileToProcess[$section]) && !empty($fileToProcess[$section])) {
188
                    $files = $fileToProcess[$section];
189
                    foreach ($files as $fileInfo) {
190
                        $method = $fileInfo['method'];
191
                        $file = $fileInfo['file'];
192
193
                        echo 'File: '.$file.PHP_EOL;
194
                        $this->logger->addInfo("Reading file: $file");
195
                        if ($method == 'importSessions') {
196
                            $this->$method(
197
                                $file,
198
                                true,
199
                                $teacherBackup,
200
                                $groupBackup
201
                            );
202
                        } else {
203
                            $this->$method($file, true);
204
                        }
205
                        $this->logger->addInfo("--Finish reading file--");
206
                    }
207
                }
208
            }
209
210
            $sections = array(
211
                'students-static',
212
                'teachers-static',
213
                'courses-static',
214
                'sessions-static',
215
                'calendar-static',
216
                'sessionsextid-static',
217
                'unsubscribe-static',
218
                'unsubsessionsextid-static',
219
                'subsessionsextid-static'
220
            );
221
222
            foreach ($sections as $section) {
223
                $this->logger->addInfo("-- Import static files $section --");
224
225
                if (isset($fileToProcessStatic[$section]) &&
226
                    !empty($fileToProcessStatic[$section])
227
                ) {
228
                    $files = $fileToProcessStatic[$section];
229
                    foreach ($files as $fileInfo) {
230
                        $method = $fileInfo['method'];
231
232
                        $file = $fileInfo['file'];
233
                        echo 'Static file: '.$file.PHP_EOL;
234
                        $this->logger->addInfo("Reading static file: $file");
235
                        $this->$method(
236
                            $file,
237
                            true,
238
                            $teacherBackup,
239
                            $groupBackup
240
                        );
241
                        $this->logger->addInfo("--Finish reading file--");
242
                    }
243
                }
244
            }
245
        }
246
    }
247
248
    /**
249
     * Prepares extra fields before the import
250
     */
251
    private function prepareImport()
252
    {
253
        // Create user extra field: extra_external_user_id
254
        UserManager::create_extra_field(
255
            $this->extraFieldIdNameList['user'],
256
            1,
257
            'External user id',
258
            null
259
        );
260
261
        // Create course extra field: extra_external_course_id
262
        CourseManager::create_course_extra_field(
263
            $this->extraFieldIdNameList['course'],
264
            1,
265
            'External course id',
266
            ''
267
        );
268
269
        // Create session extra field extra_external_session_id
270
        SessionManager::create_session_extra_field(
271
            $this->extraFieldIdNameList['session'],
272
            1,
273
            'External session id'
274
        );
275
276
        // Create calendar_event extra field extra_external_session_id
277
        $extraField = new ExtraField('calendar_event');
278
        $extraField->save(
279
            array(
280
                'field_type' => ExtraField::FIELD_TYPE_TEXT,
281
                'variable' => $this->extraFieldIdNameList['calendar_event'],
282
                'display_text' => 'External calendar event id',
283
            )
284
        );
285
    }
286
287
    /**
288
     * @param string $file
289
     */
290
    private function moveFile($file)
291
    {
292
        $moved = str_replace('incoming', 'treated', $file);
293
294
        if ($this->test) {
295
            $result = 1;
296
        } else {
297
            $result = rename($file, $moved);
298
        }
299
300
        if ($result) {
301
            $this->logger->addInfo("Moving file to the treated folder: $file");
302
        } else {
303
            $this->logger->addError(
304
                "Error - Cant move file to the treated folder: $file"
305
            );
306
        }
307
    }
308
309
    /**
310
     * @param array $row
311
     *
312
     * @return array
313
     */
314
    private function cleanUserRow($row)
315
    {
316
        $row['lastname'] = $row['LastName'];
317
        $row['firstname'] = $row['FirstName'];
318
        $row['email'] = $row['Email'];
319
        $row['username'] = $row['UserName'];
320
        $row['password'] = $row['Password'];
321
        $row['auth_source'] = isset($row['AuthSource']) ? $row['AuthSource'] : PLATFORM_AUTH_SOURCE;
322
        $row['official_code'] = $row['OfficialCode'];
323
        $row['phone'] = isset($row['PhoneNumber']) ? $row['PhoneNumber'] : '';
324
325
        if (isset($row['StudentID'])) {
326
            $row['extra_'.$this->extraFieldIdNameList['user']] = $row['StudentID'];
327
        }
328
329
        if (isset($row['TeacherID'])) {
330
            $row['extra_'.$this->extraFieldIdNameList['user']] = $row['TeacherID'];
331
        }
332
333
        return $row;
334
    }
335
336
    /**
337
     * @param array $row
338
     *
339
     * @return array
340
     */
341
    private function cleanCourseRow($row)
342
    {
343
        $row['title'] = $row['Title'];
344
        $row['course_code'] = $row['Code'];
345
        $row['course_category'] = $row['CourseCategory'];
346
        $row['email'] = $row['Teacher'];
347
        $row['language'] = $row['Language'];
348
349
        $row['teachers'] = array();
350
        if (isset($row['Teacher']) && !empty($row['Teacher'])) {
351
            //$this->logger->addInfo("Teacher list found: ".$row['Teacher']);
352
            $teachers = explode(',', $row['Teacher']);
353
            if (!empty($teachers)) {
354
                foreach ($teachers as $teacherUserName) {
355
                    $teacherUserName = trim($teacherUserName);
356
                    $userInfo = api_get_user_info_from_username($teacherUserName);
357
                    if (!empty($userInfo)) {
358
                        //$this->logger->addInfo("Username found: $teacherUserName");
359
                        $row['teachers'][] = $userInfo['user_id'];
360
                    }
361
                }
362
            }
363
        }
364
365
        if (isset($row['CourseID'])) {
366
            $row['extra_'.$this->extraFieldIdNameList['course']] = $row['CourseID'];
367
        }
368
369
        return $row;
370
    }
371
372
    /**
373
     * File to import
374
     * @param string $file
375
     */
376
    private function importTeachersStatic($file)
377
    {
378
        $this->importTeachers($file, true);
379
    }
380
381
    /**
382
     * File to import
383
     * @param string $file
384
     * @param bool $moveFile
385
     */
386
    private function importTeachers($file, $moveFile = true)
387
    {
388
        $this->fixCSVFile($file);
0 ignored issues
show
Unused Code introduced by
The call to the method ImportCsv::fixCSVFile() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
389
        $data = Import::csvToArray($file);
0 ignored issues
show
Deprecated Code introduced by
The method Import::csvToArray() has been deprecated with message: use cvs_reader instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
390
391
        /* Unique identifier: official-code username.
392
        Email address and password should never get updated. *ok
393
        The only fields that I can think of that should update if the data changes in the csv file are FirstName and LastName. *ok
394
        A slight edit of these fields should be taken into account. ???
395
        Adding teachers is no problem, but deleting them shouldn’t be automated, but we should get a log of “to delete teachers”.
396
        We’ll handle that manually if applicable.
397
        No delete!
398
        */
399
        $language = $this->defaultLanguage;
400
401
        if (!empty($data)) {
402
            $this->logger->addInfo(count($data)." records found.");
403
            $expirationDateOnCreation = api_get_utc_datetime(strtotime("+".intval($this->expirationDateInUserCreation)."years"));
404
            $expirationDateOnUpdate = api_get_utc_datetime(strtotime("+".intval($this->expirationDateInUserUpdate)."years"));
405
406
            $batchSize = $this->batchSize;
407
            $em = Database::getManager();
408
            $counter = 1;
409
            foreach ($data as $row) {
410
                $row = $this->cleanUserRow($row);
411
412
                $user_id = UserManager::get_user_id_from_original_id(
413
                    $row['extra_'.$this->extraFieldIdNameList['user']],
414
                    $this->extraFieldIdNameList['user']
415
                );
416
                $userInfo = array();
417
                $userInfoByOfficialCode = null;
418
419 View Code Duplication
                if (!empty($user_id)) {
420
                    $userInfo = api_get_user_info($user_id);
421
                    $userInfoByOfficialCode = api_get_user_info_from_official_code($row['official_code']);
422
                }
423
424
                if (empty($userInfo) && empty($userInfoByOfficialCode)) {
425
                    // Create user
426
                    $userId = UserManager::create_user(
427
                        $row['firstname'],
428
                        $row['lastname'],
429
                        COURSEMANAGER,
430
                        $row['email'],
431
                        $row['username'],
432
                        $row['password'],
433
                        $row['official_code'],
434
                        $language, //$row['language'],
435
                        $row['phone'],
436
                        null, //$row['picture'], //picture
437
                        $row['auth_source'], // ?
438
                        $expirationDateOnCreation, //'0000-00-00 00:00:00', //$row['expiration_date'], //$expiration_date = '0000-00-00 00:00:00',
0 ignored issues
show
Bug introduced by
It seems like $expirationDateOnCreation defined by api_get_utc_datetime(str...erCreation) . 'years')) on line 403 can also be of type object<DateTime>; however, UserManager::create_user() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
439
                        1, //active
440
                        0,
441
                        null, // extra
442
                        null, //$encrypt_method = '',
443
                        false //$send_mail = false
444
                    );
445
446 View Code Duplication
                    if ($userId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $userId of type false|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
447
                        foreach ($row as $key => $value) {
448
                            if (substr($key, 0, 6) == 'extra_') {
449
                                //an extra field
450
                                UserManager::update_extra_field_value(
451
                                    $userId,
452
                                    substr($key, 6),
453
                                    $value
454
                                );
455
                            }
456
                        }
457
                        $this->logger->addInfo("Teachers - User created: ".$row['username']);
458
                    } else {
459
                        $this->logger->addError("Teachers - User NOT created: ".$row['username']." ".$row['firstname']." ".$row['lastname']);
460
                        $this->logger->addError(strip_tags(Display::getFlashToString()));
0 ignored issues
show
Deprecated Code introduced by
The method Display::getFlashToString() has been deprecated.

This method has been deprecated.

Loading history...
461
                        Display::cleanFlashMessages();
0 ignored issues
show
Deprecated Code introduced by
The method Display::cleanFlashMessages() has been deprecated.

This method has been deprecated.

Loading history...
462
                    }
463
                } else {
464
                    if (empty($userInfo)) {
465
                        $this->logger->addError("Teachers - Can't update user :".$row['username']);
466
                        continue;
467
                    }
468
469
                    // Update user
470
                    $result = UserManager::update_user(
471
                        $userInfo['user_id'],
472
                        $row['firstname'], // <<-- changed
473
                        $row['lastname'],  // <<-- changed
474
                        $userInfo['username'],
475
                        null, //$password = null,
476
                        $row['auth_source'],
477
                        $userInfo['email'],
478
                        COURSEMANAGER,
479
                        $userInfo['official_code'],
480
                        $userInfo['phone'],
481
                        $userInfo['picture_uri'],
482
                        $expirationDateOnUpdate,
483
                        $userInfo['active'],
484
                        null, //$creator_id = null,
485
                        0, //$hr_dept_id = 0,
486
                        null, // $extra = null,
487
                        null, //$language = 'english',
488
                        null, //$encrypt_method = '',
489
                        false, //$send_email = false,
490
                        0 //$reset_password = 0
491
                    );
492
493
                    if ($result) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type false|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
494 View Code Duplication
                        foreach ($row as $key => $value) {
495
                            if (substr($key, 0, 6) == 'extra_') {
496
                                //an extra field
497
                                UserManager::update_extra_field_value(
498
                                    $userInfo['user_id'],
499
                                    substr($key, 6),
500
                                    $value
501
                                );
502
                            }
503
                        }
504
                        $this->logger->addInfo("Teachers - User updated: ".$row['username']);
505
                    } else {
506
                        $this->logger->addError("Teachers - User not updated: ".$row['username']);
507
                    }
508
                }
509
510
                if (($counter % $batchSize) === 0) {
511
                    $em->flush();
512
                    $em->clear(); // Detaches all objects from Doctrine!
513
                }
514
                $counter++;
515
            }
516
517
            $em->clear(); // Detaches all objects from Doctrine!
518
        }
519
520
        if ($moveFile) {
521
            $this->moveFile($file);
522
        }
523
    }
524
525
    /**
526
     * @param string $file
527
     */
528
    private function importStudentsStatic($file)
529
    {
530
        $this->importStudents($file, true);
531
    }
532
533
    /**
534
     * @param string $file
535
     * @param bool $moveFile
536
     */
537
    private function importStudents($file, $moveFile = true)
538
    {
539
        $this->fixCSVFile($file);
0 ignored issues
show
Unused Code introduced by
The call to the method ImportCsv::fixCSVFile() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
540
        $data = Import::csvToArray($file);
0 ignored issues
show
Deprecated Code introduced by
The method Import::csvToArray() has been deprecated with message: use cvs_reader instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
541
542
        /*
543
         * Another users import.
544
        Unique identifier: official code and username . ok
545
        Password should never get updated. ok
546
        If an update should need to occur (because it changed in the .csv),
547
        we’ll want that logged. We will handle this manually in that case.
548
        All other fields should be updateable, though passwords should of course not get updated. ok
549
        If a user gets deleted (not there anymore),
550
        He should be set inactive one year after the current date.
551
        So I presume you’ll just update the expiration date.
552
        We want to grant access to courses up to a year after deletion.
553
         */
554
        $timeStart = microtime(true);
555
556
        $batchSize = $this->batchSize;
557
        $em = Database::getManager();
558
559
        if (!empty($data)) {
560
            $language = $this->defaultLanguage;
561
            $this->logger->addInfo(count($data)." records found.");
562
563
            $expirationDateOnCreate = api_get_utc_datetime(strtotime("+".intval($this->expirationDateInUserCreation)."years"));
564
            $expirationDateOnUpdate = api_get_utc_datetime(strtotime("+".intval($this->expirationDateInUserUpdate)."years"));
565
566
            $counter = 1;
567
568
            foreach ($data as $row) {
569
                $row = $this->cleanUserRow($row);
570
                $user_id = UserManager::get_user_id_from_original_id(
571
                    $row['extra_'.$this->extraFieldIdNameList['user']],
572
                    $this->extraFieldIdNameList['user']
573
                );
574
575
                $userInfo = array();
576
                $userInfoByOfficialCode = null;
577 View Code Duplication
                if (!empty($user_id)) {
578
                    $userInfo = api_get_user_info($user_id, false, true);
579
                    $userInfoByOfficialCode = api_get_user_info_from_official_code($row['official_code']);
580
                }
581
582
                if (empty($userInfo) && empty($userInfoByOfficialCode)) {
583
                    // Create user
584
                    $result = UserManager::create_user(
585
                        $row['firstname'],
586
                        $row['lastname'],
587
                        STUDENT,
588
                        $row['email'],
589
                        $row['username'],
590
                        $row['password'],
591
                        $row['official_code'],
592
                        $language, //$row['language'],
593
                        $row['phone'],
594
                        null, //$row['picture'], //picture
595
                        $row['auth_source'], // ?
596
                        $expirationDateOnCreate, //'0000-00-00 00:00:00', //$row['expiration_date'], //$expiration_date = '0000-00-00 00:00:00',
0 ignored issues
show
Bug introduced by
It seems like $expirationDateOnCreate defined by api_get_utc_datetime(str...erCreation) . 'years')) on line 563 can also be of type object<DateTime>; however, UserManager::create_user() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
597
                        1, //active
598
                        0,
599
                        null, // extra
600
                        null, //$encrypt_method = '',
601
                        false //$send_mail = false
602
                    );
603
604 View Code Duplication
                    if ($result) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type false|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
605
                        foreach ($row as $key => $value) {
606
                            if (substr($key, 0, 6) === 'extra_') {
607
                                //an extra field
608
                                UserManager::update_extra_field_value(
609
                                    $result,
610
                                    substr($key, 6),
611
                                    $value
612
                                );
613
                            }
614
                        }
615
                        $this->logger->addInfo("Students - User created: ".$row['username']);
616
                    } else {
617
                        $this->logger->addError("Students - User NOT created: ".$row['username']." ".$row['firstname']." ".$row['lastname']);
618
                        $this->logger->addError(strip_tags(Display::getFlashToString()));
0 ignored issues
show
Deprecated Code introduced by
The method Display::getFlashToString() has been deprecated.

This method has been deprecated.

Loading history...
619
                        Display::cleanFlashMessages();
0 ignored issues
show
Deprecated Code introduced by
The method Display::cleanFlashMessages() has been deprecated.

This method has been deprecated.

Loading history...
620
                    }
621
                } else {
622
                    if (empty($userInfo)) {
623
                        $this->logger->addError("Students - Can't update user :".$row['username']);
624
                        continue;
625
                    }
626
627
                    if (isset($row['action']) && $row['action'] === 'delete') {
628
                        // Inactive one year later
629
                        $userInfo['expiration_date'] = api_get_utc_datetime(api_strtotime(time() + 365*24*60*60));
630
                    }
631
632
                    $password = $row['password']; // change password
633
                    $email = $row['email']; // change email
634
                    $resetPassword = 2; // allow password change
635
636
                    // Conditions that disables the update of password and email:
637
                    if (isset($this->conditions['importStudents'])) {
638
                        if (isset($this->conditions['importStudents']['update']) &&
639
                            isset($this->conditions['importStudents']['update']['avoid'])
640
                        ) {
641
                            // Blocking email update -
642
                            // 1. Condition
643
                            $avoidUsersWithEmail = $this->conditions['importStudents']['update']['avoid']['email'];
644
                            if ($userInfo['email'] != $row['email'] && in_array($row['email'], $avoidUsersWithEmail)) {
645
                                $this->logger->addInfo("Students - User email is not updated : ".$row['username']." because the avoid conditions (email).");
646
                                // Do not change email keep the old email.
647
                                $email = $userInfo['email'];
648
                            }
649
650
                            // 2. Condition
651 View Code Duplication
                            if (!in_array($userInfo['email'], $avoidUsersWithEmail) && !in_array($row['email'], $avoidUsersWithEmail)) {
652
                                $email = $userInfo['email'];
653
                            }
654
655
                            // 3. Condition
656 View Code Duplication
                            if (in_array($userInfo['email'], $avoidUsersWithEmail) && !in_array($row['email'], $avoidUsersWithEmail)) {
657
                                $email = $row['email'];
658
                            }
659
660
                            // Blocking password update
661
                            //$avoidUsersWithPassword = $this->conditions['importStudents']['update']['avoid']['password'];
662
663
                            /*if (isset($row['password'])) {
664
                                $user = api_get_user_entity($userInfo['id']);
665
                                $encoded = UserManager::encryptPassword(
666
                                    $row['password'],
667
                                    $user
668
                                );
669
670
                                if ($userInfo['password'] != $encoded &&
671
                                    in_array($row['password'], $avoidUsersWithPassword)
672
                                ) {
673
                                    $this->logger->addInfo(
674
                                        "Students - User password is not updated: ".$row['username']." because the avoid conditions (password)."
675
                                    );
676
                                    $password = null;
677
                                    $resetPassword = 0; // disallow password change
678
                                }
679
                            }*/
680
                        }
681
                    }
682
683
                    // Always disallow password change during update
684
                    $password = null;
685
                    $resetPassword = 0; // disallow password change
686
687
                    // Update user
688
                    $result = UserManager::update_user(
689
                        $userInfo['user_id'],
690
                        $row['firstname'], // <<-- changed
691
                        $row['lastname'],  // <<-- changed
692
                        $row['username'],  // <<-- changed
693
                        $password, //$password = null,
694
                        $row['auth_source'],
695
                        $email,
696
                        STUDENT,
697
                        $userInfo['official_code'],
698
                        $userInfo['phone'],
699
                        $userInfo['picture_uri'],
700
                        $expirationDateOnUpdate,
701
                        $userInfo['active'],
702
                        null, //$creator_id = null,
703
                        0, //$hr_dept_id = 0,
704
                        null, // $extra = null,
705
                        null, //$language = 'english',
706
                        null, //$encrypt_method = '',
707
                        false, //$send_email = false,
708
                        $resetPassword //$reset_password = 0
709
                    );
710
711
                    if ($result) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type false|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
712
                        if ($row['username'] != $userInfo['username']) {
713
                            $this->logger->addInfo("Students - Username was changes from '".$userInfo['username']."' to '".$row['username']."' ");
714
                        }
715 View Code Duplication
                        foreach ($row as $key => $value) {
716
                            if (substr($key, 0, 6) === 'extra_') {
717
                                //an extra field
718
                                UserManager::update_extra_field_value(
719
                                    $userInfo['user_id'],
720
                                    substr($key, 6),
721
                                    $value
722
                                );
723
                            }
724
                        }
725
726
                        $this->logger->addInfo("Students - User updated: ".$row['username']);
727
                    } else {
728
                        $this->logger->addError("Students - User NOT updated: ".$row['username']." ".$row['firstname']." ".$row['lastname']);
729
                    }
730
                }
731
732
                if (($counter % $batchSize) === 0) {
733
                    $em->flush();
734
                    $em->clear(); // Detaches all objects from Doctrine!
735
                    $this->logger->addInfo("Detaches all objects");
736
                }
737
                $counter++;
738
            }
739
            $em->clear(); // Detaches all objects from Doctrine!
740
        }
741
742
        $timeEnd = microtime(true);
743
        $executionTime = round(($timeEnd - $timeStart)/60, 2);
744
        $this->logger->addInfo("Execution Time for process students: $executionTime Min");
745
746
        if ($moveFile) {
747
            $this->moveFile($file);
748
        }
749
    }
750
751
    /**
752
     * @param string $file
753
     */
754
    private function importCoursesStatic($file, $moveFile, &$teacherBackup = array(), &$groupBackup = array())
755
    {
756
        $this->importCourses($file, true, $teacherBackup, $groupBackup);
757
    }
758
759
    /**
760
     * @param string $file
761
     * @param bool $moveFile
762
     *
763
     * @return int
764
     */
765
    private function importCalendarStatic($file, $moveFile = true)
766
    {
767
        $this->fixCSVFile($file);
0 ignored issues
show
Unused Code introduced by
The call to the method ImportCsv::fixCSVFile() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
768
        $data = Import::csvToArray($file);
0 ignored issues
show
Deprecated Code introduced by
The method Import::csvToArray() has been deprecated with message: use cvs_reader instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
769
770
        if (!empty($data)) {
771
            $this->logger->addInfo(count($data)." records found.");
772
            $eventsToCreate = array();
773
            $errorFound = false;
774
775
            foreach ($data as $row) {
776
                $sessionId = null;
777
                $externalSessionId = null;
778
                if (isset($row['external_sessionID'])) {
779
                    $externalSessionId = $row['external_sessionID'];
780
                    $sessionId = SessionManager::getSessionIdFromOriginalId(
781
                        $externalSessionId,
782
                        $this->extraFieldIdNameList['session']
783
                    );
784
                }
785
786
                $courseCode = null;
787
                if (isset($row['coursecode'])) {
788
                    $courseCode = $row['coursecode'];
789
                }
790
                $courseInfo = api_get_course_info($courseCode);
791
792
                if (empty($courseInfo)) {
793
                    $this->logger->addInfo("Course '$courseCode' does not exists");
794
                }
795
796
                if (empty($sessionId)) {
797
                    $this->logger->addInfo("external_sessionID: ".$externalSessionId." does not exists.");
798
                }
799
                $teacherId = null;
800
801
                if (!empty($sessionId) && !empty($courseInfo)) {
802
                    $courseIncluded = SessionManager::relation_session_course_exist(
803
                        $sessionId,
804
                        $courseInfo['real_id']
805
                    );
806
807
                    if ($courseIncluded == false) {
808
                        $this->logger->addInfo(
809
                            "Course '$courseCode' is not included in session: $sessionId"
810
                        );
811
                        $errorFound = true;
812
                    } else {
813
                        $teachers = CourseManager::get_coach_list_from_course_code(
814
                            $courseInfo['code'],
815
                            $sessionId
816
                        );
817
818
                        // Getting first teacher.
819
                        if (!empty($teachers)) {
820
                            $teacher = current($teachers);
821
                            $teacherId = $teacher['user_id'];
822
                        } else {
823
                            $sessionInfo = api_get_session_info($sessionId);
824
                            $teacherId = $sessionInfo['id_coach'];
825
                        }
826
                    }
827
                } else {
828
                    $errorFound = true;
829
                }
830
831
                if (empty($teacherId)) {
832
                    $errorFound = true;
833
                    $this->logger->addInfo(
834
                        "No teacher found in course code : '$courseCode' and session: '$sessionId'"
835
                    );
836
                }
837
838
                $date = $row['date'];
839
                $startTime = $row['time_start'];
840
                $endTime = $row['time_end'];
841
                $title = $row['title'];
842
                $comment = $row['comment'];
843
                $color = isset($row['color']) ? $row['color'] : '';
844
845
                $startDateYear = substr($date, 0, 4);
846
                $startDateMonth = substr($date, 4, 2);
847
                $startDateDay = substr($date, 6, 8);
848
849
                $startDate = $startDateYear.'-'.$startDateMonth.'-'.$startDateDay.' '.$startTime.":00";
850
                $endDate = $startDateYear.'-'.$startDateMonth.'-'.$startDateDay.' '.$endTime.":00";
851
852
                if (!api_is_valid_date($startDate) || !api_is_valid_date($endDate)) {
853
                    $this->logger->addInfo(
854
                        "Verify your dates:  '$startDate' : '$endDate' "
855
                    );
856
                    $errorFound = true;
857
                }
858
859
                if ($errorFound == false) {
860
                    $eventsToCreate[] = array(
861
                        'start' => $startDate,
862
                        'end' => $endDate,
863
                        'title' => $title,
864
                        'sender_id' => $teacherId,
865
                        'course_id' => $courseInfo['real_id'],
866
                        'session_id' => $sessionId,
867
                        'comment' => $comment,
868
                        'color' => $color,
869
                        $this->extraFieldIdNameList['calendar_event'] => $row['external_calendar_itemID'],
870
                    );
871
                }
872
                $errorFound = false;
873
            }
874
875
            if (empty($eventsToCreate)) {
876
                $this->logger->addInfo(
877
                    "No events to add"
878
                );
879
880
                return 0;
881
            }
882
883
            $extraFieldValue = new ExtraFieldValue('calendar_event');
884
            $extraFieldName = $this->extraFieldIdNameList['calendar_event'];
885
            $externalEventId = null;
886
887
            $extraField = new ExtraField('calendar_event');
888
            $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable(
889
                $extraFieldName
890
            );
891
892
            if (empty($extraFieldInfo)) {
893
                $this->logger->addInfo(
894
                    "No calendar event extra field created: $extraFieldName"
895
                );
896
897
                return 0;
898
            }
899
900
            $this->logger->addInfo(
901
                "Ready to insert events"
902
            );
903
904
            $batchSize = $this->batchSize;
905
            $counter = 1;
906
            $em = Database::getManager();
907
            $eventStartDateList = [];
908
            $eventEndDateList = [];
909
            $report = [
910
                'mail_sent' => 0,
911
                'mail_not_sent_announcement_exists' => 0,
912
                'mail_not_sent_because_date' => 0,
913
            ];
914
915
            $eventsToCreateFinal = [];
916
917
            foreach ($eventsToCreate as $event) {
918
                $update = false;
919
                $item = null;
920
                if (!isset($event[$extraFieldName])) {
921
                    $this->logger->addInfo(
922
                        "No external_calendar_itemID found. Skipping ..."
923
                    );
924
                    continue;
925
                } else {
926
                    $externalEventId = $event[$extraFieldName];
927
                    if (empty($externalEventId)) {
928
                        $this->logger->addInfo(
929
                            "external_calendar_itemID was set but empty. Skipping ..."
930
                        );
931
                        continue;
932
                    }
933
934
                    $item = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
935
                        $extraFieldName,
936
                        $externalEventId,
937
                        false,
938
                        false,
939
                        false
940
                    );
941
942
                    if (!empty($item)) {
943
                        $update = true;
944
                    }
945
                }
946
947
                $courseInfo = api_get_course_info_by_id($event['course_id']);
948
                $event['course_info']  = $courseInfo;
949
                $event['update']  = $update;
950
                $event['item']  = $item;
951
                $event['external_event_id']  = $externalEventId;
952
953
                if (isset($eventStartDateList[$courseInfo['real_id']]) &&
954
                    isset($eventStartDateList[$courseInfo['real_id']][$event['session_id']])
955
                ) {
956
                    $currentItemDate = api_strtotime($event['start']);
957
                    $firstDate = $eventStartDateList[$courseInfo['real_id']][$event['session_id']];
958 View Code Duplication
                    if ($currentItemDate < api_strtotime($firstDate)) {
959
                        $eventStartDateList[$courseInfo['real_id']][$event['session_id']] = $event['start'];
960
                        $eventEndDateList[$courseInfo['real_id']][$event['session_id']] = $event['end'];
961
                    }
962 View Code Duplication
                } else {
963
                    // First time
964
                    $eventStartDateList[$courseInfo['real_id']][$event['session_id']] = $event['start'];
965
                    $eventEndDateList[$courseInfo['real_id']][$event['session_id']] = $event['end'];
966
                }
967
                $eventsToCreateFinal[] = $event;
968
            }
969
970
            $eventAlreadySent = [];
971
            foreach ($eventsToCreateFinal as $event) {
972
                $courseInfo = $event['course_info'];
973
                $item = $event['item'];
974
                $update = $event['update'];
975
                $externalEventId = $event['external_event_id'];
976
977
                $info = 'Course: '.$courseInfo['real_id'].' ('.$courseInfo['code'].') - Session: '.$event['session_id'];
978
979
                $agenda = new Agenda(
980
                    'course',
981
                    $event['sender_id'],
982
                    $courseInfo['real_id'],
983
                    $event['session_id']
984
                );
985
                $agenda->set_course($courseInfo);
986
                $agenda->setSessionId($event['session_id']);
987
                $agenda->setSenderId($event['sender_id']);
988
                $agenda->setIsAllowedToEdit(true);
989
990
                $eventComment = $event['comment'];
991
                $color = $event['color'];
992
993
                // To use the event comment you need
994
                // ALTER TABLE c_calendar_event ADD COLUMN comment TEXT;
995
                // add in configuration.php allow_agenda_event_comment = true
996
                if (empty($courseInfo)) {
997
                    $this->logger->addInfo(
998
                        "No course found for event #$externalEventId Course #".$event['course_id']." Skipping ..."
999
                    );
1000
                    continue;
1001
                }
1002
1003
                if (empty($event['sender_id'])) {
1004
                    $this->logger->addInfo(
1005
                        "No sender found for event #$externalEventId Send #".$event['sender_id']." Skipping ..."
1006
                    );
1007
                    continue;
1008
                }
1009
1010
                // Taking first element of course-session event
1011
                $alreadyAdded = false;
1012
                $firstDate = $eventStartDateList[$courseInfo['real_id']][$event['session_id']];
1013
                $firstEndDate = $eventEndDateList[$courseInfo['real_id']][$event['session_id']];
1014
1015
                if (isset($eventAlreadySent[$courseInfo['real_id']]) &&
1016
                    isset($eventAlreadySent[$courseInfo['real_id']][$event['session_id']])
1017
                ) {
1018
                    $alreadyAdded = true;
1019
                } else {
1020
                    $eventAlreadySent[$courseInfo['real_id']][$event['session_id']] = true;
1021
                }
1022
1023
                // Working days (Mon-Fri)see BT#12156#note-16
1024
                $days = 5;
1025
                $startDatePlusDays = api_strtotime("$days weekdays");
1026
1027
                $this->logger->addInfo(
1028
                    "startDatePlusDays: ".api_get_utc_datetime($startDatePlusDays).' - First date: '.$firstDate
1029
                );
1030
1031
                // Send
1032
                if ($startDatePlusDays > api_strtotime($firstDate)) {
1033
                    $sendMail = true;
1034
                } else {
1035
                    $sendMail = false;
1036
                }
1037
1038
                // Send announcement to users
1039
                if ($sendMail && $alreadyAdded == false) {
1040
                    $start = $firstDate;
1041
                    $end = $firstEndDate;
1042
1043
                    if (!empty($end) &&
1044
                        api_format_date($start, DATE_FORMAT_LONG) == api_format_date($end, DATE_FORMAT_LONG)
1045
                    ) {
1046
                        $date = api_format_date($start, DATE_FORMAT_LONG).' ('.
1047
                            api_format_date($start, TIME_NO_SEC_FORMAT).' '.
1048
                            api_format_date($end, TIME_NO_SEC_FORMAT).')';
1049
                    } else {
1050
                        $date = api_format_date($start,DATE_TIME_FORMAT_LONG_24H).' - '.
1051
                                api_format_date($end, DATE_TIME_FORMAT_LONG_24H);
1052
                    }
1053
1054
                    $sessionName = '';
1055
                    if (!empty($event['session_id'])) {
1056
                        $sessionName = ' ('.api_get_session_name($event['session_id']).')';
1057
                    }
1058
1059
                    $courseTitle = $courseInfo['title'].$sessionName;
1060
1061
                    $emailBody = get_lang('Dear').' ((user_firstname)) <br />'.
1062
                        sprintf(
1063
                        get_lang('YouHaveBeenSubscribedToCourseXTheStartDateXAndCommentX'),
1064
                        $courseTitle,
1065
                        $date,
1066
                        $event['comment']
1067
                    );
1068
1069
                    $subject = sprintf(
1070
                        get_lang('AgendaAvailableInCourseX'),
1071
                        $courseInfo['title']
1072
                    );
1073
1074
                    $coaches = SessionManager::getCoachesByCourseSession(
1075
                        $courseInfo['real_id'],
1076
                        $event['session_id']
1077
                    );
1078
1079
                    // Search if an announcement exists:
1080
                    $announcementsWithTitleList = AnnouncementManager::getAnnouncementsByTitle(
1081
                        $subject,
1082
                        $courseInfo['real_id'],
1083
                        $event['session_id'],
1084
                        1
1085
                    );
1086
1087
                    if (count($announcementsWithTitleList) == 0) {
1088
                        $this->logger->addInfo(
1089
                            "Mail to be sent because start date: ".$event['start']." and no announcement found."
1090
                        );
1091
                        $announcementId = AnnouncementManager::add_announcement(
1092
                            $courseInfo,
1093
                            $event['session_id'],
1094
                            $subject,
1095
                            $emailBody,
1096
                            [
1097
                                'everyone',
1098
                                'users' => $coaches
1099
                            ],
1100
                            [],
1101
                            null,
1102
                            null,
1103
                            false,
1104
                            $this->defaultAdminId
1105
                        );
1106
1107
                        if ($announcementId) {
1108
                            $this->logger->addInfo(
1109
                                "Announcement added: ".(int)($announcementId)." in $info"
1110
                            );
1111
                            $this->logger->addInfo(
1112
                                "<<--SENDING MAIL-->>"
1113
                            );
1114
1115
                            $report['mail_sent']++;
1116
                            AnnouncementManager::sendEmail(
1117
                                $courseInfo,
1118
                                $event['session_id'],
1119
                                $announcementId,
1120
                                false
1121
                            );
1122
                        }
1123
                    } else {
1124
                        $report['mail_not_sent_announcement_exists']++;
1125
                        $this->logger->addInfo(
1126
                            "Mail NOT sent. An announcement seems to be already saved in $info"
1127
                        );
1128
                    }
1129
                } else {
1130
                    if ($sendMail == false) {
1131
                        $report['mail_not_sent_because_date']++;
1132
                    }
1133
                }
1134
1135
                $content = '';
1136
                if ($update && isset($item['item_id'])) {
1137
                    //the event already exists, just update
1138
                    $eventResult = $agenda->editEvent(
1139
                        $item['item_id'],
1140
                        $event['start'],
1141
                        $event['end'],
1142
                        false,
1143
                        $event['title'],
1144
                        $content,
1145
                        array('everyone'), // $usersToSend
1146
                        array(), //$attachmentArray = array(),
1147
                        [], //$attachmentCommentList
1148
                        $eventComment,
1149
                        $color,
1150
                        false,
1151
                        false
1152
                    );
1153
1154
                    if ($eventResult !== false) {
1155
                        $this->logger->addInfo(
1156
                            "Event updated #".$item['item_id']." External cal Id: (".$externalEventId.") $info"
1157
                        );
1158
                    } else {
1159
                        $this->logger->addInfo(
1160
                            "Error while updating event with external id: $externalEventId"
1161
                        );
1162
                    }
1163
                } else {
1164
                    // New event. Create it.
1165
                    $eventId = $agenda->addEvent(
1166
                        $event['start'],
1167
                        $event['end'],
1168
                        false,
1169
                        $event['title'],
1170
                        $content,
1171
                        array('everyone'), // $usersToSend
1172
                        false, //$addAsAnnouncement = false
1173
                        null, //  $parentEventId
1174
                        array(), //$attachmentArray = array(),
1175
                        [], //$attachmentCommentList
1176
                        $eventComment,
1177
                        $color
1178
                    );
1179
1180
                    if (!empty($eventId)) {
1181
                        //$extraFieldValue->is_course_model = true;
1182
                        $extraFieldValue->save(
1183
                            array(
1184
                                'value' => $externalEventId,
1185
                                'field_id' => $extraFieldInfo['id'],
1186
                                'item_id' => $eventId
1187
                            )
1188
                        );
1189
                        $this->logger->addInfo(
1190
                            "Event added: #$eventId External cal id: (".$externalEventId.") $info"
1191
                        );
1192
                    } else {
1193
                        $this->logger->addInfo(
1194
                            "Error while creating event external id: $externalEventId"
1195
                        );
1196
                    }
1197
                }
1198
1199
                if (($counter % $batchSize) === 0) {
1200
                    $em->flush();
1201
                    $em->clear(); // Detaches all objects from Doctrine!
1202
                }
1203
                $counter++;
1204
            }
1205
1206
            $em->clear(); // Detaches all objects from Doctrine!
1207
            $this->logger->addInfo('------Summary------');
1208
            foreach ($report as $title => $count) {
1209
                $this->logger->addInfo("$title: $count");
1210
            }
1211
            $this->logger->addInfo('------End Summary------');
1212
        }
1213
1214
        if ($moveFile) {
1215
            $this->moveFile($file);
1216
        }
1217
    }
1218
1219
    /**
1220
     * @param string $file
1221
     * @param bool $moveFile
1222
     * @param array $teacherBackup
1223
     * @param array $groupBackup
1224
     */
1225
    private function importCourses(
1226
        $file,
1227
        $moveFile = true,
1228
        &$teacherBackup = array(),
1229
        &$groupBackup = array()
1230
    ) {
1231
        $this->fixCSVFile($file);
0 ignored issues
show
Unused Code introduced by
The call to the method ImportCsv::fixCSVFile() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
1232
        $data = Import::csvToArray($file);
0 ignored issues
show
Deprecated Code introduced by
The method Import::csvToArray() has been deprecated with message: use cvs_reader instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1233
1234
        if (!empty($data)) {
1235
            $this->logger->addInfo(count($data)." records found.");
1236
1237
            foreach ($data as $row) {
1238
                $row = $this->cleanCourseRow($row);
1239
1240
                $courseId = CourseManager::get_course_id_from_original_id(
1241
                    $row['extra_'.$this->extraFieldIdNameList['course']],
1242
                    $this->extraFieldIdNameList['course']
1243
                );
1244
1245
                $courseInfo = api_get_course_info_by_id($courseId);
1246
1247
                if (empty($courseInfo)) {
1248
                    // Create
1249
                    $params = array();
1250
                    $params['title'] = $row['title'];
1251
                    $params['exemplary_content'] = false;
1252
                    $params['wanted_code'] = $row['course_code'];
1253
                    $params['course_category'] = $row['course_category'];
1254
                    $params['course_language'] = $row['language'];
1255
                    $params['teachers'] = $row['teachers'];
1256
1257
                    $courseInfo = CourseManager::create_course(
1258
                        $params,
1259
                        $this->defaultAdminId
1260
                    );
1261
1262
                    if (!empty($courseInfo)) {
1263
                        CourseManager::update_course_extra_field_value(
1264
                            $courseInfo['code'],
1265
                            'external_course_id',
1266
                            $row['extra_'.$this->extraFieldIdNameList['course']]
1267
                        );
1268
1269
                        $this->logger->addInfo("Courses - Course created ".$courseInfo['code']);
1270
                    } else {
1271
                        $this->logger->addError("Courses - Can't create course:".$row['title']);
1272
                    }
1273
                } else {
1274
                    // Update
1275
                    $params = array(
1276
                        'title' => $row['title'],
1277
                        'category_code' => $row['course_category']
1278
                    );
1279
1280
                    $result = CourseManager::update_attributes(
1281
                        $courseInfo['real_id'],
1282
                        $params
1283
                    );
1284
1285
                    $addTeacherToSession = isset($courseInfo['add_teachers_to_sessions_courses']) && !empty($courseInfo['add_teachers_to_sessions_courses']) ? true : false;
1286
1287
                    $teachers = $row['teachers'];
1288
                    if (!is_array($teachers)) {
1289
                        $teachers = array($teachers);
1290
                    }
1291
1292
                    if ($addTeacherToSession) {
1293
                        CourseManager::updateTeachers(
1294
                            $courseInfo,
1295
                            $row['teachers'],
1296
                            false,
1297
                            true,
1298
                            false,
1299
                            $teacherBackup
1300
                        );
1301
                    } else {
1302
                        CourseManager::updateTeachers(
1303
                            $courseInfo,
1304
                            $row['teachers'],
1305
                            true,
1306
                            false,
1307
                            false,
1308
                            $teacherBackup
1309
                        );
1310
                    }
1311
1312
                    foreach ($teachers as $teacherId) {
1313
                        if (isset($groupBackup['tutor'][$teacherId]) &&
1314
                            isset($groupBackup['tutor'][$teacherId][$courseInfo['code']])
1315
                        ) {
1316
                            foreach ($groupBackup['tutor'][$teacherId][$courseInfo['code']] as $data) {
1317
                                GroupManager::subscribe_tutors(
1318
                                    array($teacherId),
1319
                                    $data['group_id'],
1320
                                    $data['c_id']
1321
                                );
1322
                            }
1323
                        }
1324
1325
                        if (isset($groupBackup['user'][$teacherId]) &&
1326
                            isset($groupBackup['user'][$teacherId][$courseInfo['code']]) &&
1327
                            !empty($groupBackup['user'][$teacherId][$courseInfo['code']])
1328
                        ) {
1329
                            foreach ($groupBackup['user'][$teacherId][$courseInfo['code']] as $data) {
1330
                                GroupManager::subscribe_users(
1331
                                    array($teacherId),
1332
                                    $data['group_id'],
1333
                                    $data['c_id']
1334
                                );
1335
                            }
1336
                        }
1337
                    }
1338
1339
                    if ($result) {
1340
                        $this->logger->addInfo("Courses - Course updated ".$courseInfo['code']);
1341
                    } else {
1342
                        $this->logger->addError("Courses - Course NOT updated ".$courseInfo['code']);
1343
                    }
1344
                }
1345
            }
1346
        }
1347
1348
        if ($moveFile) {
1349
            $this->moveFile($file);
1350
        }
1351
    }
1352
1353
    /**
1354
     * Parse filename: encora_subsessionsextid-static_31082016.csv
1355
     * @param string $file
1356
     */
1357
    private function importSubscribeUserToCourseSessionExtStatic($file, $moveFile = true)
1358
    {
1359
        $data = Import::csv_reader($file);
1360
        if (!empty($data)) {
1361
            $this->logger->addInfo(count($data)." records found.");
1362
            $userIdList = [];
1363
            foreach ($data as $row) {
1364
                $chamiloUserName = $row['UserName'];
1365
                $chamiloCourseCode = $row['CourseCode'];
1366
                $externalSessionId = $row['ExtSessionID'];
1367
                $status = $row['Status'];
1368
1369
                $chamiloSessionId = null;
1370
                if (!empty($externalSessionId)) {
1371
                    $chamiloSessionId = SessionManager::getSessionIdFromOriginalId(
1372
                        $externalSessionId,
1373
                        $this->extraFieldIdNameList['session']
1374
                    );
1375
                }
1376
1377
                $sessionInfo = api_get_session_info($chamiloSessionId);
1378
1379
                if (empty($sessionInfo)) {
1380
                    $this->logger->addError('Session does not exists: '.$chamiloSessionId);
1381
                    continue;
1382
                }
1383
1384
                $courseInfo = api_get_course_info($chamiloCourseCode);
1385
                if (empty($courseInfo)) {
1386
                    $this->logger->addError('Course does not exists: '.$courseInfo);
1387
                    continue;
1388
                }
1389
1390
                $userId = UserManager::get_user_id_from_username($chamiloUserName);
1391
1392
                if (empty($userId)) {
1393
                    $this->logger->addError('User does not exists: '.$chamiloUserName);
1394
                    continue;
1395
                }
1396
1397
                switch ($status) {
1398
                    case 'student':
1399
                        SessionManager::subscribe_users_to_session_course(
1400
                            array($userId),
1401
                            $chamiloSessionId,
1402
                            $courseInfo['code']
1403
                        );
1404
                        break;
1405
                    case 'teacher':
1406
                        SessionManager::set_coach_to_course_session(
1407
                            $userId,
1408
                            $chamiloSessionId,
1409
                            $courseInfo['code']
1410
                        );
1411
                        break;
1412
                    case 'drh':
1413
                        $removeAllSessionsFromUser = true;
1414
                        if (in_array($userId, $userIdList)) {
1415
                            $removeAllSessionsFromUser = false;
1416
                        } else {
1417
                            $userIdList[] = $userId;
1418
                        }
1419
1420
                        $userInfo = api_get_user_info($userId);
1421
                        SessionManager::subscribeSessionsToDrh(
1422
                            $userInfo,
0 ignored issues
show
Security Bug introduced by
It seems like $userInfo defined by api_get_user_info($userId) on line 1420 can also be of type false; however, SessionManager::subscribeSessionsToDrh() does only seem to accept array, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
1423
                            [$chamiloSessionId],
1424
                            false,
1425
                            $removeAllSessionsFromUser
1426
                        );
1427
                        break;
1428
                }
1429
1430
                $this->logger->addError(
1431
                    "User '$chamiloUserName' was added as '$status' to Session: #$chamiloSessionId - Course: ".$courseInfo['code']
1432
                );
1433
1434
            }
1435
        }
1436
1437
        if ($moveFile) {
1438
            $this->moveFile($file);
1439
        }
1440
    }
1441
1442
    /**
1443
     * @param $file
1444
     * @param bool $moveFile
1445
     */
1446
    private function importUnsubSessionsExtIdStatic($file, $moveFile = true)
1447
    {
1448
        $data = Import::csv_reader($file);
1449
1450
        if (!empty($data)) {
1451
            $this->logger->addInfo(count($data)." records found.");
1452
            foreach ($data as $row) {
1453
                $chamiloUserName = $row['UserName'];
1454
                $chamiloCourseCode = $row['CourseCode'];
1455
                $externalSessionId = $row['ExtSessionID'];
1456
                $dateStop = $row['DateStop'];
1457
1458
                $chamiloSessionId = null;
1459
                if (!empty($externalSessionId)) {
1460
                    $chamiloSessionId = SessionManager::getSessionIdFromOriginalId(
1461
                        $externalSessionId,
1462
                        $this->extraFieldIdNameList['session']
1463
                    );
1464
                }
1465
1466
                $sessionInfo = api_get_session_info($chamiloSessionId);
1467
1468
                if (empty($sessionInfo)) {
1469
                    $this->logger->addError('Session does not exists: '.$chamiloSessionId);
1470
                    continue;
1471
                }
1472
1473
                $courseInfo = api_get_course_info($chamiloCourseCode);
1474
                if (empty($courseInfo)) {
1475
                    $this->logger->addError('Course does not exists: '.$courseInfo);
1476
                    continue;
1477
                }
1478
1479
                $userId = UserManager::get_user_id_from_username($chamiloUserName);
1480
1481
                if (empty($userId)) {
1482
                    $this->logger->addError('User does not exists: '.$chamiloUserName);
1483
                    continue;
1484
                }
1485
1486
                SessionManager::removeUsersFromCourseSession(
1487
                    array($userId),
1488
                    $chamiloSessionId,
1489
                    $courseInfo
1490
                );
1491
1492
                $this->logger->addError(
1493
                    "User '$chamiloUserName' was remove from Session: #$chamiloSessionId - Course: " . $courseInfo['code']
1494
                );
1495
1496
            }
1497
        }
1498
1499
        if ($moveFile) {
1500
            $this->moveFile($file);
1501
        }
1502
    }
1503
1504
    /**
1505
     *
1506
     * @param string $file
1507
     */
1508
    private function importSessionsExtIdStatic($file, $moveFile = true)
1509
    {
1510
        $data = Import::csv_reader($file);
1511
1512
        if (!empty($data)) {
1513
            $this->logger->addInfo(count($data)." records found.");
1514
            foreach ($data as $row) {
1515
                $chamiloUserName = $row['UserName'];
1516
                $chamiloCourseCode = $row['CourseCode'];
1517
                $externalSessionId = $row['ExtSessionID'];
1518
                $type = $row['Type'];
1519
1520
                $chamiloSessionId = null;
1521
                if (!empty($externalSessionId)) {
1522
                    $chamiloSessionId = SessionManager::getSessionIdFromOriginalId(
1523
                        $externalSessionId,
1524
                        $this->extraFieldIdNameList['session']
1525
                    );
1526
                }
1527
1528
                $sessionInfo = api_get_session_info($chamiloSessionId);
1529
1530
                if (empty($sessionInfo)) {
1531
                    $this->logger->addError('Session does not exists: '.$chamiloSessionId);
1532
                    continue;
1533
                }
1534
1535
                $courseInfo = api_get_course_info($chamiloCourseCode);
1536
                if (empty($courseInfo)) {
1537
                    $this->logger->addError('Course does not exists: '.$courseInfo);
1538
                    continue;
1539
                }
1540
1541
                $userId = UserManager::get_user_id_from_username($chamiloUserName);
1542
1543
                if (empty($userId)) {
1544
                    $this->logger->addError('User does not exists: '.$chamiloUserName);
1545
                    continue;
1546
                }
1547 View Code Duplication
                switch ($type) {
1548
                    case 'student':
1549
                        SessionManager::subscribe_users_to_session_course(
1550
                            array($userId),
1551
                            $chamiloSessionId,
1552
                            $courseInfo['code'],
1553
                            null,
1554
                            false
1555
                        );
1556
                        break;
1557
                    case 'teacher':
1558
                        SessionManager::set_coach_to_course_session(
1559
                            $userId,
1560
                            $chamiloSessionId,
1561
                            $courseInfo['code']
1562
                        );
1563
                        break;
1564
                }
1565
1566
                $this->logger->addError(
1567
                    "User '$chamiloUserName' with status $type was added to session: #$chamiloSessionId - Course: " . $courseInfo['code']
1568
                );
1569
            }
1570
        }
1571
1572
        if ($moveFile) {
1573
            $this->moveFile($file);
1574
        }
1575
    }
1576
1577
    /**
1578
     * Updates the session synchronize with the csv file.
1579
     * @param bool $moveFile
1580
     * @param string $file
1581
     */
1582
    private function importSessionsStatic($file, $moveFile = true)
1583
    {
1584
        $content = file($file);
1585
        $sessions = array();
1586
        $tag_names = array();
1587
1588
        foreach ($content as $key => $enreg) {
1589
            $enreg = explode(';', trim($enreg));
1590 View Code Duplication
            if ($key) {
1591
                foreach ($tag_names as $tag_key => $tag_name) {
1592
                    if (isset($enreg[$tag_key])) {
1593
                        $sessions[$key - 1][$tag_name] = $enreg[$tag_key];
1594
                    }
1595
                }
1596
            } else {
1597
                foreach ($enreg as $tag_name) {
1598
                    $tag_names[] = api_preg_replace(
1599
                        '/[^a-zA-Z0-9_\-]/',
1600
                        '',
1601
                        $tag_name
1602
                    );
1603
                }
1604
                if (!in_array('SessionName', $tag_names) ||
1605
                    !in_array('DateStart',$tag_names) || !in_array('DateEnd', $tag_names)
1606
                ) {
1607
                    $error_message = get_lang('NoNeededData');
1608
                    break;
1609
                }
1610
            }
1611
        }
1612
1613
1614
        if (!empty($sessions)) {
1615
            // Looping the sessions.
1616
            foreach ($sessions as $session) {
1617
                if (!empty($session['SessionID'])) {
1618
                    $sessionId = SessionManager::getSessionIdFromOriginalId(
1619
                        $session['SessionID'],
1620
                        $this->extraFieldIdNameList['session']
1621
                    );
1622
1623
                    $coachUserName = isset($session['Coach']) ? $session['Coach'] : null;
1624
                    $categoryId = isset($session['category_id']) ? $session['category_id'] : null;
1625
1626
                    // 2014-06-30
1627
                    $dateStart = explode('/', $session['DateStart']);
1628
                    $dateEnd = explode('/', $session['DateEnd']);
1629
                    $visibility = $this->defaultSessionVisibility;
1630
1631
                    $coachId = null;
1632
                    if (!empty($coachUserName)) {
1633
                        $coachInfo = api_get_user_info_from_username($coachUserName);
1634
                        $coachId = $coachInfo['user_id'];
1635
                    }
1636
1637
                    $dateStart = $dateStart[0].'-'.$dateStart[1].'-'.$dateStart[2].' 00:00:00';
1638
                    $dateEnd = $dateEnd[0].'-'.$dateEnd[1].'-'.$dateEnd[2].' 23:59:59';
1639
1640
                    $date = new \DateTime($dateStart);
1641
                    $interval = new DateInterval('P'.$this->daysCoachAccessBeforeBeginning.'D');
1642
                    $date->sub($interval);
1643
                    $coachBefore = $date->format('Y-m-d h:i');
1644
1645
                    $date = new \DateTime($dateEnd);
1646
                    $interval = new DateInterval('P'.$this->daysCoachAccessAfterBeginning.'D');
1647
                    $date->add($interval);
1648
                    $coachAfter = $date->format('Y-m-d h:i');
1649
1650
                    /*$dateStart = api_get_utc_datetime($dateStart);
1651
                    $dateEnd = api_get_utc_datetime($dateEnd);
1652
                    $coachBefore = api_get_utc_datetime($coachBefore);
1653
                    $coachAfter = api_get_utc_datetime($coachAfter);*/
1654
1655
                    if (empty($sessionId)) {
1656
                        $result = SessionManager::create_session(
1657
                            $session['SessionName'],
1658
                            $dateStart,
1659
                            $dateEnd,
1660
                            $dateStart,
1661
                            $dateEnd,
1662
                            $coachBefore,
1663
                            $coachAfter,
1664
                            $coachId,
1665
                            $categoryId,
1666
                            $visibility
1667
                        );
1668
1669
                        if (is_numeric($result)) {
1670
                            $sessionId = $result;
1671
                            $this->logger->addInfo("Session #$sessionId created: ".$session['SessionName']);
1672
                            SessionManager::update_session_extra_field_value(
1673
                                $sessionId,
1674
                                $this->extraFieldIdNameList['session'],
1675
                                $session['SessionID']
1676
                            );
1677
                        } else {
1678
                            $this->logger->addInfo("Failed creating session: ".$session['SessionName']);
1679
                        }
1680
                    } else {
1681
                        $sessionInfo = api_get_session_info($sessionId);
1682
                        $accessBefore = null;
1683
                        $accessAfter = null;
1684
1685 View Code Duplication
                        if (empty($sessionInfo['nb_days_access_before_beginning']) ||
1686
                            (!empty($sessionInfo['nb_days_access_before_beginning']) &&
1687
                                $sessionInfo['nb_days_access_before_beginning'] < $this->daysCoachAccessBeforeBeginning)
1688
                        ) {
1689
                            $accessBefore = $coachBefore;
1690
                        }
1691
1692
                        $accessAfter = null;
1693 View Code Duplication
                        if (empty($sessionInfo['nb_days_access_after_end']) ||
1694
                            (!empty($sessionInfo['nb_days_access_after_end']) &&
1695
                                $sessionInfo['nb_days_access_after_end'] < $this->daysCoachAccessAfterBeginning)
1696
                        ) {
1697
                            $accessAfter = $coachAfter;
1698
                        }
1699
1700
                        $showDescription = isset($sessionInfo['show_description']) ? $sessionInfo['show_description'] : 1;
1701
1702
                        $result = SessionManager::edit_session(
1703
                            $sessionId,
1704
                            $session['SessionName'],
1705
                            $dateStart,
1706
                            $dateEnd,
1707
                            $dateStart,
1708
                            $dateEnd,
1709
                            $accessBefore,
1710
                            $accessAfter,
1711
                            $coachId,
1712
                            $categoryId,
1713
                            $visibility,
1714
                            null, //$description = null,
1715
                            $showDescription
1716
                        );
1717
1718
                        if (is_numeric($result)) {
1719
                            $this->logger->addInfo("Session #$sessionId updated: ".$session['SessionName']);
1720
                            $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1721
                            $params = array(
1722
                                'description' => $session['SessionDescription']
1723
                            );
1724
                            Database::update(
1725
                                $tbl_session,
1726
                                $params,
1727
                                array('id = ?' => $sessionId)
1728
                            );
1729
                        }
1730
                    }
1731
1732
                    if (!empty($sessionId)) {
1733
                        // Courses
1734
                        $courses = explode('|', $session['Courses']);
1735
                        $courseList = [];
1736
                        $courseListWithCoach = [];
1737
                        foreach ($courses as $course) {
1738
                            $courseArray = bracketsToArray($course);
1739
                            $courseCode = $courseArray[0];
1740
                            if (CourseManager::course_exists($courseCode)) {
1741
                                $courseInfo = api_get_course_info($courseCode);
1742
                                $courseList[] = $courseInfo['real_id'];
1743
                                // Extracting course coaches
1744
                                $courseCoaches = isset($courseArray[1]) ? $courseArray[1] : null;
1745
                                $courseCoaches = explode(',', $courseCoaches);
1746
1747
                                // Extracting students
1748
                                $courseUsers = isset($courseArray[2]) ? $courseArray[2] : null;
1749
                                $courseUsers = explode(',', $courseUsers);
1750
1751
                                $courseListWithCoach[] = [
1752
                                    'course_info' => $courseInfo,
1753
                                    'coaches' => $courseCoaches,
1754
                                    'course_users' => $courseUsers
1755
                                ];
1756
                            }
1757
                        }
1758
1759
                        SessionManager::add_courses_to_session(
1760
                            $sessionId,
1761
                            $courseList,
1762
                            true
1763
                        );
1764
1765
                        $this->logger->addInfo("Session #$sessionId: Courses added: '".implode(', ', $courseList)."'");
1766
1767
                        if (empty($courseListWithCoach)) {
1768
                            $this->logger->addInfo("No users/coaches to update");
1769
                            continue;
1770
                        }
1771
1772
                        foreach ($courseListWithCoach as $courseData) {
1773
                            $courseInfo = $courseData['course_info'];
1774
                            $courseCode = $courseInfo['code'];
1775
                            $courseId = $courseInfo['real_id'];
1776
                            $courseCoaches = $courseData['coaches'];
1777
                            $courseUsers = $courseData['course_users'];
1778
1779
                            // Coaches
1780
                            if (!empty($courseCoaches)) {
1781
                                $coachList = array();
1782
                                foreach ($courseCoaches as $courseCoach) {
1783
                                    $courseCoachId = UserManager::get_user_id_from_username(
1784
                                        $courseCoach
1785
                                    );
1786
                                    if ($courseCoachId !== false) {
1787
                                        // Just insert new coaches
1788
                                        $coachList[] = $courseCoachId;
1789
                                    }
1790
                                }
1791
1792
                                $this->logger->addInfo("Session #$sessionId: course '$courseCode' coaches added: '".implode(', ', $coachList)."'");
1793
1794
                                SessionManager::updateCoaches(
1795
                                    $sessionId,
1796
                                    $courseId,
1797
                                    $coachList,
1798
                                    true
1799
                                );
1800
                            } else {
1801
                                $this->logger->addInfo("No coaches added");
1802
                            }
1803
1804
                            // Students
1805
                            if (!empty($courseUsers)) {
1806
                                $userList = array();
1807
                                foreach ($courseUsers as $username) {
1808
                                    $userInfo = api_get_user_info_from_username(trim($username));
1809
                                    if (!empty($userInfo)) {
1810
                                        $userList[] = $userInfo['user_id'];
1811
                                    }
1812
                                }
1813
1814
                                $this->logger->addInfo("Session #$sessionId: course '$courseCode': Students added '".implode(', ', $userList)."'");
1815
                                SessionManager::subscribe_users_to_session_course(
1816
                                    $userList,
1817
                                    $sessionId,
1818
                                    $courseCode,
1819
                                    SESSION_VISIBLE_READ_ONLY,
1820
                                    true
1821
                                );
1822
                            } else {
1823
                                $this->logger->addInfo("No users to register.");
1824
                            }
1825
                        }
1826
                    } else {
1827
                        $this->logger->addInfo(
1828
                            'SessionID not found in system.'
1829
                        );
1830
                    }
1831
                } else {
1832
                    $this->logger->addInfo('SessionID does not exists');
1833
                }
1834
            }
1835
        } else {
1836
            $this->logger->addInfo($error_message);
1837
        }
1838
1839
        if ($moveFile) {
1840
            $this->moveFile($file);
1841
        }
1842
    }
1843
1844
    /**
1845
     * @param string $file
1846
     * @param bool $moveFile
1847
     * @param array $teacherBackup
1848
     * @param array $groupBackup
1849
     */
1850
    private function importSessions(
1851
        $file,
1852
        $moveFile = true,
1853
        &$teacherBackup = array(),
1854
        &$groupBackup = array()
1855
    ) {
1856
        $avoid = null;
1857
        if (isset($this->conditions['importSessions']) &&
1858
            isset($this->conditions['importSessions']['update'])
1859
        ) {
1860
            $avoid = $this->conditions['importSessions']['update'];
1861
        }
1862
        $result = SessionManager::importCSV(
1863
            $file,
1864
            true,
1865
            $this->defaultAdminId,
1866
            $this->logger,
1867
            array('SessionID' => 'extra_'.$this->extraFieldIdNameList['session']),
1868
            $this->extraFieldIdNameList['session'],
1869
            $this->daysCoachAccessBeforeBeginning,
1870
            $this->daysCoachAccessAfterBeginning,
1871
            $this->defaultSessionVisibility,
1872
            $avoid,
1873
            false, // deleteUsersNotInList
1874
            false, // updateCourseCoaches
1875
            true, // sessionWithCoursesModifier
1876
            true, //$addOriginalCourseTeachersAsCourseSessionCoaches
1877
            true, //$removeAllTeachersFromCourse
1878
            1, // $showDescription,
1879
            $teacherBackup,
1880
            $groupBackup
1881
        );
1882
1883
        if (!empty($result['error_message'])) {
1884
            $this->logger->addError($result['error_message']);
1885
        }
1886
        $this->logger->addInfo("Sessions - Sessions parsed: ".$result['session_counter']);
1887
1888
        if ($moveFile) {
1889
            $this->moveFile($file);
1890
        }
1891
    }
1892
1893
    /**
1894
     * @param string $file
1895
     * @param bool $moveFile
1896
     */
1897
    private function importSubscribeStatic($file, $moveFile = true)
1898
    {
1899
        $data = Import::csv_reader($file);
1900
1901
        if (!empty($data)) {
1902
            $this->logger->addInfo(count($data) . " records found.");
1903
            foreach ($data as $row) {
1904
                $chamiloUserName = $row['UserName'];
1905
                $chamiloCourseCode = $row['CourseCode'];
1906
                $chamiloSessionId = $row['SessionID'];
1907
                $type = $row['Type'];
1908
1909
                $sessionInfo = api_get_session_info($chamiloSessionId);
1910
1911
                if (empty($sessionInfo)) {
1912
                    $this->logger->addError('Session does not exists: '.$chamiloSessionId);
1913
                    continue;
1914
                }
1915
1916
                $courseInfo = api_get_course_info($chamiloCourseCode);
1917
                if (empty($courseInfo)) {
1918
                    $this->logger->addError('Course does not exists: '.$courseInfo);
1919
                    continue;
1920
                }
1921
1922
                $userId = UserManager::get_user_id_from_username($chamiloUserName);
1923
1924
                if (empty($userId)) {
1925
                    $this->logger->addError('User does not exists: '.$chamiloUserName);
1926
                    continue;
1927
                }
1928
1929 View Code Duplication
                switch ($type) {
1930
                    case 'student':
1931
                        SessionManager::subscribe_users_to_session_course(
1932
                            array($userId),
1933
                            $chamiloSessionId,
1934
                            $courseInfo['code'],
1935
                            null,
1936
                            false
1937
                        );
1938
                        break;
1939
                    case 'teacher':
1940
                        SessionManager::set_coach_to_course_session(
1941
                            $userId,
1942
                            $chamiloSessionId,
1943
                            $courseInfo['real_id']
1944
                        );
1945
                        break;
1946
                }
1947
1948
                $this->logger->addError(
1949
                    "User '$chamiloUserName' with status $type was added to session: #$chamiloSessionId - Course: " . $courseInfo['code']
1950
                );
1951
            }
1952
        }
1953
1954
        if ($moveFile) {
1955
            $this->moveFile($file);
1956
        }
1957
    }
1958
1959
    /**
1960
     * @param $file
1961
     * @param bool $moveFile
1962
     */
1963
    private function importSubscribeUserToCourse($file, $moveFile = false)
1964
    {
1965
        $data = Import::csv_reader($file);
1966
1967
        if (!empty($data)) {
1968
            $this->logger->addInfo(count($data) . " records found.");
1969
            foreach ($data as $row) {
1970
                $chamiloUserName = $row['UserName'];
1971
                $chamiloCourseCode = $row['CourseCode'];
1972
                $status = $row['Status'];
1973
1974
                $courseInfo = api_get_course_info($chamiloCourseCode);
1975
1976
                if (empty($courseInfo)) {
1977
                    $this->logger->addError(
1978
                        'Course does not exists: '.$chamiloCourseCode
1979
                    );
1980
                    continue;
1981
                }
1982
1983
                $userId = UserManager::get_user_id_from_username(
1984
                    $chamiloUserName
1985
                );
1986
1987
                if (empty($userId)) {
1988
                    $this->logger->addError(
1989
                        'User does not exists: '.$chamiloUserName
1990
                    );
1991
                    continue;
1992
                }
1993
1994
                CourseManager::subscribe_user(
1995
                    $userId,
1996
                    $courseInfo['code'],
1997
                    $status
1998
                );
1999
                $this->logger->addInfo(
2000
                    "User $userId added to course $chamiloCourseCode as $status"
2001
                );
2002
            }
2003
        }
2004
2005
        if ($moveFile) {
2006
            $this->moveFile($file);
2007
        }
2008
    }
2009
2010
    /**
2011
     * @param string $file
2012
     * @param bool $moveFile
2013
     * @param array $teacherBackup
2014
     * @param array $groupBackup
2015
     */
2016
    private function importUnsubscribeStatic(
2017
        $file,
2018
        $moveFile = false,
2019
        &$teacherBackup = array(),
2020
        &$groupBackup = array()
2021
    ) {
2022
        $data = Import::csv_reader($file);
2023
2024
        if (!empty($data)) {
2025
            $this->logger->addInfo(count($data)." records found.");
2026
            foreach ($data as $row) {
2027
                $chamiloUserName = $row['UserName'];
2028
                $chamiloCourseCode = $row['CourseCode'];
2029
                $chamiloSessionId = $row['SessionID'];
2030
2031
                $sessionInfo = api_get_session_info($chamiloSessionId);
2032
2033
                if (empty($sessionInfo)) {
2034
                    $this->logger->addError('Session does not exists: '.$chamiloSessionId);
2035
                    continue;
2036
                }
2037
2038
                $courseInfo = api_get_course_info($chamiloCourseCode);
2039
                if (empty($courseInfo)) {
2040
                    $this->logger->addError('Course does not exists: '.$courseInfo);
2041
                    continue;
2042
                }
2043
2044
                $userId = UserManager::get_user_id_from_username($chamiloUserName);
2045
2046
                if (empty($userId)) {
2047
                    $this->logger->addError('User does not exists: '.$chamiloUserName);
2048
                    continue;
2049
                }
2050
2051
                $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
2052
                        WHERE
2053
                            user_id = ".$userId." AND
2054
                            course_code = '".$courseInfo['code']."'
2055
                        ";
2056
2057
                $result = Database::query($sql);
2058
                $userCourseData = Database::fetch_array($result, 'ASSOC');
2059
                $teacherBackup[$userId][$courseInfo['code']] = $userCourseData;
2060
2061
                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
2062
                        WHERE
2063
                            user_id = ".$userId." AND
2064
                            c_id = '".$courseInfo['real_id']."'
2065
                        ";
2066
2067
                $result = Database::query($sql);
2068
                while ($groupData = Database::fetch_array($result, 'ASSOC')) {
2069
                    $groupBackup['user'][$userId][$courseInfo['code']][$groupData['group_id']] = $groupData;
2070
                }
2071
2072
                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
2073
                        WHERE
2074
                            user_id = ".$userId." AND
2075
                            c_id = '".$courseInfo['real_id']."'
2076
                        ";
2077
2078
                $result = Database::query($sql);
2079
                while ($groupData = Database::fetch_array($result, 'ASSOC')) {
2080
                    $groupBackup['tutor'][$userId][$courseInfo['code']][$groupData['group_id']] = $groupData;
2081
                }
2082
2083
                CourseManager::unsubscribe_user(
2084
                    $userId,
2085
                    $courseInfo['code'],
2086
                    $chamiloSessionId
2087
                );
2088
2089
                $this->logger->addError(
2090
                    "User '$chamiloUserName' was removed from session: #$chamiloSessionId, Course: ".$courseInfo['code']
2091
                );
2092
            }
2093
        }
2094
2095
        if ($moveFile) {
2096
            $this->moveFile($file);
2097
        }
2098
    }
2099
2100
    /**
2101
     *  Dump database tables
2102
     */
2103
    private function dumpDatabaseTables()
2104
    {
2105
        echo 'Dumping tables'.PHP_EOL;
2106
2107
        // User
2108
        $table = Database::get_main_table(TABLE_MAIN_USER);
2109
        $tableAdmin = Database::get_main_table(TABLE_MAIN_ADMIN);
2110
        $sql = "DELETE FROM $table
2111
                WHERE user_id not in (select user_id from $tableAdmin) and status <> ".ANONYMOUS;
2112
        Database::query($sql);
2113
        echo $sql.PHP_EOL;
2114
2115
        // Truncate tables
2116
        $truncateTables = array(
2117
            Database::get_main_table(TABLE_MAIN_COURSE),
2118
            Database::get_main_table(TABLE_MAIN_COURSE_USER),
2119
            Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE),
2120
            Database::get_main_table(TABLE_MAIN_CATEGORY),
2121
            Database::get_main_table(TABLE_MAIN_COURSE_MODULE),
2122
            Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER),
2123
            Database::get_main_table(TABLE_MAIN_SESSION),
2124
            Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY),
2125
            Database::get_main_table(TABLE_MAIN_SESSION_COURSE),
2126
            Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER),
2127
            Database::get_main_table(TABLE_MAIN_SESSION_USER),
2128
            Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION),
2129
            Database::get_main_table(TABLE_MAIN_SESSION_FIELD_VALUES),
2130
            Database::get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES),
2131
            Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES),
2132
            Database::get_main_table(TABLE_MAIN_USER_FIELD),
2133
            Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS),
2134
            Database::get_main_table(TABLE_MAIN_COURSE_FIELD),
2135
            Database::get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES),
2136
            Database::get_main_table(TABLE_MAIN_SESSION_FIELD),
2137
            Database::get_main_table(TABLE_MAIN_SESSION_FIELD_VALUES),
2138
            Database::get_course_table(TABLE_AGENDA),
2139
            Database::get_course_table(TABLE_AGENDA_ATTACHMENT),
2140
            Database::get_course_table(TABLE_AGENDA_REPEAT),
2141
            Database::get_course_table(TABLE_AGENDA_REPEAT_NOT),
2142
            Database::get_main_table(TABLE_PERSONAL_AGENDA),
2143
            Database::get_main_table(TABLE_PERSONAL_AGENDA_REPEAT_NOT),
2144
            Database::get_main_table(TABLE_PERSONAL_AGENDA_REPEAT),
2145
            Database::get_main_table(TABLE_MAIN_CALENDAR_EVENT_VALUES),
2146
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS),
2147
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS),
2148
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN),
2149
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_DOWNLOADS),
2150
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCICES),
2151
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT),
2152
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING),
2153
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT),
2154
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_UPLOADS),
2155
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT),
2156
            Database::get_main_table(TABLE_STATISTIC_TRACK_E_ITEM_PROPERTY),
2157
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY),
2158
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION),
2159
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINKEVAL_LOG),
2160
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT),
2161
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT_LOG),
2162
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK),
2163
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_SCORE_DISPLAY),
2164
            Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE),
2165
            Database::get_course_table(TABLE_STUDENT_PUBLICATION),
2166
            Database::get_course_table(TABLE_QUIZ_QUESTION),
2167
            Database::get_course_table(TABLE_QUIZ_TEST),
2168
            Database::get_course_table(TABLE_QUIZ_ORDER),
2169
            Database::get_course_table(TABLE_QUIZ_ANSWER),
2170
            Database::get_course_table(TABLE_QUIZ_TEST_QUESTION),
2171
            Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION),
2172
            Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY),
2173
            Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY),
2174
            Database::get_course_table(TABLE_LP_MAIN),
2175
            Database::get_course_table(TABLE_LP_ITEM),
2176
            Database::get_course_table(TABLE_LP_VIEW),
2177
            Database::get_course_table(TABLE_LP_ITEM_VIEW),
2178
            Database::get_course_table(TABLE_DOCUMENT),
2179
            Database::get_course_table(TABLE_ITEM_PROPERTY),
2180
            Database::get_course_table(TABLE_TOOL_LIST),
2181
            Database::get_course_table(TABLE_TOOL_INTRO),
2182
            Database::get_course_table(TABLE_COURSE_SETTING),
2183
            Database::get_course_table(TABLE_SURVEY),
2184
            Database::get_course_table(TABLE_SURVEY_QUESTION),
2185
            Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION),
2186
            Database::get_course_table(TABLE_SURVEY_INVITATION),
2187
            Database::get_course_table(TABLE_SURVEY_ANSWER),
2188
            Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP),
2189
            Database::get_course_table(TABLE_SURVEY_REPORT),
2190
            Database::get_course_table(TABLE_GLOSSARY),
2191
            Database::get_course_table(TABLE_LINK),
2192
            Database::get_course_table(TABLE_LINK_CATEGORY),
2193
            Database::get_course_table(TABLE_GROUP),
2194
            Database::get_course_table(TABLE_GROUP_USER),
2195
            Database::get_course_table(TABLE_GROUP_TUTOR),
2196
            Database::get_course_table(TABLE_GROUP_CATEGORY),
2197
            Database::get_course_table(TABLE_DROPBOX_CATEGORY),
2198
            Database::get_course_table(TABLE_DROPBOX_FEEDBACK),
2199
            Database::get_course_table(TABLE_DROPBOX_POST),
2200
            Database::get_course_table(TABLE_DROPBOX_FILE),
2201
            Database::get_course_table(TABLE_DROPBOX_PERSON)
2202
        );
2203
2204
        foreach ($truncateTables as $table) {
2205
            $sql = "TRUNCATE $table";
2206
            Database::query($sql);
2207
            echo $sql.PHP_EOL;
2208
        }
2209
2210
        $table = Database::get_course_table(TABLE_ITEM_PROPERTY);
2211
        $sql = "DELETE FROM $table WHERE tool = 'calendar_event'";
2212
        Database::query($sql);
2213
        echo $sql.PHP_EOL;
2214
    }
2215
2216
    /**
2217
     * If csv file ends with '"' character then a '";' is added
2218
     * @param string $file
2219
     */
2220
    private function fixCSVFile($file)
2221
    {
2222
        /*$f = fopen($file, 'r+');
2223
        $cursor = -1;
2224
2225
        fseek($f, $cursor, SEEK_END);
2226
        $char = fgetc($f);
2227
        while ($char === "\n" || $char === "\r") {
2228
            fseek($f, $cursor--, SEEK_END);
2229
            $char = fgetc($f);
2230
        }
2231
2232
        if ($char === "\"") {
2233
            fseek($f, -1, SEEK_CUR);
2234
            fwrite($f, '";');
2235
        }*/
2236
    }
2237
}
2238
2239
use Monolog\Logger;
2240
use Monolog\Handler\StreamHandler;
2241
use Monolog\Handler\NativeMailerHandler;
2242
use Monolog\Handler\RotatingFileHandler;
2243
use Monolog\Handler\BufferHandler;
2244
2245
$logger = new Logger('cron');
2246
$emails = isset($_configuration['cron_notification_mails']) ? $_configuration['cron_notification_mails'] : null;
2247
2248
$minLevel = Logger::DEBUG;
2249
2250
if (!is_array($emails)) {
2251
    $emails = array($emails);
2252
}
2253
$subject = "Cron main/cron/import_csv.php ".date('Y-m-d h:i:s');
2254
$from = api_get_setting('emailAdministrator');
2255
/*
2256
if (!empty($emails)) {
2257
    foreach ($emails as $email) {
2258
        $stream = new NativeMailerHandler($email, $subject, $from, $minLevel);
2259
        $logger->pushHandler(new BufferHandler($stream, 0, $minLevel));
2260
    }
2261
}*/
2262
2263
$stream = new StreamHandler(
2264
    api_get_path(SYS_ARCHIVE_PATH).'import_csv.log',
2265
    $minLevel
2266
);
2267
$logger->pushHandler(new BufferHandler($stream, 0, $minLevel));
2268
$logger->pushHandler(new RotatingFileHandler('import_csv', 5, $minLevel));
2269
2270
$cronImportCSVConditions = isset($_configuration['cron_import_csv_conditions']) ? $_configuration['cron_import_csv_conditions'] : null;
2271
2272
echo 'See the error log here: '.api_get_path(SYS_ARCHIVE_PATH).'import_csv.log'."\n";
2273
2274
$import = new ImportCsv($logger, $cronImportCSVConditions);
2275
2276
if (isset($_configuration['default_admin_user_id_for_cron'])) {
2277
    $import->defaultAdminId = $_configuration['default_admin_user_id_for_cron'];
2278
}
2279
// @todo in production disable the dump option
2280
$dump = false;
2281
2282
if (isset($argv[1]) && $argv[1] = '--dump') {
2283
    $dump = true;
2284
}
2285
2286
if (isset($_configuration['import_csv_disable_dump']) &&
2287
    $_configuration['import_csv_disable_dump'] == true
2288
) {
2289
    $import->setDumpValues(false);
2290
} else {
2291
    $import->setDumpValues($dump);
2292
}
2293
2294
// Do not moves the files to treated
2295
if (isset($_configuration['import_csv_test'])) {
2296
    $import->test = $_configuration['import_csv_test'];
2297
} else {
2298
    $import->test = true;
2299
}
2300
2301
$timeStart = microtime(true);
2302
$import->run();
2303
2304
$timeEnd = microtime(true);
2305
$executionTime = round(($timeEnd - $timeStart) / 60, 2);
2306
$logger->addInfo("Total execution Time $executionTime Min");
2307
2308
if (isset($_configuration['import_csv_fix_permissions']) &&
2309
    $_configuration['import_csv_fix_permissions'] == true
2310
) {
2311
    $command = "sudo find ".api_get_path(SYS_COURSE_PATH)." -type d -exec chmod 777 {} \; ";
2312
    echo "Executing: ".$command.PHP_EOL;
2313
    system($command);
2314
2315
    $command = "sudo find ".api_get_path(SYS_CODE_PATH)."upload/users  -type d -exec chmod 777 {} \;";
2316
    echo "Executing: ".$command.PHP_EOL;
2317
    system($command);
2318
}
2319