user_import.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. <?php
  2. // $Id: user_import.php 13774 2007-11-26 08:23:42Z elixir_julian $
  3. /*
  4. ==============================================================================
  5. Dokeos - elearning and course management software
  6. Copyright (c) 2004 Dokeos S.A.
  7. Copyright (c) 2003 Ghent University (UGent)
  8. Copyright (c) 2001 Universite catholique de Louvain (UCL)
  9. Copyright (c) Olivier Brouckaert
  10. Copyright (c) 2005 Bart Mollet <bart.mollet@hogent.be>
  11. For a full list of contributors, see "credits.txt".
  12. The full license can be read in "license.txt".
  13. This program is free software; you can redistribute it and/or
  14. modify it under the terms of the GNU General Public License
  15. as published by the Free Software Foundation; either version 2
  16. of the License, or (at your option) any later version.
  17. See the GNU General Public License for more details.
  18. Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
  19. ==============================================================================
  20. */
  21. /**
  22. ==============================================================================
  23. * This tool allows platform admins to add users by uploading a CSV or XML file
  24. * @todo Add some langvars to DLTT
  25. * @package dokeos.admin
  26. ==============================================================================
  27. */
  28. /**
  29. * validate the imported data
  30. */
  31. function validate_data($users)
  32. {
  33. global $defined_auth_sources;
  34. $errors = array ();
  35. $usernames = array ();
  36. foreach ($users as $index => $user)
  37. {
  38. //1. check if mandatory fields are set
  39. $mandatory_fields = array ('LastName', 'FirstName');
  40. if (api_get_setting('registration', 'email') == 'true')
  41. {
  42. $mandatory_fields[] = 'Email';
  43. }
  44. foreach ($mandatory_fields as $key => $field)
  45. {
  46. if (!isset ($user[$field]) || strlen($user[$field]) == 0)
  47. {
  48. $user['error'] = get_lang($field.'Mandatory');
  49. $errors[] = $user;
  50. }
  51. }
  52. //2. check username
  53. if (isset ($user['UserName']) && strlen($user['UserName']) != 0)
  54. {
  55. //2.1. check if no username was used twice in import file
  56. if (isset ($usernames[$user['UserName']]))
  57. {
  58. $user['error'] = get_lang('UserNameUsedTwice');
  59. $errors[] = $user;
  60. }
  61. $usernames[$user['UserName']] = 1;
  62. //2.2. check if username isn't allready in use in database
  63. if (!UserManager :: is_username_available($user['UserName']))
  64. {
  65. $user['error'] = get_lang('UserNameNotAvailable');
  66. $errors[] = $user;
  67. }
  68. //2.3. check if username isn't longer than the 20 allowed characters
  69. if (strlen($user['UserName']) > 20)
  70. {
  71. $user['error'] = get_lang('UserNameTooLong');
  72. $errors[] = $user;
  73. }
  74. }
  75. //3. check status
  76. if (isset ($user['Status']) && ($user['Status'] != 'user' && $user['Status'] != 'teacher' && $user['Status'] != COURSEMANAGER && $user['Status'] != STUDENT))
  77. {
  78. $user['error'] = get_lang('WrongStatus');
  79. $errors[] = $user;
  80. }
  81. //4. Check classname
  82. if (isset ($user['ClassName']) && strlen($user['ClassName']) != 0)
  83. {
  84. if (!ClassManager :: class_name_exists($user['ClassName']))
  85. {
  86. $user['error'] = get_lang('ClassNameNotAvailable');
  87. $errors[] = $user;
  88. }
  89. }
  90. //5. Check authentication source
  91. if (isset ($user['AuthSource']) && strlen($user['AuthSource']) != 0)
  92. {
  93. if (!in_array($user['AuthSource'], $defined_auth_sources))
  94. {
  95. $user['error'] = get_lang('AuthSourceNotAvailable');
  96. $errors[] = $user;
  97. }
  98. }
  99. }
  100. return $errors;
  101. }
  102. /**
  103. * Add missing user-information (which isn't required, like password, username
  104. * etc)
  105. */
  106. function complete_missing_data($user)
  107. {
  108. //1. Create a username if necessary
  109. if (!isset ($user['UserName']) || strlen($user['UserName']) == 0)
  110. {
  111. $username = strtolower(ereg_replace('[^a-zA-Z]', '', substr($user['FirstName'], 0, 3).' '.substr($user['LastName'], 0, 4)));
  112. if (!UserManager :: is_username_available($username))
  113. {
  114. $i = 0;
  115. $temp_username = $username.$i;
  116. while (!UserManager :: is_username_available($temp_username))
  117. {
  118. $temp_username = $username.++$i;
  119. }
  120. $username = $temp_username;
  121. }
  122. $user['UserName'] = $username;
  123. }
  124. //2. generate a password if necessary
  125. if (!isset ($user['Password']) || strlen($user['Password']) == 0)
  126. {
  127. $user['Password'] = api_generate_password();
  128. }
  129. //3. set status if not allready set
  130. if (!isset ($user['Status']) || strlen($user['Status']) == 0)
  131. {
  132. $user['Status'] = 'user';
  133. }
  134. //4. set authsource if not allready set
  135. if (!isset ($user['AuthSource']) || strlen($user['AuthSource']) == 0)
  136. {
  137. $user['AuthSource'] = PLATFORM_AUTH_SOURCE;
  138. }
  139. return $user;
  140. }
  141. /**
  142. * Save the imported data
  143. */
  144. function save_data($users)
  145. {
  146. $user_table = Database :: get_main_table(TABLE_MAIN_USER);
  147. $sendMail = $_POST['sendMail'] ? 1 : 0;
  148. foreach ($users as $index => $user)
  149. {
  150. $user = complete_missing_data($user);
  151. if($user['Status'] == 'user'){
  152. $user['Status'] = STUDENT;
  153. }
  154. elseif($user['Status'] == 'teacher'){
  155. $user['Status'] = COURSEMANAGER;
  156. }
  157. $user_id = UserManager :: create_user($user['FirstName'], $user['LastName'], $user['Status'], $user['Email'], $user['UserName'], $user['Password'], $user['OfficialCode'], '', $user['PhoneNumber'], '', $user['AuthSource']);
  158. foreach ($user['Courses'] as $index => $course)
  159. {
  160. CourseManager :: subscribe_user($user_id, $course,$user['Status']);
  161. }
  162. if (strlen($user['ClassName']) > 0)
  163. {
  164. $class_id = ClassManager :: get_class_id($user['ClassName']);
  165. ClassManager :: add_user($user_id, $class_id);
  166. }
  167. if ($sendMail)
  168. {
  169. $emailto = '"'.$user['FirstName'].' '.$user['LastName'].'" <'.$user['Email'].'>';
  170. $emailsubject = '['.get_setting('siteName').'] '.get_lang('YourReg').' '.get_setting('siteName');
  171. $emailbody = get_lang('Dear').$user['FirstName'].' '.$user['LastName'].",\n\n".get_lang('YouAreReg')." ".get_setting('siteName')." ".get_lang('Settings')." $user[UserName]\n".get_lang('Pass')." : $user[Password]\n\n".get_lang('Address')." ".get_setting('siteName')." ".get_lang('Is')." : ".api_get_path('WEB_PATH')." \n\n".get_lang('Problem')."\n\n".get_lang('Formula').",\n\n".get_setting('administratorName')." ".get_setting('administratorSurname')."\n".get_lang('Manager')." ".get_setting('siteName')."\nT. ".get_setting('administratorTelephone')."\n".get_lang('Email')." : ".get_setting('emailAdministrator')."";
  172. $emailheaders = 'From: '.get_setting('administratorName').' '.get_setting('administratorSurname').' <'.get_setting('emailAdministrator').">\n";
  173. $emailheaders .= 'Reply-To: '.get_setting('emailAdministrator');
  174. @ api_send_mail($emailto, $emailsubject, $emailbody, $emailheaders);
  175. }
  176. }
  177. }
  178. /**
  179. * Read the CSV-file
  180. * @param string $file Path to the CSV-file
  181. * @return array All userinformation read from the file
  182. */
  183. function parse_csv_data($file)
  184. {
  185. $users = Import :: csv_to_array($file);
  186. foreach ($users as $index => $user)
  187. {
  188. if (isset ($user['Courses']))
  189. {
  190. $user['Courses'] = explode('|', trim($user['Courses']));
  191. }
  192. $users[$index] = $user;
  193. }
  194. return $users;
  195. }
  196. /**
  197. * XML-parser: handle start of element
  198. */
  199. function element_start($parser, $data)
  200. {
  201. global $user;
  202. global $current_tag;
  203. switch ($data)
  204. {
  205. case 'Contact' :
  206. $user = array ();
  207. break;
  208. default :
  209. $current_tag = $data;
  210. }
  211. }
  212. /**
  213. * XML-parser: handle end of element
  214. */
  215. function element_end($parser, $data)
  216. {
  217. global $user;
  218. global $users;
  219. global $current_value;
  220. switch ($data)
  221. {
  222. case 'Contact' :
  223. if ($user['Status'] == '5')
  224. {
  225. $user['Status'] = STUDENT;
  226. }
  227. if ($user['Status'] == '1')
  228. {
  229. $user['Status'] = COURSEMANAGER;
  230. }
  231. $users[] = $user;
  232. break;
  233. default :
  234. $user[$data] = $current_value;
  235. break;
  236. }
  237. }
  238. /**
  239. * XML-parser: handle character data
  240. */
  241. function character_data($parser, $data)
  242. {
  243. global $current_value;
  244. $current_value = $data;
  245. }
  246. /**
  247. * Read the XML-file
  248. * @param string $file Path to the XML-file
  249. * @return array All userinformation read from the file
  250. */
  251. function parse_xml_data($file)
  252. {
  253. global $current_tag;
  254. global $current_value;
  255. global $user;
  256. global $users;
  257. $users = array ();
  258. $parser = xml_parser_create();
  259. xml_set_element_handler($parser, 'element_start', 'element_end');
  260. xml_set_character_data_handler($parser, "character_data");
  261. xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
  262. xml_parse($parser, file_get_contents($file));
  263. xml_parser_free($parser);
  264. return $users;
  265. }
  266. // name of the language file that needs to be included
  267. $language_file = array ('admin', 'registration');
  268. $cidReset = true;
  269. include ('../inc/global.inc.php');
  270. $this_section = SECTION_PLATFORM_ADMIN;
  271. api_protect_admin_script();
  272. require_once (api_get_path(LIBRARY_PATH).'fileManage.lib.php');
  273. require_once (api_get_path(LIBRARY_PATH).'usermanager.lib.php');
  274. require_once (api_get_path(LIBRARY_PATH).'classmanager.lib.php');
  275. require_once (api_get_path(LIBRARY_PATH).'import.lib.php');
  276. require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
  277. $formSent = 0;
  278. $errorMsg = '';
  279. $defined_auth_sources[] = PLATFORM_AUTH_SOURCE;
  280. if (is_array($extAuthSource))
  281. {
  282. $defined_auth_sources = array_merge($defined_auth_sources, array_keys($extAuthSource));
  283. }
  284. $tool_name = get_lang('ImportUserListXMLCSV');
  285. $interbreadcrumb[] = array ("url" => 'index.php', "name" => get_lang('PlatformAdmin'));
  286. set_time_limit(0);
  287. if ($_POST['formSent'] AND $_FILES['import_file']['size'] !== 0)
  288. {
  289. $file_type = $_POST['file_type'];
  290. if ($file_type == 'csv')
  291. {
  292. $users = parse_csv_data($_FILES['import_file']['tmp_name']);
  293. }
  294. else
  295. {
  296. $users = parse_xml_data($_FILES['import_file']['tmp_name']);
  297. }
  298. $errors = validate_data($users);
  299. if (count($errors) == 0)
  300. {
  301. save_data($users);
  302. header('Location: user_list.php?action=show_message&message='.urlencode(get_lang('FileImported')));
  303. exit ();
  304. }
  305. }
  306. Display :: display_header($tool_name);
  307. //api_display_tool_title($tool_name);
  308. if($_FILES['import_file']['size'] == 0 AND $_POST)
  309. {
  310. Display::display_error_message(get_lang('ThisFieldIsRequired'));
  311. }
  312. if (count($errors) != 0)
  313. {
  314. $error_message = '<ul>';
  315. foreach ($errors as $index => $error_user)
  316. {
  317. $error_message .= '<li><b>'.$error_user['error'].'</b>: ';
  318. $error_message .= $error_user['FirstName'].' '.$error_user['LastName'];
  319. $error_message .= '</li>';
  320. }
  321. $error_message .= '</ul>';
  322. Display :: display_error_message($error_message, false);
  323. }
  324. $form = new FormValidator('user_import');
  325. $form->addElement('hidden', 'formSent');
  326. $form->addElement('file', 'import_file', get_lang('ImportFileLocation'));
  327. $form->addRule('import_file', get_lang('ThisFieldIsRequired'), 'required');
  328. $allowed_file_types = array ('xml', 'csv');
  329. $form->addRule('file', get_lang('InvalidExtension').' ('.implode(',', $allowed_file_types).')', 'filetype', $allowed_file_types);
  330. $form->addElement('radio', 'file_type', get_lang('FileType'), 'XML (<a href="exemple.xml" target="_blank">'.get_lang('ExampleXMLFile').'</a>)', 'xml');
  331. $form->addElement('radio', 'file_type', null, 'CSV (<a href="exemple.csv" target="_blank">'.get_lang('ExampleCSVFile').'</a>)', 'csv');
  332. $form->addElement('radio', 'sendMail', get_lang('SendMailToUsers'), get_lang('Yes'), 1);
  333. $form->addElement('radio', 'sendMail', null, get_lang('No'), 0);
  334. $form->addElement('submit', 'submit', get_lang('Ok'));
  335. $defaults['formSent'] = 1;
  336. $defaults['file_type'] = 'xml';
  337. $form->setDefaults($defaults);
  338. $form->display();
  339. ?>
  340. <p><?php echo get_lang('CSVMustLookLike').' ('.get_lang('MandatoryFields').')'; ?> :</p>
  341. <blockquote>
  342. <pre>
  343. <b>LastName</b>;<b>FirstName</b>;UserName;Password;AuthSource;<b>Email</b>;OfficialCode;PhoneNumber;Status;Courses;ClassName
  344. <b>xxx</b>;<b>xxx</b>;xxx;xxx;<?php echo implode('/',$defined_auth_sources); ?>;<b>xxx</b>;xxx;xxx;user/teacher;xxx1|xxx2|xxx3;xxx
  345. </pre>
  346. </blockquote>
  347. <p><?php echo get_lang('XMLMustLookLike').' ('.get_lang('MandatoryFields').')'; ?> :</p>
  348. <blockquote>
  349. <pre>
  350. &lt;?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?&gt;
  351. &lt;Contacts&gt;
  352. &lt;Contact&gt;
  353. <b>&lt;LastName&gt;xxx&lt;/LastName&gt;</b>
  354. <b>&lt;FirstName&gt;xxx&lt;/FirstName&gt;</b>
  355. &lt;UserName&gt;xxx&lt;/UserName&gt;
  356. &lt;Password&gt;xxx&lt;/Password&gt;
  357. &lt;AuthSource&gt;<?php echo implode('/',$defined_auth_sources); ?>&lt;/AuthSource&gt;
  358. <b>&lt;Email&gt;xxx&lt;/Email&gt;</b>
  359. &lt;OfficialCode&gt;xxx&lt;/OfficialCode&gt;
  360. &lt;PhoneNumber&gt;xxx&lt;/PhoneNumber&gt;
  361. &lt;Status&gt;user/teacher&lt;/Status&gt;
  362. &lt;Courses&gt;xxx1|xxx2|xxx3&lt;/Courses&gt;
  363. &lt;ClassName&gt;class 1&lt;/ClassName&gt;
  364. &lt;/Contact&gt;
  365. &lt;/Contacts&gt;
  366. </pre>
  367. </blockquote>
  368. <?php
  369. /*
  370. ==============================================================================
  371. FOOTER
  372. ==============================================================================
  373. */
  374. Display :: display_footer();
  375. ?>