profile.php 36 KB

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