personal_data.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use Chamilo\CoreBundle\Entity\Repository\LegalRepository;
  4. /**
  5. * @package chamilo.messages
  6. */
  7. $cidReset = true;
  8. require_once __DIR__.'/../inc/global.inc.php';
  9. api_set_more_memory_and_time_limits();
  10. api_block_anonymous_users();
  11. if (api_get_configuration_value('disable_gdpr')) {
  12. api_not_allowed(true);
  13. }
  14. $userId = api_get_user_id();
  15. $userInfo = api_get_user_info($userId);
  16. if (empty($userInfo)) {
  17. api_not_allowed(true);
  18. }
  19. $substitutionTerms = [
  20. 'password' => get_lang('EncryptedData'),
  21. 'salt' => get_lang('RandomData'),
  22. 'empty' => get_lang('NoData'),
  23. ];
  24. $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
  25. $formToString = '';
  26. if (api_get_setting('allow_terms_conditions') === 'true') {
  27. $form = new FormValidator('delete_term', 'post', api_get_self().'?action=delete_legal&user_id='.$userId);
  28. $form->addHtml(Display::return_message(get_lang('WhyYouWantToDeleteYourLegalAgreement'), 'normal', false));
  29. $form->addTextarea('explanation', [get_lang('DeleteLegal'), get_lang('ExplanationDeleteLegal')], [], true);
  30. $form->addHidden('action', 'delete_legal');
  31. $form->addButtonSave(get_lang('DeleteLegal'));
  32. $formToString = $form->returnForm();
  33. $formDelete = new FormValidator('delete_account', 'post', api_get_self().'?action=delete_account&user_id='.$userId);
  34. $formDelete->addTextarea(
  35. 'explanation',
  36. [get_lang('DeleteAccount'), get_lang('ExplanationDeleteAccount')],
  37. [],
  38. true
  39. );
  40. $formDelete->addHidden('action', 'delete_account');
  41. $formDelete->addButtonDelete(get_lang('DeleteAccount'));
  42. $formToString .= $formDelete->returnForm();
  43. }
  44. switch ($action) {
  45. case 'send_legal':
  46. $language = api_get_interface_language();
  47. $language = api_get_language_id($language);
  48. $terms = LegalManager::get_last_condition($language);
  49. if (!$terms) {
  50. //look for the default language
  51. $language = api_get_setting('platformLanguage');
  52. $language = api_get_language_id($language);
  53. $terms = LegalManager::get_last_condition($language);
  54. }
  55. $legalAcceptType = $terms['version'].':'.$terms['language_id'].':'.time();
  56. UserManager::update_extra_field_value(
  57. $userId,
  58. 'legal_accept',
  59. $legalAcceptType
  60. );
  61. Event::addEvent(
  62. LOG_TERM_CONDITION_ACCEPTED,
  63. LOG_USER_OBJECT,
  64. api_get_user_info($userId),
  65. api_get_utc_datetime()
  66. );
  67. $bossList = UserManager::getStudentBossList($userId);
  68. if (!empty($bossList)) {
  69. $bossList = array_column($bossList, 'boss_id');
  70. $currentUserInfo = api_get_user_info($userId);
  71. foreach ($bossList as $bossId) {
  72. $subjectEmail = sprintf(
  73. get_lang('UserXSignedTheAgreement'),
  74. $currentUserInfo['complete_name']
  75. );
  76. $contentEmail = sprintf(
  77. get_lang('UserXSignedTheAgreementTheDateY'),
  78. $currentUserInfo['complete_name'],
  79. api_get_local_time($time)
  80. );
  81. MessageManager::send_message_simple(
  82. $bossId,
  83. $subjectEmail,
  84. $contentEmail,
  85. $user_id
  86. );
  87. }
  88. }
  89. Display::addFlash(Display::return_message(get_lang('Saved')));
  90. header('Location: '.api_get_self());
  91. exit;
  92. break;
  93. case 'delete_account':
  94. if ($formDelete->validate()) {
  95. $explanation = $formDelete->getSubmitValue('explanation');
  96. UserManager::createDataPrivacyExtraFields();
  97. UserManager::update_extra_field_value(
  98. $userId,
  99. 'request_for_delete_account',
  100. 1
  101. );
  102. UserManager::update_extra_field_value(
  103. $userId,
  104. 'request_for_delete_account_justification',
  105. $explanation
  106. );
  107. Display::addFlash(Display::return_message(get_lang('Saved')));
  108. Event::addEvent(
  109. LOG_USER_DELETE_ACCOUNT_REQUEST,
  110. LOG_USER_OBJECT,
  111. $userInfo
  112. );
  113. $url = api_get_path(WEB_CODE_PATH).'admin/user_list_consent.php';
  114. $link = Display::url($url, $url);
  115. $subject = get_lang('RequestForAccountDeletion');
  116. $content = sprintf(
  117. get_lang('TheUserXAskedForAccountDeletionWithJustificationXGoHereX'),
  118. $userInfo['complete_name'],
  119. $explanation,
  120. $link
  121. );
  122. $email = api_get_configuration_value('data_protection_officer_email');
  123. if (!empty($email)) {
  124. api_mail_html('', $email, $subject, $content);
  125. } else {
  126. MessageManager::sendMessageToAllAdminUsers(api_get_user_id(), $subject, $content);
  127. }
  128. header('Location: '.api_get_self());
  129. exit;
  130. }
  131. break;
  132. case 'delete_legal':
  133. if ($form->validate()) {
  134. $explanation = $form->getSubmitValue('explanation');
  135. UserManager::createDataPrivacyExtraFields();
  136. UserManager::update_extra_field_value(
  137. $userId,
  138. 'request_for_legal_agreement_consent_removal',
  139. 1
  140. );
  141. UserManager::update_extra_field_value(
  142. $userId,
  143. 'request_for_legal_agreement_consent_removal_justification',
  144. $explanation
  145. );
  146. Display::addFlash(Display::return_message(get_lang('Sent')));
  147. Event::addEvent(
  148. LOG_USER_REMOVED_LEGAL_ACCEPT,
  149. LOG_USER_OBJECT,
  150. $userInfo
  151. );
  152. $url = api_get_path(WEB_CODE_PATH).'admin/user_list_consent.php';
  153. $link = Display::url($url, $url);
  154. $subject = get_lang('RequestForLegalConsentWithdrawal');
  155. $content = sprintf(
  156. get_lang('TheUserXAskedLegalConsentWithdrawalWithJustificationXGoHereX'),
  157. $userInfo['complete_name'],
  158. $explanation,
  159. $link
  160. );
  161. $email = api_get_configuration_value('data_protection_officer_email');
  162. if (!empty($email)) {
  163. api_mail_html('', $email, $subject, $content);
  164. } else {
  165. MessageManager::sendMessageToAllAdminUsers(api_get_user_id(), $subject, $content);
  166. }
  167. header('Location: '.api_get_self());
  168. exit;
  169. }
  170. break;
  171. }
  172. $propertiesToJson = UserManager::getRepository()->getPersonalDataToJson($userId, $substitutionTerms);
  173. if (!empty($_GET['export'])) {
  174. $filename = md5(mt_rand(0, 1000000)).'.json';
  175. $path = api_get_path(SYS_ARCHIVE_PATH).$filename;
  176. $writeResult = file_put_contents($path, $propertiesToJson);
  177. if ($writeResult !== false) {
  178. DocumentManager::file_send_for_download($path, true, $filename);
  179. exit;
  180. }
  181. }
  182. $allowSocial = api_get_setting('allow_social_tool') === 'true';
  183. $nameTools = get_lang('PersonalDataReport');
  184. $show_message = null;
  185. if ($allowSocial) {
  186. $this_section = SECTION_SOCIAL;
  187. $interbreadcrumb[] = [
  188. 'url' => api_get_path(WEB_PATH).'main/social/home.php',
  189. 'name' => get_lang('SocialNetwork'),
  190. ];
  191. } else {
  192. $this_section = SECTION_MYPROFILE;
  193. $interbreadcrumb[] = [
  194. 'url' => api_get_path(WEB_PATH).'main/auth/profile.php',
  195. 'name' => get_lang('Profile'),
  196. ];
  197. }
  198. $interbreadcrumb[] = ['url' => '#', 'name' => get_lang('PersonalDataReport')];
  199. // LEFT CONTENT
  200. $socialMenuBlock = '';
  201. if ($allowSocial) {
  202. // Block Social Menu
  203. $socialMenuBlock = SocialManager::show_social_menu('personal-data');
  204. }
  205. // MAIN CONTENT
  206. $personalDataContent = '<ul>';
  207. $properties = json_decode($propertiesToJson);
  208. $webCoursePath = api_get_path(WEB_COURSE_PATH);
  209. $showWarningMessage = false;
  210. foreach ($properties as $key => $value) {
  211. if (is_array($value) || is_object($value)) {
  212. switch ($key) {
  213. case 'classes':
  214. foreach ($value as $category => $subValue) {
  215. $categoryName = 'Social group';
  216. if ($category == 0) {
  217. $categoryName = 'Class';
  218. }
  219. $personalDataContent .= '<li class="advanced_options" id="personal-data-list-'.$category.'">';
  220. $personalDataContent .= '<u>'.$categoryName.'</u> &gt;</li>';
  221. $personalDataContent .= '<ul id="personal-data-list-'.$category.'_options" style="display:none;">';
  222. if (empty($subValue)) {
  223. $personalDataContent .= '<li>'.get_lang('NoData').'</li>';
  224. } else {
  225. foreach ($subValue as $subSubValue) {
  226. $personalDataContent .= '<li>'.Security::remove_XSS($subSubValue).'</li>';
  227. }
  228. }
  229. $personalDataContent .= '</ul>';
  230. }
  231. break;
  232. case 'extraFields':
  233. $personalDataContent .= '<li>'.$key.': </li><ul>';
  234. if (empty($value)) {
  235. $personalDataContent .= '<li>'.get_lang('NoData').'</li>';
  236. } else {
  237. foreach ($value as $subValue) {
  238. if (is_array($subValue->value)) {
  239. // tags fields can be stored as arrays
  240. $val = json_encode(Security::remove_XSS($subValue->value));
  241. } else {
  242. $val = Security::remove_XSS($subValue->value);
  243. }
  244. $personalDataContent .= '<li>'.$subValue->variable.': '.$val.'</li>';
  245. }
  246. }
  247. $personalDataContent .= '</ul>';
  248. break;
  249. case 'dropBoxSentFiles':
  250. foreach ($value as $category => $subValue) {
  251. $personalDataContent .= '<li class="advanced_options" id="personal-data-list-'.$category.'">';
  252. $personalDataContent .= '<u>'.get_lang($category).'</u> &gt;</li>';
  253. $personalDataContent .= '<ul id="personal-data-list-'.$category.'_options" style="display:none;">';
  254. if (empty($subValue)) {
  255. $personalDataContent .= '<li>'.get_lang('NoData').'</li>';
  256. } else {
  257. if (count($subValue) === 1000) {
  258. $showWarningMessage = true;
  259. }
  260. foreach ($subValue as $subSubValue) {
  261. if ($category === 'DocumentsAdded') {
  262. $documentLink = Display::url(
  263. $subSubValue->code_path,
  264. $webCoursePath.$subSubValue->directory.'/document'.$subSubValue->path
  265. );
  266. $personalDataContent .= '<li>'.$documentLink.'</li>';
  267. } else {
  268. $personalDataContent .= '<li>'.Security::remove_XSS($subSubValue).'</li>';
  269. }
  270. }
  271. }
  272. $personalDataContent .= '</ul>';
  273. }
  274. break;
  275. case 'portals':
  276. case 'roles':
  277. case 'achievedSkills':
  278. case 'sessionAsGeneralCoach':
  279. case 'courses':
  280. case 'groupNames':
  281. case 'groups':
  282. $personalDataContent .= '<li>'.$key.': </li><ul>';
  283. if (empty($subValue)) {
  284. $personalDataContent .= '<li>'.get_lang('NoData').'</li>';
  285. } else {
  286. foreach ($value as $subValue) {
  287. $personalDataContent .= '<li>'.Security::remove_XSS($subValue).'</li>';
  288. }
  289. }
  290. $personalDataContent .= '</ul>';
  291. break;
  292. case 'sessionCourseSubscriptions':
  293. $personalDataContent .= '<li>'.$key.': </li><ul>';
  294. foreach ($value as $session => $courseList) {
  295. $personalDataContent .= '<li>'.$session.'<ul>';
  296. if (empty($courseList)) {
  297. $personalDataContent .= '<li>'.get_lang('NoData').'</li>';
  298. } else {
  299. foreach ($courseList as $course) {
  300. $personalDataContent .= '<li>'.$course.'</li>';
  301. }
  302. }
  303. $personalDataContent .= '</ul>';
  304. }
  305. $personalDataContent .= '</ul>';
  306. break;
  307. default:
  308. //var_dump($key);
  309. break;
  310. }
  311. /*foreach ($value as $subValue) {
  312. foreach ($subValue as $subSubValue) {
  313. var_dump($subSubValue);
  314. //$personalDataContent .= '<li>'.$subSubValue.'</li>';
  315. }
  316. }*/
  317. //skip in some cases
  318. /*sif (!empty($value['date'])) {
  319. $personalDataContent .= '<li>'.$key.': '.$value['date'].'</li>';
  320. } else {
  321. $personalDataContent .= '<li>'.$key.': '.get_lang('ComplexDataNotShown').'</li>';
  322. }*/
  323. } else {
  324. $personalDataContent .= '<li>'.$key.': '.Security::remove_XSS($value).'</li>';
  325. }
  326. }
  327. $personalDataContent .= '</ul>';
  328. // Check terms acceptation
  329. $permissionBlock = '';
  330. if (api_get_setting('allow_terms_conditions') === 'true') {
  331. $extraFieldValue = new ExtraFieldValue('user');
  332. $value = $extraFieldValue->get_values_by_handler_and_field_variable(
  333. $userId,
  334. 'legal_accept'
  335. );
  336. $permissionBlock .= Display::return_icon('accept_na.png', get_lang('NotAccepted'));
  337. if (isset($value['value']) && !empty($value['value'])) {
  338. list($legalId, $legalLanguageId, $legalTime) = explode(':', $value['value']);
  339. $permissionBlock = '<h4>'.get_lang('CurrentStatus').'</h4>'.
  340. get_lang('LegalAgreementAccepted').' '.Display::return_icon('accept.png', get_lang('LegalAgreementAccepted'), [], ICON_SIZE_TINY).
  341. '<br />';
  342. $permissionBlock .= get_lang('Date').': '.api_get_local_time($legalTime).'<br /><br />';
  343. $permissionBlock .= $formToString;
  344. /*$permissionBlock .= Display::url(
  345. get_lang('DeleteLegal'),
  346. api_get_self().'?action=delete_legal&user_id='.$userId,
  347. ['class' => 'btn btn-danger btn-xs']
  348. );*/
  349. } else {
  350. // @TODO add action handling for button
  351. $permissionBlock .= Display::url(
  352. get_lang('SendLegal'),
  353. api_get_self().'?action=send_legal&user_id='.$userId,
  354. ['class' => 'btn btn-primary btn-xs']
  355. );
  356. }
  357. } else {
  358. $permissionBlock .= get_lang('NoTermsAndConditionsAvailable');
  359. }
  360. //Build the final array to pass to template
  361. $personalData = [];
  362. $personalData['data'] = $personalDataContent;
  363. //$personalData['responsible'] = api_get_setting('personal_data_responsible_org');
  364. $em = Database::getManager();
  365. /** @var LegalRepository $legalTermsRepo */
  366. $legalTermsRepo = $em->getRepository('ChamiloCoreBundle:Legal');
  367. // Get data about the treatment of data
  368. $treatmentTypes = LegalManager::getTreatmentTypeList();
  369. /*foreach ($treatmentTypes as $id => $item) {
  370. $personalData['treatment'][$item]['title'] = get_lang('PersonalData'.ucfirst($item).'Title');
  371. $legalTerm = $legalTermsRepo->findOneByTypeAndLanguage($id, api_get_language_id($user_language));
  372. $legalTermContent = '';
  373. if (!empty($legalTerm[0]) && is_array($legalTerm[0])) {
  374. $legalTermContent = $legalTerm[0]['content'];
  375. }
  376. $personalData['treatment'][$item]['content'] = $legalTermContent;
  377. }*/
  378. $officerName = api_get_configuration_value('data_protection_officer_name');
  379. $officerRole = api_get_configuration_value('data_protection_officer_role');
  380. $officerEmail = api_get_configuration_value('data_protection_officer_email');
  381. if (!empty($officerName)) {
  382. $personalData['officer_name'] = $officerName;
  383. $personalData['officer_role'] = $officerRole;
  384. $personalData['officer_email'] = $officerEmail;
  385. }
  386. $tpl = new Template(null);
  387. $actions = Display::url(
  388. Display::return_icon('excel.png', get_lang('Export'), [], ICON_SIZE_MEDIUM),
  389. api_get_path(WEB_CODE_PATH).'social/personal_data.php?export=1'
  390. );
  391. $tpl->assign('actions', Display::toolbarAction('toolbar', [$actions]));
  392. $termLink = '';
  393. if (api_get_setting('allow_terms_conditions') === 'true') {
  394. $url = api_get_path(WEB_CODE_PATH).'social/terms.php';
  395. $termLink = Display::url(get_lang('ReadTermsAndConditions'), $url);
  396. }
  397. if ($showWarningMessage) {
  398. Display::addFlash(Display::return_message(get_lang('MoreDataAvailableInTheDatabaseButTrunkedForEfficiencyReasons')));
  399. }
  400. // Block Social Avatar
  401. SocialManager::setSocialUserBlock($tpl, api_get_user_id(), 'messages');
  402. if (api_get_setting('allow_social_tool') === 'true') {
  403. $tpl->assign('social_menu_block', $socialMenuBlock);
  404. } else {
  405. $tpl->assign('social_menu_block', '');
  406. $tpl->assign('personal_data_block', $personalDataContent);
  407. }
  408. $tpl->assign('personal_data', $personalData);
  409. $tpl->assign('permission', $permissionBlock);
  410. $tpl->assign('term_link', $termLink);
  411. $socialLayout = $tpl->get_template('social/personal_data.tpl');
  412. $tpl->display($socialLayout);