1 | <?php |
||
2 | |||
3 | /* For licensing terms, see /license.txt */ |
||
4 | |||
5 | use Chamilo\CoreBundle\Entity\ExtraFieldOptions; |
||
6 | use ChamiloSession as Session; |
||
7 | use Ddeboer\DataImport\Writer\CsvWriter; |
||
8 | |||
9 | /** |
||
10 | * This tool allows platform admins to add users by uploading a CSV or XML file. |
||
11 | */ |
||
12 | $cidReset = true; |
||
13 | require_once __DIR__.'/../inc/global.inc.php'; |
||
14 | |||
15 | // Set this option to true to enforce strict purification for usenames. |
||
16 | $purification_option_for_usernames = false; |
||
17 | $userId = api_get_user_id(); |
||
18 | api_protect_admin_script(true, null); |
||
19 | api_protect_limit_for_session_admin(); |
||
20 | set_time_limit(0); |
||
21 | |||
22 | /** |
||
23 | * Create directories and subdirectories for backup import csv data. |
||
24 | * |
||
25 | * @param null $path |
||
0 ignored issues
–
show
Documentation
Bug
introduced
by
Loading history...
|
|||
26 | * |
||
27 | * @return string|null |
||
28 | */ |
||
29 | function createDirectory($path = null) |
||
30 | { |
||
31 | if ($path == null) { |
||
32 | return $path; |
||
33 | } |
||
34 | $path = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $path); |
||
35 | $realPath = explode(DIRECTORY_SEPARATOR, $path); |
||
36 | $data = ''; |
||
37 | foreach ($realPath as $pth) { |
||
38 | if (strlen($pth) > 0) { |
||
39 | $data .= DIRECTORY_SEPARATOR.$pth; |
||
40 | if (!is_dir($data)) { |
||
41 | mkdir($data, api_get_permissions_for_new_directories()); |
||
42 | $block = |
||
43 | '<FilesMatch "\.(csv|xml)$"> |
||
44 | Order allow,deny |
||
45 | Deny from all |
||
46 | </FilesMatch> |
||
47 | Options -Indexes'; |
||
48 | |||
49 | $fp = fopen($data.'/.htaccess', 'w'); |
||
50 | if ($fp) { |
||
51 | fwrite($fp, $block); |
||
52 | } |
||
53 | fclose($fp); |
||
54 | } |
||
55 | } |
||
56 | } |
||
57 | |||
58 | return $data; |
||
59 | } |
||
60 | |||
61 | /** |
||
62 | * @param array $users |
||
63 | * @param bool $checkUniqueEmail |
||
64 | * |
||
65 | * @return array |
||
66 | */ |
||
67 | function validate_data($users, $checkUniqueEmail = false) |
||
68 | { |
||
69 | global $defined_auth_sources; |
||
70 | $usernames = []; |
||
71 | |||
72 | // 1. Check if mandatory fields are set. |
||
73 | $mandatory_fields = ['LastName', 'FirstName']; |
||
74 | if (api_get_setting('registration', 'email') == 'true' || $checkUniqueEmail) { |
||
75 | $mandatory_fields[] = 'Email'; |
||
76 | } |
||
77 | |||
78 | $classExistList = []; |
||
79 | $usergroup = new UserGroup(); |
||
80 | foreach ($users as &$user) { |
||
81 | $user['has_error'] = false; |
||
82 | $user['message'] = ''; |
||
83 | |||
84 | foreach ($mandatory_fields as $field) { |
||
85 | if (empty($user[$field])) { |
||
86 | $user['message'] .= Display::return_message(get_lang($field.'Mandatory'), 'warning'); |
||
87 | $user['has_error'] = true; |
||
88 | } |
||
89 | } |
||
90 | |||
91 | $username = isset($user['UserName']) ? $user['UserName'] : ''; |
||
92 | // 2. Check username, first, check whether it is empty. |
||
93 | if (!UserManager::is_username_empty($username)) { |
||
94 | // 2.1. Check whether username is too long. |
||
95 | if (UserManager::is_username_too_long($username)) { |
||
96 | $user['message'] .= Display::return_message(get_lang('UserNameTooLong'), 'warning'); |
||
97 | $user['has_error'] = true; |
||
98 | } |
||
99 | // 2.1.1 |
||
100 | /*$hasDash = strpos($username, '-'); |
||
101 | if ($hasDash !== false) { |
||
102 | $user['message'] .= Display::return_message(get_lang('UserNameHasDash'), 'warning'); |
||
103 | $user['has_error'] = true; |
||
104 | }*/ |
||
105 | // 2.2. Check whether the username was used twice in import file. |
||
106 | if (isset($usernames[$username])) { |
||
107 | $user['message'] .= Display::return_message(get_lang('UserNameUsedTwice'), 'warning'); |
||
108 | $user['has_error'] = true; |
||
109 | } |
||
110 | $usernames[$username] = 1; |
||
111 | // 2.3. Check whether username is already occupied. |
||
112 | if (!UserManager::is_username_available($username)) { |
||
113 | $user['message'] .= Display::return_message(get_lang('UserNameNotAvailable'), 'warning'); |
||
114 | $user['has_error'] = true; |
||
115 | } |
||
116 | |||
117 | if ('true' === api_get_setting('login_is_email')) { |
||
118 | if (false === api_valid_email($username)) { |
||
119 | $user['message'] .= Display::return_message(get_lang('PleaseEnterValidEmail'), 'warning'); |
||
120 | $user['has_error'] = true; |
||
121 | } |
||
122 | } else { |
||
123 | if (!UserManager::is_username_valid($username)) { |
||
124 | $user['message'] .= Display::return_message(get_lang('UsernameWrong'), 'warning'); |
||
125 | $user['has_error'] = true; |
||
126 | } |
||
127 | } |
||
128 | } |
||
129 | |||
130 | // When e-mail is not a required field, e-mail is left empty |
||
131 | if (api_get_setting('registration', 'email') === 'false' && empty($user['Email'])) { |
||
132 | $user['Email'] = ''; |
||
133 | } |
||
134 | if (!empty($user['Email'])) { |
||
135 | $result = api_valid_email($user['Email']); |
||
136 | if ($result === false) { |
||
137 | $user['message'] .= Display::return_message(get_lang('PleaseEnterValidEmail'), 'warning'); |
||
138 | $user['has_error'] = true; |
||
139 | } |
||
140 | } |
||
141 | |||
142 | if ($checkUniqueEmail) { |
||
143 | if (!empty($user['Email'])) { |
||
144 | $userFromEmail = api_get_user_info_from_email($user['Email']); |
||
145 | if (!empty($userFromEmail)) { |
||
146 | $user['message'] .= Display::return_message(get_lang('EmailUsedTwice'), 'warning'); |
||
147 | $user['has_error'] = true; |
||
148 | } |
||
149 | } |
||
150 | } |
||
151 | |||
152 | // 3. Check status. |
||
153 | if (isset($user['Status']) && !api_status_exists($user['Status'])) { |
||
154 | $user['message'] .= Display::return_message(get_lang('WrongStatus'), 'warning'); |
||
155 | $user['has_error'] = true; |
||
156 | } |
||
157 | |||
158 | // 4. Check ClassId |
||
159 | if (!empty($user['ClassId'])) { |
||
160 | $classId = explode('|', trim($user['ClassId'])); |
||
161 | foreach ($classId as $id) { |
||
162 | if (in_array($id, $classExistList)) { |
||
163 | continue; |
||
164 | } |
||
165 | $info = $usergroup->get($id); |
||
166 | if (empty($info)) { |
||
167 | $user['message'] .= Display::return_message( |
||
168 | sprintf(get_lang('ClassIdDoesntExists'), $id), |
||
169 | 'warning' |
||
170 | ); |
||
171 | $user['has_error'] = true; |
||
172 | } else { |
||
173 | $classExistList[] = $info['id']; |
||
174 | } |
||
175 | } |
||
176 | } |
||
177 | |||
178 | // 5. Check authentication source |
||
179 | if (!empty($user['AuthSource'])) { |
||
180 | if (!in_array($user['AuthSource'], $defined_auth_sources)) { |
||
181 | $user['message'] .= Display::return_message(get_lang('AuthSourceNotAvailable'), 'warning'); |
||
182 | $user['has_error'] = true; |
||
183 | } |
||
184 | } |
||
185 | } |
||
186 | |||
187 | return $users; |
||
188 | } |
||
189 | |||
190 | /** |
||
191 | * Add missing user-information (which isn't required, like password, username etc). |
||
192 | * |
||
193 | * @param array $user |
||
194 | */ |
||
195 | function complete_missing_data($user) |
||
196 | { |
||
197 | global $purification_option_for_usernames; |
||
198 | |||
199 | $username = isset($user['UserName']) ? $user['UserName'] : ''; |
||
200 | |||
201 | // 1. Create a username if necessary. |
||
202 | if (UserManager::is_username_empty($username)) { |
||
203 | $user['UserName'] = UserManager::create_unique_username( |
||
204 | $user['FirstName'], |
||
205 | $user['LastName'] |
||
206 | ); |
||
207 | } else { |
||
208 | $user['UserName'] = UserManager::purify_username( |
||
209 | $user['UserName'], |
||
210 | $purification_option_for_usernames |
||
211 | ); |
||
212 | } |
||
213 | |||
214 | // 2. Generate a password if necessary. |
||
215 | if (empty($user['Password'])) { |
||
216 | $user['Password'] = api_generate_password(); |
||
217 | } |
||
218 | // 3. Set status if not allready set. |
||
219 | if (empty($user['Status'])) { |
||
220 | $user['Status'] = 'user'; |
||
221 | } |
||
222 | // 4. Set authsource if not allready set. |
||
223 | if (empty($user['AuthSource'])) { |
||
224 | $user['AuthSource'] = PLATFORM_AUTH_SOURCE; |
||
225 | } |
||
226 | |||
227 | if (empty($user['ExpiryDate'])) { |
||
228 | $user['ExpiryDate'] = ''; |
||
229 | } |
||
230 | |||
231 | if (!isset($user['OfficialCode'])) { |
||
232 | $user['OfficialCode'] = ''; |
||
233 | } |
||
234 | |||
235 | if (!isset($user['language'])) { |
||
236 | $user['language'] = ''; |
||
237 | } |
||
238 | |||
239 | if (!isset($user['PhoneNumber'])) { |
||
240 | $user['PhoneNumber'] = ''; |
||
241 | } |
||
242 | |||
243 | if (!isset($user['OfficialCode'])) { |
||
244 | $user['OfficialCode'] = ''; |
||
245 | } |
||
246 | |||
247 | return $user; |
||
248 | } |
||
249 | |||
250 | /** |
||
251 | * Save the imported data. |
||
252 | * |
||
253 | * @param array $users List of users |
||
254 | * @param bool $sendMail |
||
255 | * |
||
256 | * @uses \global variable $inserted_in_course, which returns the list of |
||
257 | * courses the user was inserted in |
||
258 | */ |
||
259 | function save_data( |
||
260 | $users, |
||
261 | $sendMail = false, |
||
262 | $targetFolder = null |
||
263 | ) { |
||
264 | global $inserted_in_course, $extra_fields; |
||
265 | |||
266 | // Not all scripts declare the $inserted_in_course array (although they should). |
||
267 | if (!isset($inserted_in_course)) { |
||
268 | $inserted_in_course = []; |
||
269 | } |
||
270 | |||
271 | if (!empty($targetFolder)) { |
||
272 | $userSaved = []; |
||
273 | $userError = []; |
||
274 | $userWarning = []; |
||
275 | } |
||
276 | |||
277 | $usergroup = new UserGroup(); |
||
278 | if (is_array($users)) { |
||
279 | $efo = new ExtraFieldOption('user'); |
||
280 | |||
281 | $optionsByField = []; |
||
282 | |||
283 | foreach ($users as &$user) { |
||
284 | if ($user['has_error']) { |
||
285 | $userError[] = $user; |
||
286 | continue; |
||
287 | } |
||
288 | |||
289 | $user = complete_missing_data($user); |
||
290 | $user['Status'] = api_status_key($user['Status']); |
||
291 | $redirection = isset($user['Redirection']) ? $user['Redirection'] : ''; |
||
292 | |||
293 | $user_id = UserManager::create_user( |
||
294 | $user['FirstName'], |
||
295 | $user['LastName'], |
||
296 | $user['Status'], |
||
297 | $user['Email'], |
||
298 | $user['UserName'], |
||
299 | $user['Password'], |
||
300 | $user['OfficialCode'], |
||
301 | $user['language'], |
||
302 | $user['PhoneNumber'], |
||
303 | '', |
||
304 | $user['AuthSource'], |
||
305 | $user['ExpiryDate'], |
||
306 | 1, |
||
307 | 0, |
||
308 | null, |
||
309 | null, |
||
310 | $sendMail, |
||
311 | false, |
||
312 | '', |
||
313 | false, |
||
314 | null, |
||
315 | null, |
||
316 | null, |
||
317 | $redirection |
||
318 | ); |
||
319 | |||
320 | if ($user_id) { |
||
321 | $returnMessage = Display::return_message(get_lang('UserAdded'), 'success'); |
||
322 | |||
323 | if (isset($user['Courses']) && is_array($user['Courses'])) { |
||
324 | foreach ($user['Courses'] as $course) { |
||
325 | if (CourseManager::course_exists($course)) { |
||
326 | $result = CourseManager::subscribeUser($user_id, $course, $user['Status']); |
||
327 | if ($result) { |
||
328 | $course_info = api_get_course_info($course); |
||
329 | $inserted_in_course[$course] = $course_info['title']; |
||
330 | } |
||
331 | } |
||
332 | } |
||
333 | } |
||
334 | |||
335 | if (isset($user['Sessions']) && is_array($user['Sessions'])) { |
||
336 | foreach ($user['Sessions'] as $sessionId) { |
||
337 | $sessionInfo = api_get_session_info($sessionId); |
||
338 | if (!empty($sessionInfo)) { |
||
339 | SessionManager::subscribeUsersToSession( |
||
340 | $sessionId, |
||
341 | [$user_id], |
||
342 | SESSION_VISIBLE_READ_ONLY, |
||
343 | false |
||
344 | ); |
||
345 | } |
||
346 | } |
||
347 | } |
||
348 | |||
349 | if (!empty($user['ClassId'])) { |
||
350 | $classId = explode('|', trim($user['ClassId'])); |
||
351 | foreach ($classId as $id) { |
||
352 | $usergroup->subscribe_users_to_usergroup($id, [$user_id], false); |
||
353 | } |
||
354 | } |
||
355 | |||
356 | // We are sure that the extra field exists. |
||
357 | foreach ($extra_fields as $extras) { |
||
358 | if (!isset($user[$extras[1]])) { |
||
359 | continue; |
||
360 | } |
||
361 | |||
362 | $key = $extras[1]; |
||
363 | $value = $user[$key]; |
||
364 | |||
365 | if (!array_key_exists($key, $optionsByField)) { |
||
366 | $optionsByField[$key] = $efo->getOptionsByFieldVariable($key); |
||
367 | } |
||
368 | |||
369 | /** @var ExtraFieldOptions $option */ |
||
370 | foreach ($optionsByField[$key] as $option) { |
||
371 | if ($option->getDisplayText() === $value) { |
||
372 | $value = $option->getValue(); |
||
373 | } |
||
374 | } |
||
375 | |||
376 | UserManager::update_extra_field_value($user_id, $key, $value); |
||
377 | } |
||
378 | $userSaved[] = $user; |
||
379 | } else { |
||
380 | $returnMessage = Display::return_message(get_lang('Error'), 'warning'); |
||
381 | $userWarning[] = $user; |
||
382 | } |
||
383 | $user['message'] = $returnMessage; |
||
384 | } |
||
385 | } |
||
386 | |||
387 | // Save with success, error and warning users |
||
388 | if (!empty($targetFolder)) { |
||
389 | $header = [ |
||
390 | 'id', |
||
391 | 'FirstName', |
||
392 | 'LastName', |
||
393 | 'Status', |
||
394 | 'Email', |
||
395 | 'UserName', |
||
396 | 'message', |
||
397 | ]; |
||
398 | // Save user with success |
||
399 | if (count($userSaved) != 0) { |
||
400 | $csv_content = []; |
||
401 | $csv_row = $header; |
||
402 | $csv_content[] = $csv_row; |
||
403 | foreach ($userSaved as $user) { |
||
404 | $csv_row = []; |
||
405 | $csv_row[] = isset($user['id']) ? $user['id'] : ''; |
||
406 | $csv_row[] = isset($user['FirstName']) ? $user['FirstName'] : ''; |
||
407 | $csv_row[] = isset($user['LastName']) ? $user['LastName'] : ''; |
||
408 | $csv_row[] = isset($user['Status']) ? $user['Status'] : ''; |
||
409 | $csv_row[] = isset($user['Email']) ? $user['Email'] : ''; |
||
410 | $csv_row[] = isset($user['UserName']) ? $user['UserName'] : ''; |
||
411 | $csv_row[] = isset($user['message']) ? strip_tags($user['message']) : ''; |
||
412 | $csv_content[] = $csv_row; |
||
413 | } |
||
414 | saveCsvFile($csv_content, $targetFolder.'user_success_'.count($userSaved)); |
||
415 | } |
||
416 | if (count($userError) != 0) { |
||
417 | // Save user with error |
||
418 | $csv_content = []; |
||
419 | $csv_row = $header; |
||
420 | $csv_content[] = $csv_row; |
||
421 | foreach ($userError as $user) { |
||
422 | $csv_row = []; |
||
423 | $csv_row[] = isset($user['id']) ? $user['id'] : ''; |
||
424 | $csv_row[] = isset($user['FirstName']) ? $user['FirstName'] : ''; |
||
425 | $csv_row[] = isset($user['LastName']) ? $user['LastName'] : ''; |
||
426 | $csv_row[] = isset($user['Status']) ? $user['Status'] : '-'; |
||
427 | $csv_row[] = isset($user['Email']) ? $user['Email'] : ''; |
||
428 | $csv_row[] = isset($user['UserName']) ? $user['UserName'] : ''; |
||
429 | $csv_row[] = isset($user['message']) ? strip_tags($user['message']) : ''; |
||
430 | $csv_content[] = $csv_row; |
||
431 | error_log(print_r($csv_row, 1)); |
||
432 | } |
||
433 | saveCsvFile($csv_content, $targetFolder.'user_error_'.count($userError)); |
||
434 | } |
||
435 | if (count($userWarning) != 0) { |
||
436 | // Save user with warning |
||
437 | $csv_content = []; |
||
438 | $csv_row = $header; |
||
439 | $csv_content[] = $csv_row; |
||
440 | foreach ($userWarning as $user) { |
||
441 | $csv_row = []; |
||
442 | $csv_row[] = isset($user['id']) ? $user['id'] : ''; |
||
443 | $csv_row[] = isset($user['FirstName']) ? $user['FirstName'] : ''; |
||
444 | $csv_row[] = isset($user['LastName']) ? $user['LastName'] : ''; |
||
445 | $csv_row[] = isset($user['Status']) ? $user['Status'] : ''; |
||
446 | $csv_row[] = isset($user['Email']) ? $user['Email'] : ''; |
||
447 | $csv_row[] = isset($user['UserName']) ? $user['UserName'] : ''; |
||
448 | $csv_row[] = isset($user['message']) ? strip_tags($user['message']) : ''; |
||
449 | $csv_content[] = $csv_row; |
||
450 | } |
||
451 | saveCsvFile($csv_content, $targetFolder.'user_warning_'.count($userWarning)); |
||
452 | } |
||
453 | } |
||
454 | |||
455 | return $users; |
||
456 | } |
||
457 | |||
458 | /** |
||
459 | * Save array to a specific file. |
||
460 | * |
||
461 | * @param array $data |
||
462 | * @param $file |
||
463 | * @param string $enclosure |
||
464 | */ |
||
465 | function saveCsvFile($data = [], $file = 'example', $enclosure = '"') |
||
466 | { |
||
467 | $filePath = $file.'.csv'; |
||
468 | $stream = fopen($filePath, 'w'); |
||
469 | $writer = new CsvWriter(';', $enclosure, $stream, true); |
||
470 | $writer->prepare(); |
||
471 | |||
472 | foreach ($data as $item) { |
||
473 | if (empty($item)) { |
||
474 | $writer->writeItem([]); |
||
475 | continue; |
||
476 | } |
||
477 | $item = array_map('trim', $item); |
||
478 | $writer->writeItem($item); |
||
479 | } |
||
480 | $writer->finish(); |
||
481 | |||
482 | return null; |
||
483 | } |
||
484 | |||
485 | /** |
||
486 | * @param array $users |
||
487 | * @param string $fileName |
||
488 | * @param int $sendEmail |
||
489 | * @param bool $checkUniqueEmail |
||
490 | * @param bool $resumeImport |
||
491 | * |
||
492 | * @return array |
||
493 | */ |
||
494 | function parse_csv_data($users, $fileName, $sendEmail = 0, $checkUniqueEmail = true, $resumeImport = false) |
||
495 | { |
||
496 | $usersFromOrigin = $users; |
||
497 | $allowRandom = api_get_configuration_value('generate_random_login'); |
||
498 | if ($allowRandom) { |
||
499 | $factory = new RandomLib\Factory(); |
||
500 | $generator = $factory->getLowStrengthGenerator(); |
||
501 | $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; |
||
502 | } |
||
503 | |||
504 | $readMax = 50; |
||
505 | $userId = api_get_user_id(); |
||
506 | $logMessages = ''; |
||
507 | $importData = Session::read('user_import_data_'.$userId); |
||
508 | if (!empty($importData)) { |
||
509 | $counter = $importData['counter']; |
||
510 | $users = $importData['complete_list']; |
||
511 | $users = array_splice($users, $counter, $readMax); |
||
512 | $logMessages = $importData['log_messages']; |
||
513 | } else { |
||
514 | $users = array_splice($users, 0, $readMax); |
||
515 | } |
||
516 | |||
517 | if ($resumeImport === false) { |
||
518 | $users = $usersFromOrigin; |
||
519 | } |
||
520 | |||
521 | $counter = 0; |
||
522 | foreach ($users as $index => $user) { |
||
523 | if ($resumeImport) { |
||
524 | if ($counter >= $readMax) { |
||
525 | $users = array_splice($users, $counter, $readMax); |
||
526 | break; |
||
527 | } |
||
528 | } |
||
529 | $counter++; |
||
530 | if (empty($user['UserName'])) { |
||
531 | if ($allowRandom) { |
||
532 | $username = $generator->generateString(10, $chars); |
||
533 | $user['UserName'] = $username; |
||
534 | } |
||
535 | } |
||
536 | if (isset($user['Courses'])) { |
||
537 | $user['Courses'] = explode('|', trim($user['Courses'])); |
||
538 | } |
||
539 | |||
540 | if (isset($user['Sessions'])) { |
||
541 | $user['Sessions'] = explode('|', trim($user['Sessions'])); |
||
542 | } |
||
543 | |||
544 | // Lastname is needed. |
||
545 | if (!isset($user['LastName']) || (isset($user['LastName']) && empty($user['LastName']))) { |
||
546 | unset($users[$index]); |
||
547 | continue; |
||
548 | } |
||
549 | |||
550 | // FirstName is needed. |
||
551 | if (!isset($user['FirstName']) || (isset($user['FirstName']) && empty($user['FirstName']))) { |
||
552 | unset($users[$index]); |
||
553 | continue; |
||
554 | } |
||
555 | |||
556 | $users[$index] = $user; |
||
557 | } |
||
558 | |||
559 | $globalCounter = $counter; |
||
560 | if (!empty($importData)) { |
||
561 | $globalCounter = $importData['counter'] + $counter; |
||
562 | } |
||
563 | |||
564 | $importData = [ |
||
565 | 'complete_list' => $usersFromOrigin, |
||
566 | 'filename' => $fileName, |
||
567 | 'counter' => $globalCounter, |
||
568 | 'check_unique_email' => $checkUniqueEmail, |
||
569 | 'send_email' => $sendEmail, |
||
570 | 'date' => api_get_utc_datetime(), |
||
571 | 'log_messages' => $logMessages, |
||
572 | 'resume' => $resumeImport, |
||
573 | ]; |
||
574 | |||
575 | Session::write('user_import_data_'.$userId, $importData); |
||
576 | |||
577 | return $users; |
||
578 | } |
||
579 | |||
580 | /** |
||
581 | * Read the XML-file. |
||
582 | * |
||
583 | * @param string $file Path to the XML-file |
||
584 | * |
||
585 | * @return array All user information read from the file |
||
586 | */ |
||
587 | function parse_xml_data($file, $sendEmail = 0, $checkUniqueEmail = true) |
||
588 | { |
||
589 | $crawler = Import::xml($file); |
||
590 | $crawler = $crawler->filter('Contacts > Contact '); |
||
591 | $array = []; |
||
592 | foreach ($crawler as $domElement) { |
||
593 | $row = []; |
||
594 | foreach ($domElement->childNodes as $node) { |
||
595 | if ($node->nodeName != '#text') { |
||
596 | $row[$node->nodeName] = $node->nodeValue; |
||
597 | } |
||
598 | } |
||
599 | if (!empty($row)) { |
||
600 | $array[] = $row; |
||
601 | } |
||
602 | } |
||
603 | |||
604 | Session::write( |
||
605 | 'user_import_data_'.api_get_user_id(), |
||
606 | [ |
||
607 | 'check_unique_email' => $checkUniqueEmail, |
||
608 | 'send_email' => $sendEmail, |
||
609 | 'date' => api_get_utc_datetime(), |
||
610 | 'log_messages' => '', |
||
611 | ] |
||
612 | ); |
||
613 | |||
614 | return $array; |
||
615 | } |
||
616 | |||
617 | /** |
||
618 | * @param array $users |
||
619 | * @param bool $sendMail |
||
620 | * @param string $targetFolder |
||
621 | */ |
||
622 | function processUsers(&$users, $sendMail, $targetFolder = null) |
||
623 | { |
||
624 | $users = save_data($users, $sendMail, $targetFolder); |
||
625 | |||
626 | $warningMessage = ''; |
||
627 | if (!empty($users)) { |
||
628 | $table = new HTML_Table(['class' => 'table table-responsive']); |
||
629 | $headers = [ |
||
630 | get_lang('User'), |
||
631 | get_lang('Status'), |
||
632 | ]; |
||
633 | $row = 0; |
||
634 | $column = 0; |
||
635 | foreach ($headers as $header) { |
||
636 | $table->setHeaderContents($row, $column, $header); |
||
637 | $column++; |
||
638 | } |
||
639 | $row++; |
||
640 | foreach ($users as $user) { |
||
641 | $column = 0; |
||
642 | $email = isset($user['Email']) ? ' - '.$user['Email'] : null; |
||
643 | $userData = |
||
644 | '<strong>'.$user['UserName'].'</strong> - '. |
||
645 | api_get_person_name( |
||
646 | $user['FirstName'], |
||
647 | $user['LastName'] |
||
648 | ).' '.$email; |
||
649 | $table->setCellContents($row, $column, $userData); |
||
650 | $table->setCellContents($row, ++$column, $user['message']); |
||
651 | $row++; |
||
652 | } |
||
653 | $warningMessage = $table->toHtml(); |
||
654 | } |
||
655 | |||
656 | // if the warning message is too long then we display the warning message trough a session |
||
657 | //Display::addFlash(Display::return_message(get_lang('FileImported'), 'confirmation', false)); |
||
658 | |||
659 | $importData = Session::read('user_import_data_'.api_get_user_id()); |
||
660 | if (!empty($importData)) { |
||
661 | if (isset($importData['log_messages'])) { |
||
662 | $importData['log_messages'] .= $warningMessage; |
||
663 | } else { |
||
664 | $importData['log_messages'] = $warningMessage; |
||
665 | } |
||
666 | Session::write('user_import_data_'.api_get_user_id(), $importData); |
||
667 | } |
||
668 | } |
||
669 | |||
670 | $this_section = SECTION_PLATFORM_ADMIN; |
||
671 | $defined_auth_sources[] = PLATFORM_AUTH_SOURCE; |
||
672 | if (isset($extAuthSource) && is_array($extAuthSource)) { |
||
673 | $defined_auth_sources = array_merge($defined_auth_sources, array_keys($extAuthSource)); |
||
674 | } |
||
675 | |||
676 | $tool_name = get_lang('ImportUserListXMLCSV'); |
||
677 | $interbreadcrumb[] = ['url' => 'index.php', 'name' => get_lang('PlatformAdmin')]; |
||
678 | $reloadImport = (isset($_REQUEST['reload_import']) && (int) $_REQUEST['reload_import'] === 1); |
||
679 | |||
680 | $extra_fields = UserManager::get_extra_fields(0, 0, 5, 'ASC', true); |
||
681 | |||
682 | if (isset($_POST['formSent']) && $_POST['formSent'] && $_FILES['import_file']['size'] !== 0) { |
||
683 | $file_type = $_POST['file_type']; |
||
684 | Security::clear_token(); |
||
685 | $tok = Security::get_token(); |
||
686 | $allowed_file_mimetype = ['csv', 'xml']; |
||
687 | $error_kind_file = true; |
||
688 | |||
689 | $checkUniqueEmail = isset($_POST['check_unique_email']) ? $_POST['check_unique_email'] : null; |
||
690 | $sendMail = $_POST['sendMail'] ? true : false; |
||
691 | $resume = isset($_POST['resume_import']) ? true : false; |
||
692 | $uploadInfo = pathinfo($_FILES['import_file']['name']); |
||
693 | $ext_import_file = $uploadInfo['extension']; |
||
694 | $targetFolder = null; |
||
695 | $users = []; |
||
696 | if (in_array($ext_import_file, $allowed_file_mimetype)) { |
||
697 | if (strcmp($file_type, 'csv') === 0 && |
||
698 | $ext_import_file == $allowed_file_mimetype[0] |
||
699 | ) { |
||
700 | $user = api_get_user_info(); |
||
701 | $userId = (int) $user['id']; |
||
702 | $today = new DateTime(); |
||
703 | $today = $today->format('YmdHis'); |
||
704 | $targetFolder = api_get_configuration_value('root_sys').'app/cache/backup/import_users'; |
||
705 | $targetFolder .= DIRECTORY_SEPARATOR.$userId.DIRECTORY_SEPARATOR.$today; |
||
706 | $targetFolder = createDirectory($targetFolder).DIRECTORY_SEPARATOR; |
||
707 | $originalFile = $targetFolder.$_FILES['import_file']['name']; |
||
708 | // save original file |
||
709 | if (!file_exists($originalFile)) { |
||
710 | touch($originalFile); |
||
711 | file_put_contents($originalFile, file_get_contents($_FILES['import_file']['tmp_name'])); |
||
712 | } |
||
713 | |||
714 | Session::erase('user_import_data_'.$userId); |
||
715 | $users = Import::csvToArray($_FILES['import_file']['tmp_name']); |
||
716 | $users = parse_csv_data( |
||
717 | $users, |
||
718 | $_FILES['import_file']['name'], |
||
719 | $sendMail, |
||
720 | $checkUniqueEmail, |
||
721 | $resume |
||
722 | ); |
||
723 | $users = validate_data($users, $checkUniqueEmail); |
||
724 | $error_kind_file = false; |
||
725 | } elseif (strcmp($file_type, 'xml') === 0 && $ext_import_file == $allowed_file_mimetype[1]) { |
||
726 | $users = parse_xml_data( |
||
727 | $_FILES['import_file']['tmp_name'], |
||
728 | $sendMail, |
||
729 | $checkUniqueEmail |
||
730 | ); |
||
731 | $users = validate_data($users, $checkUniqueEmail); |
||
732 | $error_kind_file = false; |
||
733 | } |
||
734 | |||
735 | processUsers($users, $sendMail, $targetFolder); |
||
736 | |||
737 | if ($error_kind_file) { |
||
738 | Display::addFlash( |
||
739 | Display::return_message( |
||
740 | get_lang('YouMustImportAFileAccordingToSelectedOption'), |
||
741 | 'error', |
||
742 | false |
||
743 | ) |
||
744 | ); |
||
745 | } else { |
||
746 | $reload = ''; |
||
747 | if ($resume) { |
||
748 | $reload = '?reload_import=1'; |
||
749 | } |
||
750 | header('Location: '.api_get_self().$reload); |
||
751 | exit; |
||
752 | } |
||
753 | } else { |
||
754 | Display::addFlash( |
||
755 | Display::return_message( |
||
756 | get_lang('YouMustImportAFileAccordingToSelectedOption'), |
||
757 | 'error', |
||
758 | false |
||
759 | ) |
||
760 | ); |
||
761 | |||
762 | header('Location: '.api_get_self()); |
||
763 | exit; |
||
764 | } |
||
765 | } |
||
766 | |||
767 | $importData = Session::read('user_import_data_'.$userId); |
||
768 | |||
769 | $formContinue = false; |
||
770 | $resumeStop = true; |
||
771 | if (!empty($importData)) { |
||
772 | $isResume = $importData['resume'] ?? false; |
||
773 | |||
774 | $formContinue = new FormValidator('user_import_continue', 'post', api_get_self()); |
||
775 | $label = get_lang('Results'); |
||
776 | if ($isResume) { |
||
777 | $label = get_lang('ContinueLastImport'); |
||
778 | } |
||
779 | $formContinue->addHeader($label); |
||
780 | if (isset($importData['filename'])) { |
||
781 | $formContinue->addLabel(get_lang('File'), $importData['filename'] ?? ''); |
||
782 | } |
||
783 | |||
784 | $resumeStop = true; |
||
785 | if ($isResume) { |
||
786 | $totalUsers = isset($importData['complete_list']) ? count($importData['complete_list']) : 0; |
||
787 | $counter = isset($importData['counter']) ? $importData['counter'] : 0; |
||
788 | $bar = ''; |
||
789 | if (!empty($totalUsers)) { |
||
790 | $bar = Display::bar_progress($counter / $totalUsers * 100); |
||
791 | } |
||
792 | $formContinue->addLabel(get_lang('Status'), $bar); |
||
793 | $formContinue->addLabel( |
||
794 | get_lang('UsersAdded'), |
||
795 | $importData['counter'].' / '.count($importData['complete_list']) |
||
796 | ); |
||
797 | } else { |
||
798 | if (!empty($importData['complete_list'])) { |
||
799 | $formContinue->addLabel( |
||
800 | get_lang('Users'), |
||
801 | count($importData['complete_list']) |
||
802 | ); |
||
803 | } |
||
804 | } |
||
805 | |||
806 | $formContinue->addLabel( |
||
807 | get_lang('CheckUniqueEmail'), |
||
808 | $importData['check_unique_email'] ? get_lang('Yes') : get_lang('No') |
||
809 | ); |
||
810 | $formContinue->addLabel(get_lang('SendMailToUsers'), $importData['send_email'] ? get_lang('Yes') : get_lang('No')); |
||
811 | $formContinue->addLabel(get_lang('Date'), Display::dateToStringAgoAndLongDate($importData['date'])); |
||
812 | |||
813 | if ($isResume) { |
||
814 | $resumeStop = $importData['counter'] >= count($importData['complete_list']); |
||
815 | if ($resumeStop == false) { |
||
816 | $formContinue->addButtonImport(get_lang('ContinueImport'), 'import_continue'); |
||
817 | } |
||
818 | } |
||
819 | |||
820 | $formContinue->addHtml('<br />'.$importData['log_messages']); |
||
821 | |||
822 | if ($formContinue->validate()) { |
||
823 | $users = parse_csv_data( |
||
824 | $importData['complete_list'], |
||
825 | $importData['filename'], |
||
826 | $importData['send_email'], |
||
827 | $importData['check_unique_email'], |
||
828 | true |
||
829 | ); |
||
830 | $users = validate_data($users, $importData['check_unique_email']); |
||
831 | |||
832 | processUsers($users, $importData['send_email']); |
||
833 | |||
834 | $reload = ''; |
||
835 | if ($isResume && $resumeStop === false) { |
||
836 | $reload = '?reload_import=1'; |
||
837 | } |
||
838 | |||
839 | header('Location: '.api_get_self().$reload); |
||
840 | exit; |
||
841 | } |
||
842 | } |
||
843 | |||
844 | Display::display_header($tool_name); |
||
845 | |||
846 | $form = new FormValidator('user_import', 'post', api_get_self()); |
||
847 | $form->addHeader($tool_name); |
||
848 | $form->addElement('hidden', 'formSent'); |
||
849 | $form->addElement('file', 'import_file', get_lang('ImportFileLocation')); |
||
850 | $group = [ |
||
851 | $form->createElement( |
||
852 | 'radio', |
||
853 | 'file_type', |
||
854 | '', |
||
855 | 'CSV (<a href="example.csv" target="_blank" download>'.get_lang('ExampleCSVFile').'</a>)', |
||
856 | 'csv' |
||
857 | ), |
||
858 | $form->createElement( |
||
859 | 'radio', |
||
860 | 'file_type', |
||
861 | null, |
||
862 | 'XML (<a href="example.xml" target="_blank" download>'.get_lang('ExampleXMLFile').'</a>)', |
||
863 | 'xml' |
||
864 | ), |
||
865 | ]; |
||
866 | |||
867 | $form->addGroup($group, '', get_lang('FileType')); |
||
868 | |||
869 | $group = [ |
||
870 | $form->createElement('radio', 'sendMail', '', get_lang('Yes'), 1), |
||
871 | $form->createElement('radio', 'sendMail', null, get_lang('No'), 0), |
||
872 | ]; |
||
873 | $form->addGroup($group, '', get_lang('SendMailToUsers')); |
||
874 | |||
875 | $form->addElement( |
||
876 | 'checkbox', |
||
877 | 'check_unique_email', |
||
878 | '', |
||
879 | get_lang('CheckUniqueEmail') |
||
880 | ); |
||
881 | |||
882 | $form->addElement( |
||
883 | 'checkbox', |
||
884 | 'resume_import', |
||
885 | '', |
||
886 | get_lang('ResumeImport') |
||
887 | ); |
||
888 | |||
889 | $form->addButtonImport(get_lang('Import')); |
||
890 | |||
891 | $defaults['formSent'] = 1; |
||
892 | $defaults['sendMail'] = 0; |
||
893 | $defaults['file_type'] = 'csv'; |
||
894 | |||
895 | $extraSettings = api_get_configuration_value('user_import_settings'); |
||
896 | if (!empty($extraSettings) && isset($extraSettings['options']) && |
||
897 | isset($extraSettings['options']['send_mail_default_option']) |
||
898 | ) { |
||
899 | $defaults['sendMail'] = $extraSettings['options']['send_mail_default_option']; |
||
900 | } |
||
901 | |||
902 | $form->setDefaults($defaults); |
||
903 | if (is_dir(api_get_path(SYS_ARCHIVE_PATH).'backup/import_users')) { |
||
904 | // only show if backup exist |
||
905 | $form->addHtml("<a href='./download_import_users.php'>".get_lang('ViewHistoryChange')."</a>"); |
||
906 | } |
||
907 | $form->display(); |
||
908 | |||
909 | if ($formContinue) { |
||
910 | $formContinue->display(); |
||
911 | } |
||
912 | |||
913 | if ($reloadImport) { |
||
914 | echo '<script> |
||
915 | $(function() { |
||
916 | function reload() { |
||
917 | $("#user_import_continue").submit(); |
||
918 | } |
||
919 | setTimeout(reload, 3000); |
||
920 | }); |
||
921 | </script>'; |
||
922 | } |
||
923 | |||
924 | $list = []; |
||
925 | $list_reponse = []; |
||
926 | $result_xml = ''; |
||
927 | $i = 0; |
||
928 | $count_fields = count($extra_fields); |
||
929 | if ($count_fields > 0) { |
||
930 | foreach ($extra_fields as $extra) { |
||
931 | $list[] = $extra[1]; |
||
932 | $list_reponse[] = 'xxx'; |
||
933 | $spaces = ' '; |
||
934 | $result_xml .= $spaces.'<'.$extra[1].'>xxx</'.$extra[1].'>'; |
||
935 | if ($i != $count_fields - 1) { |
||
936 | $result_xml .= '<br/>'; |
||
937 | } |
||
938 | $i++; |
||
939 | } |
||
940 | } |
||
941 | |||
942 | if (api_get_configuration_value('plugin_redirection_enabled')) { |
||
943 | $list[] = 'Redirection'; |
||
944 | $list_reponse[] = api_get_path(WEB_PATH); |
||
945 | } |
||
946 | |||
947 | ?> |
||
948 | <p><?php echo get_lang('CSVMustLookLike').' ('.get_lang('MandatoryFields').')'; ?> :</p> |
||
949 | <blockquote> |
||
950 | <pre> |
||
951 | <b>LastName</b>;<b>FirstName</b>;<b>Email</b>;UserName;Password;AuthSource;OfficialCode;language;PhoneNumber;Status;ExpiryDate;<span style="color:red;"><?php if (count($list) > 0) { |
||
952 | echo implode(';', $list).';'; |
||
953 | } ?></span>Courses;Sessions;ClassId; |
||
954 | <b>xxx</b>;<b>xxx</b>;<b>xxx</b>;xxx;xxx;<?php echo implode('/', $defined_auth_sources); ?>;xxx;english/spanish/(other);xxx;user/teacher/drh;0000-00-00 00:00:00;<span style="color:red;"><?php if (count($list_reponse) > 0) { |
||
955 | echo implode(';', $list_reponse).';'; |
||
956 | } ?></span>xxx1|xxx2|xxx3;sessionId|sessionId|sessionId;1;<br /> |
||
957 | </pre> |
||
958 | </blockquote> |
||
959 | <p><?php echo get_lang('XMLMustLookLike').' ('.get_lang('MandatoryFields').')'; ?> :</p> |
||
960 | <blockquote> |
||
961 | <pre> |
||
962 | <?xml version="1.0" encoding="UTF-8"?> |
||
963 | <Contacts> |
||
964 | <Contact> |
||
965 | <b><LastName>xxx</LastName></b> |
||
966 | <b><FirstName>xxx</FirstName></b> |
||
967 | <UserName>xxx</UserName> |
||
968 | <Password>xxx</Password> |
||
969 | <AuthSource><?php echo implode('/', $defined_auth_sources); ?></AuthSource> |
||
970 | <b><Email>xxx</Email></b> |
||
971 | <OfficialCode>xxx</OfficialCode> |
||
972 | <language>english/spanish/(other)</language> |
||
973 | <PhoneNumber>xxx</PhoneNumber> |
||
974 | <Status>user/teacher/drh</Status><?php if ($result_xml != '') { |
||
975 | echo '<br /><span style="color:red;">', $result_xml; |
||
976 | echo '</span><br />'; |
||
977 | } ?> |
||
978 | <Courses>xxx1|xxx2|xxx3</Courses> |
||
979 | <Sessions>sessionId|sessionId|sessionId</Sessions> |
||
980 | <ClassId>1</ClassId> |
||
981 | </Contact> |
||
982 | </Contacts> |
||
983 | </pre> |
||
984 | </blockquote> |
||
985 | <?php |
||
986 | Display::display_footer(); |
||
987 |