Completed
Push — 1.10.x ( ba0bf0...97c0d2 )
by Angel Fernando Quiroz
44:06
created

user_update_import.php ➔ updateUsers()   F

Complexity

Conditions 29
Paths > 20000

Size

Total Lines 91
Code Lines 70

Duplication

Lines 16
Ratio 17.58 %
Metric Value
cc 29
eloc 70
nc 1572876
nop 1
dl 16
loc 91
rs 2.0338

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
 * This tool allows platform admins to add users by uploading a CSV or XML file
5
 * @package chamilo.admin
6
 */
7
8
/**
9
 * Validate the imported data.
10
 */
11
12
$cidReset = true;
13
require_once '../inc/global.inc.php';
14
15
// Set this option to true to enforce strict purification for usenames.
16
$purification_option_for_usernames = false;
17
18
function validate_data($users)
0 ignored issues
show
Best Practice introduced by
The function validate_data() has been defined more than once; this definition is ignored, only the first definition in main/admin/class_import.php (L15-34) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
19
{
20
    global $defined_auth_sources;
21
    $errors = array();
22
    $usernames = array();
23
24
    // 1. Check if mandatory fields are set.
25
    $mandatory_fields = array('LastName', 'FirstName');
26
27
    if (api_get_setting('registration', 'email') == 'true') {
28
        $mandatory_fields[] = 'Email';
29
    }
30
    $classExistList = array();
31
    $usergroup = new UserGroup();
32
33
    foreach ($users as $user) {
34 View Code Duplication
        foreach ($mandatory_fields as $field) {
35
            if (isset($user[$field])) {
36
                if (empty($user[$field])) {
37
                    $user['error'] = get_lang($field.'Mandatory');
38
                    $errors[] = $user;
39
                }
40
            }
41
        }
42
43
        // 2. Check username, first, check whether it is empty.
44
45
        if (isset($user['NewUserName'])) {
46
            if (!UserManager::is_username_empty($user['NewUserName'])) {
47
                // 2.1. Check whether username is too long.
48 View Code Duplication
                if (UserManager::is_username_too_long($user['NewUserName'])) {
49
                    $user['error'] = get_lang('UserNameTooLong');
50
                    $errors[] = $user;
51
                }
52
                // 2.2. Check whether the username was used twice in import file.
53 View Code Duplication
                if (isset($usernames[$user['NewUserName']])) {
54
                    $user['error'] = get_lang('UserNameUsedTwice');
55
                    $errors[] = $user;
56
                }
57
                $usernames[$user['UserName']] = 1;
58
                // 2.3. Check whether username is allready occupied.
59
                if (!UserManager::is_username_available($user['NewUserName']) && $user['NewUserName'] != $user['UserName']) {
60
                    $user['error'] = get_lang('UserNameNotAvailable');
61
                    $errors[] = $user;
62
                }
63
             }
64
          }
65
66
        // 3. Check status.
67 View Code Duplication
        if (isset($user['Status']) && !api_status_exists($user['Status'])) {
68
            $user['error'] = get_lang('WrongStatus');
69
            $errors[] = $user;
70
        }
71
72
        // 4. Check ClassId
73 View Code Duplication
        if (!empty($user['ClassId'])) {
74
            $classId = explode('|', trim($user['ClassId']));
75
            foreach ($classId as $id) {
76
                if (in_array($id, $classExistList)) {
77
                    continue;
78
                }
79
                $info = $usergroup->get($id);
80
                if (empty($info)) {
81
                    $user['error'] = sprintf(get_lang('ClassIdDoesntExists'), $id);
82
                    $errors[] = $user;
83
                } else {
84
                    $classExistList[] = $info['id'];
85
                }
86
            }
87
        }
88
89
        // 5. Check authentication source
90 View Code Duplication
        if (!empty($user['AuthSource'])) {
91
            if (!in_array($user['AuthSource'], $defined_auth_sources)) {
92
                $user['error'] = get_lang('AuthSourceNotAvailable');
93
                $errors[] = $user;
94
            }
95
        }
96
    }
97
98
    return $errors;
99
}
100
101
/**
102
 * Add missing user-information (which isn't required, like password, username etc).
103
 */
104
function complete_missing_data($user)
0 ignored issues
show
Best Practice introduced by
The function complete_missing_data() has been defined more than once; this definition is ignored, only the first definition in main/admin/user_import.php (L117-152) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
105
{
106
    global $purification_option_for_usernames;
107
    // 1. Create a username if necessary.
108 View Code Duplication
    if (UserManager::is_username_empty($user['UserName'])) {
109
        $user['UserName'] = UserManager::create_unique_username($user['FirstName'], $user['LastName']);
110
    } else {
111
        $user['UserName'] = UserManager::purify_username($user['UserName'], $purification_option_for_usernames);
112
    }
113
    // 2. Generate a password if necessary.
114
    if (empty($user['Password'])) {
115
        $user['Password'] = api_generate_password();
116
    }
117
    // 3. Set status if not allready set.
118
    if (empty($user['Status'])) {
119
        $user['Status'] = 'user';
120
    }
121
    // 4. Set authsource if not allready set.
122
    if (empty($user['AuthSource'])) {
123
        $user['AuthSource'] = PLATFORM_AUTH_SOURCE;
124
    }
125
    return $user;
126
}
127
128
/**
129
 * Update users from the imported data
130
 * @param   array   $users List of users
131
 * @return  void
132
 * @uses global variable $inserted_in_course, which returns the list of courses the user was inserted in
133
 */
134
135
function updateUsers($users)
136
{
137
    global $insertedIn_course;
138
    // Not all scripts declare the $inserted_in_course array (although they should).
139
    if (!isset($inserted_in_course)) {
0 ignored issues
show
Bug introduced by
The variable $inserted_in_course seems only to be defined at a later point. As such the call to isset() seems to always evaluate to false.

This check marks calls to isset(...) or empty(...) that are found before the variable itself is defined. These will always have the same result.

This is likely the result of code being shifted around. Consider removing these calls.

Loading history...
140
        $inserted_in_course = array();
141
    }
142
    $usergroup = new UserGroup();
143
    $send_mail = $_POST['sendMail'] ? true : false;
144
    if (is_array($users)) {
145
        foreach ($users as $user) {
146
            $user = complete_missing_data($user);
147
            $user['Status'] = api_status_key($user['Status']);
148
            $userName = $user['UserName'];
149
            $userInfo = api_get_user_info_from_username($userName);
150
            $user_id = $userInfo['user_id'];
151
            if ($user_id == 0) {
152
                return false;
153
            }
154
            $firstName = isset($user['FirstName']) ? $user['FirstName'] : $userInfo['firstname'];
155
            $lastName = isset($user['LastName']) ? $user['LastName'] : $userInfo['lastname'];
156
            $userName = isset($user['NewUserName']) ? $user['NewUserName'] : $userInfo['username'];
157
            $password = isset($user['Password']) ? $user['Password'] : $userInfo['password'];
158
            $authSource = isset($user['AuthSource']) ? $user['AuthSource'] : $userInfo['auth_source'];
159
            $email = isset($user['Email']) ? $user['Email'] : $userInfo['email'];
160
            $status = isset($user['Status']) ? $user['Status'] : $userInfo['status'];
161
            $officialCode = isset($user['OfficialCode']) ? $user['OfficialCode'] : $userInfo['official_code'];
162
            $phone = isset($user['PhoneNumber']) ? $user['PhoneNumber'] : $userInfo['phone'];
163
            $pictureUrl = isset($user['PictureUri']) ? $user['PictureUri'] : $userInfo['picture_uri'];
164
            $expirationDate = isset($user['ExpiryDate']) ? $user['ExpiryDate'] : $userInfo['expiration_date'];
165
            $active = isset($user['Active']) ? $user['Active'] : $userInfo['active'];
166
            $creatorId = $userInfo['creator_id'];
167
            $hrDeptId = $userInfo['hr_dept_id'];
168
            $language = isset($user['Language']) ? $user['Language'] : $userInfo['language'];
169
            $sendEmail = isset($user['SendEmail']) ? $user['SendEmail'] : $userInfo['language'];
170
            $userUpdated = UserManager :: update_user(
171
                $user_id,
172
                $firstName,
173
                $lastName,
174
                $userName,
175
                $password,
176
                $authSource,
177
                $email,
178
                $status,
179
                $officialCode,
180
                $phone,
181
                $pictureUrl,
182
                $expirationDate,
183
                $active,
184
                $creatorId,
185
                $hrDeptId,
186
                null,
187
                $language,
188
                '',
189
                '',
190
                ''
191
192
            );
193 View Code Duplication
            if (!is_array($user['Courses']) && !empty($user['Courses'])) {
194
                $user['Courses'] = array($user['Courses']);
195
            }
196
            if (is_array($user['Courses'])) {
197
                foreach ($user['Courses'] as $course) {
198
                    if (CourseManager::course_exists($course)) {
199
                        CourseManager::subscribe_user($user_id, $course, $user['Status']);
200
                        $course_info = CourseManager::get_course_information($course);
201
                        $inserted_in_course[$course] = $course_info['title'];
202
                    }
203
                }
204
            }
205 View Code Duplication
            if (!empty($user['ClassId'])) {
206
                $classId = explode('|', trim($user['ClassId']));
207
                foreach ($classId as $id) {
208
                    $usergroup->subscribe_users_to_usergroup($id, array($user_id), false);
209
                }
210
            }
211
212
            // Saving extra fields.
213
            global $extra_fields;
214
215
            // We are sure that the extra field exists.
216 View Code Duplication
            foreach ($extra_fields as $extras) {
217
                if (isset($user[$extras[1]])) {
218
                    $key 	= $extras[1];
219
                    $value 	= $user[$extras[1]];
220
                    UserManager::update_extra_field_value($user_id, $key, $value);
221
                }
222
            }
223
        }
224
    }
225
}
226
227
228
/**
229
 * Read the CSV-file
230
 * @param string $file Path to the CSV-file
231
 * @return array All userinformation read from the file
232
 */
233 View Code Duplication
function parse_csv_data($file)
0 ignored issues
show
Best Practice introduced by
The function parse_csv_data() has been defined more than once; this definition is ignored, only the first definition in main/admin/class_user_import.php (L129-132) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
234
{
235
    $users = 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...
236
    foreach ($users as $index => $user) {
237
        if (isset ($user['Courses'])) {
238
            $user['Courses'] = explode('|', trim($user['Courses']));
239
        }
240
        $users[$index] = $user;
241
    }
242
    return $users;
243
}
244
/**
245
 * XML-parser: handle start of element
246
 * @param   string  $parser Deprecated?
247
 * @param   string  $data The data to be parsed
248
 */
249 View Code Duplication
function element_start($parser, $data)
0 ignored issues
show
Best Practice introduced by
The function element_start() has been defined more than once; this definition is ignored, only the first definition in main/admin/skills_import.php (L95-107) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
250
{
251
    $data = api_utf8_decode($data);
252
    global $user;
253
    global $current_tag;
254
    switch ($data) {
255
        case 'Contact':
256
            $user = array ();
257
            break;
258
        default:
259
            $current_tag = $data;
260
    }
261
}
262
263
/**
264
 * XML-parser: handle end of element
265
 * @param   string  $parser Deprecated?
266
 * @param   string  $data   The data to be parsed
267
 */
268 View Code Duplication
function element_end($parser, $data)
0 ignored issues
show
Best Practice introduced by
The function element_end() has been defined more than once; this definition is ignored, only the first definition in main/admin/skills_import.php (L112-126) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
269
{
270
    $data = api_utf8_decode($data);
271
    global $user;
272
    global $users;
273
    global $current_value;
274
    switch ($data) {
275
        case 'Contact':
276
            if ($user['Status'] == '5') {
277
                $user['Status'] = STUDENT;
278
            }
279
            if ($user['Status'] == '1') {
280
                $user['Status'] = COURSEMANAGER;
281
            }
282
            $users[] = $user;
283
            break;
284
        default:
285
            $user[$data] = $current_value;
286
            break;
287
    }
288
}
289
290
/**
291
 * XML-parser: handle character data
292
 * @param   string  $parser Parser (deprecated?)
293
 * @param   string  $data The data to be parsed
294
 * @return  void
295
 */
296
function character_data($parser, $data)
0 ignored issues
show
Best Practice introduced by
The function character_data() has been defined more than once; this definition is ignored, only the first definition in main/admin/skills_import.php (L131-136) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
297
{
298
    $data = trim(api_utf8_decode($data));
299
    global $current_value;
300
    $current_value = $data;
301
}
302
303
/**
304
 * Read the XML-file
305
 * @param string $file Path to the XML-file
306
 * @return array All user information read from the file
307
 */
308 View Code Duplication
function parse_xml_data($file)
0 ignored issues
show
Best Practice introduced by
The function parse_xml_data() has been defined more than once; this definition is ignored, only the first definition in main/admin/skills_import.php (L143-158) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
309
{
310
    global $users;
311
    $users = array();
312
    $parser = xml_parser_create('UTF-8');
313
    xml_set_element_handler($parser, 'element_start', 'element_end');
314
    xml_set_character_data_handler($parser, 'character_data');
315
    xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
316
    xml_parse($parser, api_utf8_encode_xml(file_get_contents($file)));
317
    xml_parser_free($parser);
318
    return $users;
319
}
320
321
$this_section = SECTION_PLATFORM_ADMIN;
322
api_protect_admin_script(true, null, 'login');
323
324
325
$defined_auth_sources[] = PLATFORM_AUTH_SOURCE;
326
327
if (isset($extAuthSource) && is_array($extAuthSource)) {
328
    $defined_auth_sources = array_merge($defined_auth_sources, array_keys($extAuthSource));
329
}
330
331
$tool_name = get_lang('ImportUserListXMLCSV');
332
$interbreadcrumb[] = array("url" => 'index.php', "name" => get_lang('PlatformAdmin'));
333
334
set_time_limit(0);
335
$extra_fields = UserManager::get_extra_fields(0, 0, 5, 'ASC', true);
336
$user_id_error = array();
337
$error_message = '';
338
339
if (isset($_POST['formSent']) && $_POST['formSent'] AND $_FILES['import_file']['size'] !== 0) {
340
341
    $file_type = 'csv';
342
343
    Security::clear_token();
344
    $tok = Security::get_token();
345
    $allowed_file_mimetype = array('csv', 'xml');
346
    $error_kind_file = false;
347
348
    $uploadInfo = pathinfo($_FILES['import_file']['name']);
349
    $ext_import_file = $uploadInfo['extension'];
350
351 View Code Duplication
    if (in_array($ext_import_file, $allowed_file_mimetype)) {
352
        if (strcmp($file_type, 'csv') === 0 && $ext_import_file == $allowed_file_mimetype[0]) {
353
            $users	= parse_csv_data($_FILES['import_file']['tmp_name']);
354
            $errors = validate_data($users);
355
            $error_kind_file = false;
356
        } elseif (strcmp($file_type, 'xml') === 0 && $ext_import_file == $allowed_file_mimetype[1]) {
357
            $users = parse_xml_data($_FILES['import_file']['tmp_name']);
358
            $errors = validate_data($users);
359
            $error_kind_file = false;
360
        } else {
361
362
            $error_kind_file = true;
363
        }
364
    } else {
365
        $error_kind_file = true;
366
    }
367
368
    // List user id with error.
369
    $users_to_insert = $user_id_error = array();
370
371
    if (is_array($errors)) {
372
        foreach ($errors as $my_errors) {
373
            $user_id_error[] = $my_errors['UserName'];
374
        }
375
    }
376
377 View Code Duplication
    if (is_array($users)) {
378
        foreach ($users as $my_user) {
379
            if (!in_array($my_user['UserName'], $user_id_error)) {
380
                $users_to_insert[] = $my_user;
381
            }
382
        }
383
    }
384
385
    $inserted_in_course = array();
386
    if (strcmp($file_type, 'csv') === 0) {
387
        updateUsers($users_to_insert);
388
    }
389
390 View Code Duplication
    if (count($errors) > 0) {
391
        $see_message_import = get_lang('FileImportedJustUsersThatAreNotRegistered');
392
    } else {
393
        $see_message_import = get_lang('FileImported');
394
    }
395
396 View Code Duplication
    if (count($errors) != 0) {
397
        $warning_message = '<ul>';
398
        foreach ($errors as $index => $error_user) {
399
            $warning_message .= '<li><b>'.$error_user['error'].'</b>: ';
400
            $warning_message .=
401
                '<strong>'.$error_user['UserName'].'</strong>&nbsp;('.
402
                api_get_person_name($error_user['FirstName'], $error_user['LastName']).')';
403
            $warning_message .= '</li>';
404
        }
405
        $warning_message .= '</ul>';
406
    }
407
408
    // if the warning message is too long then we display the warning message trough a session
409
    Display::addFlash(Display::return_message($warning_message, 'warning', false));
410
411 View Code Duplication
    if ($error_kind_file) {
412
        Display::addFlash(Display::return_message(get_lang('YouMustImportAFileAccordingToSelectedOption'), 'error', false));
413
    } else {
414
        header('Location: '.api_get_path(WEB_CODE_PATH).'admin/user_list.php?sec_token='.$tok);
415
        exit;
416
    }
417
418
}
419
Display :: display_header($tool_name);
420
421
if (!empty($error_message)) {
422
    Display::display_error_message($error_message);
423
}
424
425
$form = new FormValidator('user_update_import', 'post', api_get_self());
426
$form->addElement('header', $tool_name);
427
$form->addElement('hidden', 'formSent');
428
$form->addElement('file', 'import_file', get_lang('ImportFileLocation'));
429
430
$group = array();
431
432
$form->addButtonImport(get_lang('Import'));
433
$defaults['formSent'] = 1;
434
$defaults['sendMail'] = 0;
435
$defaults['file_type'] = 'csv';
436
$form->setDefaults($defaults);
437
$form->display();
438
439
$list = array();
440
$list_reponse = array();
441
$result_xml = '';
442
$i = 0;
443
$count_fields = count($extra_fields);
444 View Code Duplication
if ($count_fields > 0) {
445
    foreach ($extra_fields as $extra) {
446
        $list[] = $extra[1];
447
        $list_reponse[] = 'xxx';
448
        $spaces = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
449
        $result_xml .= $spaces.'&lt;'.$extra[1].'&gt;xxx&lt;/'.$extra[1].'&gt;';
450
        if ($i != $count_fields - 1) {
451
            $result_xml .= '<br/>';
452
        }
453
        $i++;
454
    }
455
}
456
457
?>
458
<p><?php echo get_lang('CSVMustLookLike').' ('.get_lang('MandatoryFields').')'; ?> :</p>
459
460
    <blockquote>
461
        <pre>
462
            <b>UserName</b>;LastName;FirstName;Email;NewUserName;Password;AuthSource;OfficialCode;PhoneNumber;Status;ExpiryDate;Active;Language;Courses;ClassId;
463
            xxx;xxx;xxx;xxx;xxx;xxx;xxx;xxx;xxx;user/teacher/drh;0000-00-00 00:00:00;0/1;xxx;<span style="color:red;"><?php if (count($list_reponse) > 0) echo implode(';', $list_reponse).';'; ?></span>xxx1|xxx2|xxx3;1;<br />
464
        </pre>
465
    </blockquote>
466
<p><?php
467
468
Display :: display_footer();
469