profile.php 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * This file displays the user's profile,
  5. * optionally it allows users to modify their profile as well.
  6. *
  7. * See inc/conf/profile.conf.php to modify settings
  8. *
  9. * @package chamilo.auth
  10. */
  11. use Chamilo\UserBundle\Entity\User;
  12. use ChamiloSession as Session;
  13. $cidReset = true;
  14. require_once '../inc/global.inc.php';
  15. if (api_get_setting('allow_social_tool') == 'true') {
  16. $this_section = SECTION_SOCIAL;
  17. } else {
  18. $this_section = SECTION_MYPROFILE;
  19. }
  20. //$htmlHeadXtra[] = api_get_password_checker_js('#username', '#password1');
  21. $_SESSION['this_section'] = $this_section;
  22. if (!(isset($_user['user_id']) && $_user['user_id']) || api_is_anonymous($_user['user_id'], true)) {
  23. api_not_allowed(true);
  24. }
  25. $userGeolocalization = api_get_setting('enable_profile_user_address_geolocalization') == 'true';
  26. $htmlHeadXtra[] = api_get_password_checker_js('#username', '#password1');
  27. $htmlHeadXtra[] = '<link href="'. api_get_path(WEB_PATH) .'web/assets/cropper/dist/cropper.min.css" rel="stylesheet">';
  28. $htmlHeadXtra[] = '<script src="'. api_get_path(WEB_PATH) .'web/assets/cropper/dist/cropper.min.js"></script>';
  29. $htmlHeadXtra[] = '<script type="text/javascript" src="//maps.googleapis.com/maps/api/js?sensor=true" ></script>';
  30. $htmlHeadXtra[] = '<script>
  31. $(document).ready(function() {
  32. var $image = $("#previewImage");
  33. var $input = $("[name=\'cropResult\']");
  34. var $cropButton = $("#cropButton");
  35. $("input:file").change(function() {
  36. var oFReader = new FileReader();
  37. oFReader.readAsDataURL(document.getElementById("picture_form").files[0]);
  38. oFReader.onload = function (oFREvent) {
  39. $image.attr("src", this.result);
  40. $("#labelCropImage").html("'.get_lang('Preview').'");
  41. $("#cropImage").addClass("thumbnail");
  42. $cropButton.removeClass("hidden");
  43. // Destroy cropper
  44. $image.cropper("destroy");
  45. $image.cropper({
  46. aspectRatio: 1 / 1,
  47. responsive : true,
  48. center : false,
  49. guides : false,
  50. movable: false,
  51. zoomable: false,
  52. rotatable: false,
  53. scalable: false,
  54. crop: function(e) {
  55. // Output the result data for cropping image.
  56. $input.val(e.x+","+e.y+","+e.width+","+e.height);
  57. }
  58. });
  59. };
  60. });
  61. $("#cropButton").on("click", function() {
  62. var canvas = $image.cropper("getCroppedCanvas");
  63. var dataUrl = canvas.toDataURL();
  64. $image.attr("src", dataUrl);
  65. $image.cropper("destroy");
  66. $cropButton.addClass("hidden");
  67. return false;
  68. });
  69. $("id_generate_api_key").on("click", function (e) {
  70. e.preventDefault();
  71. $.ajax({
  72. contentType: "application/x-www-form-urlencoded",
  73. type: "POST",
  74. url: "'.api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php?a=generate_api_key",
  75. data: "num_key_id="+"",
  76. success: function(datos) {
  77. $("#div_api_key").html(datos);
  78. }
  79. });
  80. });
  81. });
  82. function confirmation(name) {
  83. if (confirm("'.get_lang('AreYouSureToDeleteJS', '').' " + name + " ?")) {
  84. document.forms["profile"].submit();
  85. } else {
  86. return false;
  87. }
  88. }
  89. function show_image(image,width,height) {
  90. width = parseInt(width) + 20;
  91. height = parseInt(height) + 20;
  92. window_x = window.open(image,\'windowX\',\'width=\'+ width + \', height=\'+ height + \'\');
  93. }
  94. function hide_icon_edit(element_html) {
  95. ident="#edit_image";
  96. $(ident).hide();
  97. }
  98. function show_icon_edit(element_html) {
  99. ident="#edit_image";
  100. $(ident).show();
  101. }
  102. </script>';
  103. $warning_msg = '';
  104. if (!empty($_GET['fe'])) {
  105. $warning_msg .= get_lang('UplUnableToSaveFileFilteredExtension');
  106. $_GET['fe'] = null;
  107. }
  108. $jquery_ready_content = '';
  109. if (api_get_setting('allow_message_tool') == 'true') {
  110. $jquery_ready_content = <<<EOF
  111. $(".message-content .message-delete").click(function(){
  112. $(this).parents(".message-content").animate({ opacity: "hide" }, "slow");
  113. $(".message-view").animate({ opacity: "show" }, "slow");
  114. });
  115. EOF;
  116. }
  117. $tool_name = is_profile_editable() ? get_lang('ModifProfile') : get_lang('ViewProfile');
  118. $table_user = Database :: get_main_table(TABLE_MAIN_USER);
  119. /*
  120. * Get initial values for all fields.
  121. */
  122. $user_data = api_get_user_info(api_get_user_id());
  123. $array_list_key = UserManager::get_api_keys(api_get_user_id());
  124. $id_temp_key = UserManager::get_api_key_id(api_get_user_id(), 'dokeos');
  125. $value_array = $array_list_key[$id_temp_key];
  126. $user_data['api_key_generate'] = $value_array;
  127. if ($userGeolocalization) {
  128. $htmlHeadXtra[] = '<script>
  129. $(document).ready(function() {
  130. var address = "' . $user_data['address'] . '";
  131. initializeGeo(address, false);
  132. $("#geolocalization").on("click", function() {
  133. var address = $("#address").val();
  134. initializeGeo(address, false);
  135. return false;
  136. });
  137. $("#myLocation").on("click", function() {
  138. myLocation();
  139. return false;
  140. });
  141. $("#address").keypress(function (event) {
  142. if (event.which == 13) {
  143. $("#geolocalization").click();
  144. return false;
  145. }
  146. });
  147. });
  148. function myLocation() {
  149. if (navigator.geolocation) {
  150. var geoPosition = function(position) {
  151. var lat = position.coords.latitude;
  152. var lng = position.coords.longitude;
  153. var latLng = new google.maps.LatLng(lat, lng);
  154. initializeGeo(false, latLng)
  155. };
  156. var geoError = function(error) {
  157. alert("Geocode ' . get_lang('Error') . ': " + error);
  158. };
  159. var geoOptions = {
  160. enableHighAccuracy: true
  161. };
  162. navigator.geolocation.getCurrentPosition(geoPosition, geoError, geoOptions);
  163. }
  164. }
  165. function initializeGeo(address, latLng) {
  166. var geocoder = new google.maps.Geocoder();
  167. var latlng = new google.maps.LatLng(-34.397, 150.644);
  168. var myOptions = {
  169. zoom: 15,
  170. center: latlng,
  171. mapTypeControl: true,
  172. mapTypeControlOptions: {
  173. style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
  174. },
  175. navigationControl: true,
  176. mapTypeId: google.maps.MapTypeId.ROADMAP
  177. };
  178. map = new google.maps.Map(document.getElementById("map"), myOptions);
  179. var parameter = address ? { "address": address } : latLng ? { "latLng": latLng } : false;
  180. if (geocoder && parameter) {
  181. geocoder.geocode(parameter, function(results, status) {
  182. if (status == google.maps.GeocoderStatus.OK) {
  183. if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
  184. map.setCenter(results[0].geometry.location);
  185. if (!address) {
  186. $("#address").val(results[0].formatted_address);
  187. }
  188. var infowindow = new google.maps.InfoWindow({
  189. content: "<b>" + $("#address").val() + "</b>",
  190. size: new google.maps.Size(150, 50)
  191. });
  192. var marker = new google.maps.Marker({
  193. position: results[0].geometry.location,
  194. map: map,
  195. title: $("#address").val()
  196. });
  197. google.maps.event.addListener(marker, "click", function() {
  198. infowindow.open(map, marker);
  199. });
  200. } else {
  201. alert("' . get_lang("NotFound") . '");
  202. }
  203. } else {
  204. alert("Geocode ' . get_lang('Error') . ': " + status);
  205. }
  206. });
  207. }
  208. }
  209. </script>';
  210. }
  211. if ($user_data !== false) {
  212. if (api_get_setting('login_is_email') == 'true') {
  213. $user_data['username'] = $user_data['email'];
  214. }
  215. if (is_null($user_data['language'])) {
  216. $user_data['language'] = api_get_setting('platformLanguage');
  217. }
  218. }
  219. /*
  220. * Initialize the form.
  221. */
  222. $form = new FormValidator(
  223. 'profile',
  224. 'post',
  225. api_get_self()."?".str_replace('&fe=1', '', Security::remove_XSS($_SERVER['QUERY_STRING'])),
  226. null
  227. );
  228. if (api_is_western_name_order()) {
  229. // FIRST NAME and LAST NAME
  230. $form->addElement('text', 'firstname', get_lang('FirstName'), array('size' => 40));
  231. $form->addElement('text', 'lastname', get_lang('LastName'), array('size' => 40));
  232. } else {
  233. // LAST NAME and FIRST NAME
  234. $form->addElement('text', 'lastname', get_lang('LastName'), array('size' => 40));
  235. $form->addElement('text', 'firstname', get_lang('FirstName'), array('size' => 40));
  236. }
  237. if (api_get_setting('profile', 'name') !== 'true') {
  238. $form->freeze(array('lastname', 'firstname'));
  239. }
  240. $form->applyFilter(array('lastname', 'firstname'), 'stripslashes');
  241. $form->applyFilter(array('lastname', 'firstname'), 'trim');
  242. $form->applyFilter(array('lastname', 'firstname'), 'html_filter');
  243. $form->addRule('lastname' , get_lang('ThisFieldIsRequired'), 'required');
  244. $form->addRule('firstname', get_lang('ThisFieldIsRequired'), 'required');
  245. // USERNAME
  246. $form->addElement(
  247. 'text',
  248. 'username',
  249. get_lang('UserName'),
  250. array(
  251. 'id' => 'username',
  252. 'maxlength' => USERNAME_MAX_LENGTH,
  253. 'size' => USERNAME_MAX_LENGTH,
  254. )
  255. );
  256. if (api_get_setting('profile', 'login') !== 'true' || api_get_setting('login_is_email') == 'true') {
  257. $form->freeze('username');
  258. }
  259. $form->applyFilter('username', 'stripslashes');
  260. $form->applyFilter('username', 'trim');
  261. $form->addRule('username', get_lang('ThisFieldIsRequired'), 'required');
  262. $form->addRule('username', get_lang('UsernameWrong'), 'username');
  263. $form->addRule('username', get_lang('UserTaken'), 'username_available', $user_data['username']);
  264. // OFFICIAL CODE
  265. if (CONFVAL_ASK_FOR_OFFICIAL_CODE) {
  266. $form->addElement('text', 'official_code', get_lang('OfficialCode'), array('size' => 40));
  267. if (api_get_setting('profile', 'officialcode') !== 'true') {
  268. $form->freeze('official_code');
  269. }
  270. $form->applyFilter('official_code', 'stripslashes');
  271. $form->applyFilter('official_code', 'trim');
  272. $form->applyFilter('official_code', 'html_filter');
  273. if (api_get_setting('registration', 'officialcode') == 'true' && api_get_setting('profile', 'officialcode') == 'true') {
  274. $form->addRule('official_code', get_lang('ThisFieldIsRequired'), 'required');
  275. }
  276. }
  277. // EMAIL
  278. $form->addElement('email', 'email', get_lang('Email'), array('size' => 40));
  279. if (api_get_setting('profile', 'email') !== 'true') {
  280. $form->freeze('email');
  281. }
  282. if (api_get_setting('registration', 'email') == 'true' && api_get_setting('profile', 'email') == 'true') {
  283. $form->applyFilter('email', 'stripslashes');
  284. $form->applyFilter('email', 'trim');
  285. $form->addRule('email', get_lang('ThisFieldIsRequired'), 'required');
  286. $form->addRule('email', get_lang('EmailWrong'), 'email');
  287. }
  288. // OPENID URL
  289. if (is_profile_editable() && api_get_setting('openid_authentication') == 'true') {
  290. $form->addElement('text', 'openid', get_lang('OpenIDURL'), array('size' => 40));
  291. if (api_get_setting('profile', 'openid') !== 'true') {
  292. $form->freeze('openid');
  293. }
  294. $form->applyFilter('openid', 'trim');
  295. }
  296. // PHONE
  297. $form->addElement('text', 'phone', get_lang('Phone'), array('size' => 20));
  298. if (api_get_setting('profile', 'phone') !== 'true') {
  299. $form->freeze('phone');
  300. }
  301. $form->applyFilter('phone', 'stripslashes');
  302. $form->applyFilter('phone', 'trim');
  303. $form->applyFilter('phone', 'html_filter');
  304. if ($userGeolocalization) {
  305. // Geolocation
  306. $form->addElement('text', 'address', get_lang('AddressField'), ['id' => 'address']);
  307. $form->addHtml('
  308. <div class="form-group">
  309. <label for="geolocalization" class="col-sm-2 control-label"></label>
  310. <div class="col-sm-8">
  311. <button class="null btn btn-default " id="geolocalization" name="geolocalization" type="submit"><em class="fa fa-map-marker"></em> '.get_lang('Geolocalization').'</button>
  312. <button class="null btn btn-default " id="myLocation" name="myLocation" type="submit"><em class="fa fa-crosshairs"></em> '.get_lang('MyLocation').'</button>
  313. </div>
  314. </div>
  315. ');
  316. $form->addHtml('
  317. <div class="form-group">
  318. <label for="map" class="col-sm-2 control-label">
  319. '.get_lang('Map').'
  320. </label>
  321. <div class="col-sm-8">
  322. <div name="map" id="map" style="width:100%; height:300px;">
  323. </div>
  324. </div>
  325. </div>
  326. ');
  327. }
  328. // PICTURE
  329. if (is_profile_editable() && api_get_setting('profile', 'picture') == 'true') {
  330. $form->addElement(
  331. 'file',
  332. 'picture',
  333. ($user_data['picture_uri'] != '' ? get_lang('UpdateImage') : get_lang(
  334. 'AddImage'
  335. )),
  336. array('id' => 'picture_form', 'class' => 'picture-form')
  337. );
  338. $form->addHtml(''
  339. . '<div class="form-group">'
  340. . '<label for="cropImage" id="labelCropImage" class="col-sm-2 control-label"></label>'
  341. . '<div class="col-sm-8">'
  342. . '<div id="cropImage" class="cropCanvas">'
  343. . '<img id="previewImage" >'
  344. . '</div>'
  345. . '<div>'
  346. . '<button class="btn btn-primary hidden" name="cropButton" id="cropButton"><em class="fa fa-crop"></em> '.get_lang('CropYourPicture').'</button>'
  347. . '</div>'
  348. . '</div>'
  349. . '</div>'
  350. . '');
  351. $form->addHidden('cropResult', '');
  352. $form->add_progress_bar();
  353. if (!empty($user_data['picture_uri'])) {
  354. $form->addElement('checkbox', 'remove_picture', null, get_lang('DelImage'));
  355. }
  356. $allowed_picture_types = api_get_supported_image_extensions();
  357. $form->addRule(
  358. 'picture',
  359. get_lang('OnlyImagesAllowed').' ('.implode(', ', $allowed_picture_types).')',
  360. 'filetype',
  361. $allowed_picture_types
  362. );
  363. }
  364. // LANGUAGE
  365. $form->addElement('select_language', 'language', get_lang('Language'));
  366. if (api_get_setting('profile', 'language') !== 'true') {
  367. $form->freeze('language');
  368. }
  369. //THEME
  370. if (is_profile_editable() && api_get_setting('user_selected_theme') == 'true') {
  371. $form->addElement('SelectTheme', 'theme', get_lang('Theme'));
  372. if (api_get_setting('profile', 'theme') !== 'true') {
  373. $form->freeze('theme');
  374. }
  375. $form->applyFilter('theme', 'trim');
  376. }
  377. // EXTENDED PROFILE this make the page very slow!
  378. if (api_get_setting('extended_profile') === 'true') {
  379. $width_extended_profile = 500;
  380. // MY COMPETENCES
  381. $form->addHtmlEditor(
  382. 'competences',
  383. get_lang('MyCompetences'),
  384. false,
  385. false,
  386. array(
  387. 'ToolbarSet' => 'Profile',
  388. 'Width' => $width_extended_profile,
  389. 'Height' => '130',
  390. )
  391. );
  392. // MY DIPLOMAS
  393. $form->addHtmlEditor(
  394. 'diplomas',
  395. get_lang('MyDiplomas'),
  396. false,
  397. false,
  398. array(
  399. 'ToolbarSet' => 'Profile',
  400. 'Width' => $width_extended_profile,
  401. 'Height' => '130',
  402. )
  403. );
  404. // WHAT I AM ABLE TO TEACH
  405. $form->addHtmlEditor(
  406. 'teach',
  407. get_lang('MyTeach'),
  408. false,
  409. false,
  410. array(
  411. 'ToolbarSet' => 'Profile',
  412. 'Width' => $width_extended_profile,
  413. 'Height' => '130',
  414. )
  415. );
  416. // MY PRODUCTIONS
  417. $form->addElement('file', 'production', get_lang('MyProductions'));
  418. if ($production_list = UserManager::build_production_list(api_get_user_id(), '', true)) {
  419. $form->addElement('static', 'productions_list', null, $production_list);
  420. }
  421. // MY PERSONAL OPEN AREA
  422. $form->addHtmlEditor(
  423. 'openarea',
  424. get_lang('MyPersonalOpenArea'),
  425. false,
  426. false,
  427. array(
  428. 'ToolbarSet' => 'Profile',
  429. 'Width' => $width_extended_profile,
  430. 'Height' => '350',
  431. )
  432. );
  433. // openarea is untrimmed for maximum openness
  434. $form->applyFilter(array('competences', 'diplomas', 'teach', 'openarea'), 'stripslashes');
  435. $form->applyFilter(array('competences', 'diplomas', 'teach'), 'trim');
  436. }
  437. // PASSWORD, if auth_source is platform
  438. if (is_platform_authentication() &&
  439. is_profile_editable() &&
  440. api_get_setting('profile', 'password') == 'true'
  441. ) {
  442. $form->addElement('password', 'password0', array(get_lang('Pass'), get_lang('Enter2passToChange')), array('size' => 40));
  443. $form->addElement('password', 'password1', get_lang('NewPass'), array('id'=> 'password1', 'size' => 40));
  444. $checkPass = api_get_setting('allow_strength_pass_checker');
  445. if ($checkPass == 'true') {
  446. $form->addElement('label', null, '<div id="password_progress"></div>');
  447. }
  448. $form->addElement('password', 'password2', get_lang('Confirmation'), array('size' => 40));
  449. // user must enter identical password twice so we can prevent some user errors
  450. $form->addRule(array('password1', 'password2'), get_lang('PassTwo'), 'compare');
  451. if (CHECK_PASS_EASY_TO_FIND) {
  452. $form->addRule('password1', get_lang('CurrentPasswordEmptyOrIncorrect'), 'callback', 'api_check_password');
  453. }
  454. }
  455. $extraField = new ExtraField('user');
  456. $return = $extraField->addElements($form, api_get_user_id());
  457. $jquery_ready_content = $return['jquery_ready_content'];
  458. // the $jquery_ready_content variable collects all functions that
  459. // will be load in the $(document).ready javascript function
  460. $htmlHeadXtra[] ='<script>
  461. $(document).ready(function(){
  462. '.$jquery_ready_content.'
  463. });
  464. </script>';
  465. if (api_get_setting('profile', 'apikeys') == 'true') {
  466. $form->addElement('html', '<div id="div_api_key">');
  467. $form->addElement(
  468. 'text',
  469. 'api_key_generate',
  470. get_lang('MyApiKey'),
  471. array('size' => 40, 'id' => 'id_api_key_generate')
  472. );
  473. $form->addElement('html', '</div>');
  474. $form->addButton(
  475. 'generate_api_key',
  476. get_lang('GenerateApiKey'),
  477. 'cogs',
  478. 'default',
  479. 'default',
  480. null,
  481. ['id' => 'id_generate_api_key']
  482. );
  483. }
  484. // SUBMIT
  485. if (is_profile_editable()) {
  486. $form->addButtonUpdate(get_lang('SaveSettings'), 'apply_change');
  487. } else {
  488. $form->freeze();
  489. }
  490. $form->setDefaults($user_data);
  491. /**
  492. * Is user auth_source is platform ?
  493. *
  494. * @return boolean if auth_source is platform
  495. */
  496. function is_platform_authentication() {
  497. $tab_user_info = api_get_user_info();
  498. return $tab_user_info['auth_source'] == PLATFORM_AUTH_SOURCE;
  499. }
  500. /**
  501. * Can a user edit his/her profile?
  502. *
  503. * @return boolean Editability of the profile
  504. */
  505. function is_profile_editable() {
  506. return $GLOBALS['profileIsEditable'];
  507. }
  508. /*
  509. PRODUCTIONS FUNCTIONS
  510. */
  511. /**
  512. * Upload a submitted user production.
  513. *
  514. * @param $user_id User id
  515. * @return The filename of the new production or FALSE if the upload has failed
  516. */
  517. function upload_user_production($user_id)
  518. {
  519. $production_repository = UserManager::getUserPathById($user_id, 'system');
  520. if (!file_exists($production_repository)) {
  521. @mkdir($production_repository, api_get_permissions_for_new_directories(), true);
  522. }
  523. $filename = api_replace_dangerous_char($_FILES['production']['name']);
  524. $filename = disable_dangerous_file($filename);
  525. if (filter_extension($filename)) {
  526. if (@move_uploaded_file($_FILES['production']['tmp_name'], $production_repository.$filename)) {
  527. return $filename;
  528. }
  529. }
  530. return false; // this should be returned if anything went wrong with the upload
  531. }
  532. /**
  533. * Check current user's current password
  534. * @param char email
  535. * @return bool true o false
  536. * @uses Gets user ID from global variable
  537. */
  538. function check_user_email($email) {
  539. $user_id = api_get_user_id();
  540. if ($user_id != strval(intval($user_id)) || empty($email)) {
  541. return false;
  542. }
  543. $table_user = Database :: get_main_table(TABLE_MAIN_USER);
  544. $email = Database::escape_string($email);
  545. $sql = "SELECT * FROM $table_user
  546. WHERE user_id='".$user_id."' AND email='".$email."'";
  547. $result = Database::query($sql);
  548. return Database::num_rows($result) != 0;
  549. }
  550. $filtered_extension = false;
  551. if ($form->validate()) {
  552. $wrong_current_password = false;
  553. $user_data = $form->getSubmitValues(1);
  554. /** @var User $user */
  555. $user = UserManager::getRepository()->find(api_get_user_id());
  556. // set password if a new one was provided
  557. $validPassword = false;
  558. $passwordWasChecked = false;
  559. if ($user &&
  560. (!empty($user_data['password0']) &&
  561. !empty($user_data['password1'])) ||
  562. (!empty($user_data['password0']) &&
  563. api_get_setting('profile', 'email') == 'true')
  564. ) {
  565. $passwordWasChecked = true;
  566. $validPassword = UserManager::isPasswordValid(
  567. $user_data['password0'],
  568. $user
  569. );
  570. if ($validPassword) {
  571. $password = $user_data['password1'];
  572. } else {
  573. Display::addFlash(
  574. Display:: return_message(
  575. get_lang('CurrentPasswordEmptyOrIncorrect'),
  576. 'warning',
  577. false
  578. )
  579. );
  580. }
  581. }
  582. $allow_users_to_change_email_with_no_password = true;
  583. if (is_platform_authentication() &&
  584. api_get_setting('allow_users_to_change_email_with_no_password') == 'false'
  585. ) {
  586. $allow_users_to_change_email_with_no_password = false;
  587. }
  588. // If user sending the email to be changed (input available and not frozen )
  589. if (api_get_setting('profile', 'email') == 'true') {
  590. if ($allow_users_to_change_email_with_no_password) {
  591. if (!check_user_email($user_data['email'])) {
  592. $changeemail = $user_data['email'];
  593. }
  594. } else {
  595. // Normal behaviour
  596. if (!check_user_email($user_data['email']) && $validPassword) {
  597. $changeemail = $user_data['email'];
  598. }
  599. if (!check_user_email($user_data['email']) &&
  600. empty($user_data['password0'])
  601. ){
  602. Display::addFlash(
  603. Display:: return_message(
  604. get_lang('ToChangeYourEmailMustTypeYourPassword'),
  605. 'error',
  606. false
  607. )
  608. );
  609. }
  610. }
  611. }
  612. // Upload picture if a new one is provided
  613. if ($_FILES['picture']['size']) {
  614. $new_picture = UserManager::update_user_picture(
  615. api_get_user_id(),
  616. $_FILES['picture']['name'],
  617. $_FILES['picture']['tmp_name'],
  618. $user_data['cropResult']
  619. );
  620. if ($new_picture) {
  621. $user_data['picture_uri'] = $new_picture;
  622. Display::addFlash(
  623. Display:: return_message(
  624. get_lang('PictureUploaded'),
  625. 'normal',
  626. false
  627. )
  628. );
  629. }
  630. } elseif (!empty($user_data['remove_picture'])) {
  631. // remove existing picture if asked
  632. UserManager::delete_user_picture(api_get_user_id());
  633. $user_data['picture_uri'] = '';
  634. }
  635. // Remove production.
  636. if (isset($user_data['remove_production']) &&
  637. is_array($user_data['remove_production'])
  638. ) {
  639. foreach (array_keys($user_data['remove_production']) as $production) {
  640. UserManager::remove_user_production(api_get_user_id(), urldecode($production));
  641. }
  642. if ($production_list = UserManager::build_production_list(api_get_user_id(), true, true)) {
  643. $form->insertElementBefore(
  644. $form->createElement('static', null, null, $production_list),
  645. 'productions_list'
  646. );
  647. }
  648. $form->removeElement('productions_list');
  649. Display::addFlash(
  650. Display:: return_message(get_lang('FileDeleted'), 'normal', false)
  651. );
  652. }
  653. // upload production if a new one is provided
  654. if (isset($_FILES['production']) && $_FILES['production']['size']) {
  655. $res = upload_user_production(api_get_user_id());
  656. if (!$res) {
  657. //it's a bit excessive to assume the extension is the reason why
  658. // upload_user_production() returned false, but it's true in most cases
  659. $filtered_extension = true;
  660. } else {
  661. Display::addFlash(
  662. Display:: return_message(
  663. get_lang('ProductionUploaded'),
  664. 'normal',
  665. false
  666. )
  667. );
  668. }
  669. }
  670. // remove values that shouldn't go in the database
  671. unset(
  672. $user_data['password0'],
  673. $user_data['password1'],
  674. $user_data['password2'],
  675. $user_data['MAX_FILE_SIZE'],
  676. $user_data['remove_picture'],
  677. $user_data['apply_change'],
  678. $user_data['email']
  679. );
  680. // Following RFC2396 (http://www.faqs.org/rfcs/rfc2396.html), a URI uses ':' as a reserved character
  681. // we can thus ensure the URL doesn't contain any scheme name by searching for ':' in the string
  682. $my_user_openid = isset($user_data['openid']) ? $user_data['openid'] : '';
  683. if (!preg_match('/^[^:]*:\/\/.*$/', $my_user_openid)) {
  684. //ensure there is at least a http:// scheme in the URI provided
  685. $user_data['openid'] = 'http://'.$my_user_openid;
  686. }
  687. $extras = array();
  688. //Checking the user language
  689. $languages = api_get_languages();
  690. if (!in_array($user_data['language'], $languages['folder'])) {
  691. $user_data['language'] = api_get_setting('platformLanguage');
  692. }
  693. $_SESSION['_user']['language'] = $user_data['language'];
  694. //Only update values that are request by the "profile" setting
  695. $profile_list = api_get_setting('profile');
  696. //Adding missing variables
  697. $available_values_to_modify = array();
  698. foreach ($profile_list as $key => $status) {
  699. if ($status == 'true') {
  700. switch($key) {
  701. case 'login':
  702. $available_values_to_modify[] = 'username';
  703. break;
  704. case 'name':
  705. $available_values_to_modify[] = 'firstname';
  706. $available_values_to_modify[] = 'lastname';
  707. break;
  708. case 'picture':
  709. $available_values_to_modify[] = 'picture_uri';
  710. break;
  711. default:
  712. $available_values_to_modify[] = $key;
  713. break;
  714. }
  715. }
  716. }
  717. //Fixing missing variables
  718. $available_values_to_modify = array_merge(
  719. $available_values_to_modify,
  720. array('competences', 'diplomas', 'openarea', 'teach', 'openid', 'address')
  721. );
  722. // build SQL query
  723. $sql = "UPDATE $table_user SET";
  724. unset($user_data['api_key_generate']);
  725. foreach ($user_data as $key => $value) {
  726. if (substr($key, 0, 6) === 'extra_') { //an extra field
  727. continue;
  728. } elseif (strpos($key, 'remove_extra_') !== false) {
  729. } else {
  730. if (in_array($key, $available_values_to_modify)) {
  731. $sql .= " $key = '".Database::escape_string($value)."',";
  732. }
  733. }
  734. }
  735. $changePassword = false;
  736. // Change email
  737. if ($allow_users_to_change_email_with_no_password) {
  738. if (isset($changeemail) && in_array('email', $available_values_to_modify)) {
  739. $sql .= " email = '".Database::escape_string($changeemail)."' ";
  740. }
  741. if (isset($password) && in_array('password', $available_values_to_modify)) {
  742. $changePassword = true;
  743. /*$password = api_get_encrypted_password($password);
  744. $sql .= " password = '".Database::escape_string($password)."'";*/
  745. } else {
  746. // remove trailing , from the query we have so far
  747. //$sql = rtrim($sql, ',');
  748. }
  749. } else {
  750. if (isset($changeemail) && !isset($password) && in_array('email', $available_values_to_modify)) {
  751. $sql .= " email = '".Database::escape_string($changeemail)."'";
  752. } else {
  753. if (isset($password) && in_array('password', $available_values_to_modify)) {
  754. if (isset($changeemail) && in_array('email', $available_values_to_modify)) {
  755. $sql .= " email = '".Database::escape_string($changeemail)."' ";
  756. }
  757. $changePassword = true;
  758. /*$password = api_get_encrypted_password($password);
  759. $sql .= " password = '".Database::escape_string($password)."'";*/
  760. } else {
  761. // remove trailing , from the query we have so far
  762. //$sql = rtrim($sql, ',');
  763. }
  764. }
  765. }
  766. $sql = rtrim($sql, ',');
  767. if ($changePassword && !empty($password)) {
  768. UserManager::updatePassword(api_get_user_id(), $password);
  769. }
  770. if (api_get_setting('profile', 'officialcode') === 'true' &&
  771. isset($user_data['official_code'])
  772. ) {
  773. $sql .= ", official_code = '".Database::escape_string($user_data['official_code'])."'";
  774. }
  775. $sql .= " WHERE user_id = '".api_get_user_id()."'";
  776. Database::query($sql);
  777. $webserviceUrl = api_get_plugin_setting('logintcc', 'webservice_url');
  778. $hash = api_get_plugin_setting('logintcc', 'hash');
  779. $extraField = new ExtraFieldValue('user');
  780. $extraField->saveFieldValues($user_data);
  781. if (!empty($webserviceUrl) && !empty($hash)) {
  782. $tccUserIdData = $extraField->get_values_by_handler_and_field_variable(api_get_user_id(), 'tcc_user_id');
  783. $tccUserId = $tccUserIdData['value'];
  784. $tccHashData = $extraField->get_values_by_handler_and_field_variable(api_get_user_id(), 'tcc_hash_key');
  785. $tccHash = $tccHashData['value'];
  786. $genreData = $extraField->get_values_by_handler_and_field_variable(api_get_user_id(), 'terms_genre');
  787. $genre = $genreData['value'] == 'homme' ? 'Masculin' : 'Féminin';
  788. $codeData = $extraField->get_values_by_handler_and_field_variable(api_get_user_id(), 'terms_codepostal');
  789. $cp = $codeData['value'];
  790. $citizenshipData = $extraField->get_values_by_handler_and_field_variable(
  791. api_get_user_id(),
  792. 'terms_nationalite'
  793. );
  794. $citizenship = $citizenshipData['value'];
  795. $birthData = $extraField->get_values_by_handler_and_field_variable(api_get_user_id(), 'terms_datedenaissance');
  796. $birthDate = $birthData['value'];
  797. $countryData = $extraField->get_values_by_handler_and_field_variable(api_get_user_id(), 'terms_paysresidence');
  798. $country = $countryData['value'];
  799. $cityData = $extraField->get_values_by_handler_and_field_variable(api_get_user_id(), 'terms_ville');
  800. $city = $cityData['value'];
  801. switch ($user_data['language']) {
  802. case 'french':
  803. case 'french2':
  804. $language = 'fr-FR';
  805. break;
  806. case 'german':
  807. case 'german2':
  808. $language = 'de-DE';
  809. break;
  810. default:
  811. $language = 'fr-FR';
  812. break;
  813. }
  814. $params = [
  815. 'UserID' => $tccUserId,
  816. 'Genre' => $genre,
  817. 'Nom' => $user_data['lastname'],
  818. 'Prenom' => $user_data['firstname'],
  819. 'DateNaissance' => $birthDate,
  820. 'Langue' => $language,
  821. 'Nationalite' => $citizenship,
  822. 'Adresse' => $user_data['address'],
  823. 'CP' => $cp,
  824. 'PaysResidence' => $country,
  825. 'Ville' => $city,
  826. 'Email' => $user->getEmail(),
  827. 'HashKey' => $hash
  828. ];
  829. try {
  830. $client = new GuzzleHttp\Client();
  831. $response = $client->request('POST', $webserviceUrl.'/UpdateUser', ['json' => $params]);
  832. } catch (Exception $e) {
  833. echo $e->getMessage();
  834. }
  835. }
  836. if ($passwordWasChecked == false) {
  837. Display::addFlash(
  838. Display:: return_message(get_lang('ProfileReg'), 'normal', false)
  839. );
  840. } else {
  841. if ($validPassword) {
  842. Display::addFlash(
  843. Display:: return_message(get_lang('ProfileReg'), 'normal', false)
  844. );
  845. }
  846. }
  847. $userInfo = api_get_user_info();
  848. Session::write('_user', $userInfo);
  849. // re-init the system to take new settings into account
  850. //$_SESSION['_user']['uidReset'] = true;
  851. //$_SESSION['noredirection'] = true;
  852. $url = api_get_self();
  853. header("Location: ".$url);
  854. exit;
  855. }
  856. // the header
  857. $actions = null;
  858. if (api_get_setting('allow_social_tool') !== 'true') {
  859. if (api_get_setting('extended_profile') === 'true') {
  860. $actions .= '<div class="actions">';
  861. if (api_get_setting('allow_social_tool') === 'true' &&
  862. api_get_setting('allow_message_tool') === 'true'
  863. ) {
  864. $actions .= '<a href="'.api_get_path(WEB_PATH).'main/social/profile.php">'.
  865. Display::return_icon('shared_profile.png', get_lang('ViewSharedProfile')).'</a>';
  866. }
  867. if (api_get_setting('allow_message_tool') === 'true') {
  868. $actions .= '<a href="'.api_get_path(WEB_PATH).'main/messages/inbox.php">'.
  869. Display::return_icon('inbox.png', get_lang('Messages')).'</a>';
  870. }
  871. $show = isset($_GET['show']) ? '&amp;show='.Security::remove_XSS($_GET['show']) : '';
  872. if (isset($_GET['type']) && $_GET['type'] === 'extended') {
  873. $actions .= '<a href="profile.php?type=reduced'.$show.'">'.
  874. Display::return_icon('edit.png', get_lang('EditNormalProfile'), '', 16).'</a>';
  875. } else {
  876. $actions .= '<a href="profile.php?type=extended'.$show.'">'.
  877. Display::return_icon('edit.png', get_lang('EditExtendProfile'), '', 16).'</a>';
  878. }
  879. $actions .= '</div>';
  880. }
  881. }
  882. $show_delete_account_button = api_get_setting('platform_unsubscribe_allowed') === 'true' ? true : false;
  883. if (api_get_setting('show_terms_if_profile_completed') === 'true') {
  884. if (empty($user_data['profile_completed'])) {
  885. Display::addFlash(Display::return_message(get_lang('ProfileIsNotCompleted'), 'warning'));
  886. }
  887. $profileCompleteResults = Session::read('profile_completed_result');
  888. if (!empty($profileCompleteResults)) {
  889. foreach ($profileCompleteResults as $profileVariable => $value) {
  890. if ($value === false) {
  891. $data = $extraField->get_handler_field_info_by_field_variable($profileVariable);
  892. Display::addFlash(
  893. Display::return_message('"'.$data['display_text'].'" '.get_lang('ThisFieldIsRequired'),
  894. 'warning',
  895. false
  896. )
  897. );
  898. }
  899. }
  900. }
  901. Session::erase('profile_completed_result');
  902. }
  903. $tpl = new Template(get_lang('ModifyProfile'));
  904. $tpl->assign('actions', $actions);
  905. SocialManager::setSocialUserBlock($tpl, $user_id, 'messages');
  906. if (api_get_setting('allow_social_tool') === 'true') {
  907. SocialManager::setSocialUserBlock($tpl, api_get_user_id(), 'home');
  908. $menu = SocialManager::show_social_menu(
  909. 'home',
  910. null,
  911. api_get_user_id(),
  912. false,
  913. $show_delete_account_button
  914. );
  915. $tpl->assign('social_menu_block', $menu);
  916. $tpl->assign('social_right_content', $form->returnForm());
  917. $social_layout = $tpl->get_template('social/edit_profile.tpl');
  918. $tpl->display($social_layout);
  919. } else {
  920. $bigImage = UserManager::getUserPicture(api_get_user_id(), USER_IMAGE_SIZE_BIG);
  921. $normalImage = UserManager::getUserPicture(api_get_user_id(), USER_IMAGE_SIZE_ORIGINAL);
  922. $imageToShow = '<div id="image-message-container">';
  923. $imageToShow .= '<a class="expand-image" href="'.$bigImage.'" /><img src="'.$normalImage.'"></a>';
  924. $imageToShow .= '</div>';
  925. $content = $imageToShow.$form->returnForm();
  926. $tpl->assign('content', $content);
  927. $tpl->display_one_col_template();
  928. }