personal_data.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  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. $personalDataContent .= '<li>'.$subValue->variable.': '.Security::remove_XSS($subValue->value).'</li>';
  239. }
  240. }
  241. $personalDataContent .= '</ul>';
  242. break;
  243. case 'dropBoxSentFiles':
  244. foreach ($value as $category => $subValue) {
  245. $personalDataContent .= '<li class="advanced_options" id="personal-data-list-'.$category.'">';
  246. $personalDataContent .= '<u>'.get_lang($category).'</u> &gt;</li>';
  247. $personalDataContent .= '<ul id="personal-data-list-'.$category.'_options" style="display:none;">';
  248. if (empty($subValue)) {
  249. $personalDataContent .= '<li>'.get_lang('NoData').'</li>';
  250. } else {
  251. if (count($subValue) === 1000) {
  252. $showWarningMessage = true;
  253. }
  254. foreach ($subValue as $subSubValue) {
  255. if ($category === 'DocumentsAdded') {
  256. $documentLink = Display::url(
  257. $subSubValue->code_path,
  258. $webCoursePath.$subSubValue->directory.'/document'.$subSubValue->path
  259. );
  260. $personalDataContent .= '<li>'.$documentLink.'</li>';
  261. } else {
  262. $personalDataContent .= '<li>'.Security::remove_XSS($subSubValue).'</li>';
  263. }
  264. }
  265. }
  266. $personalDataContent .= '</ul>';
  267. }
  268. break;
  269. case 'portals':
  270. case 'roles':
  271. case 'achievedSkills':
  272. case 'sessionAsGeneralCoach':
  273. case 'courses':
  274. case 'groupNames':
  275. case 'groups':
  276. $personalDataContent .= '<li>'.$key.': </li><ul>';
  277. if (empty($subValue)) {
  278. $personalDataContent .= '<li>'.get_lang('NoData').'</li>';
  279. } else {
  280. foreach ($value as $subValue) {
  281. $personalDataContent .= '<li>'.Security::remove_XSS($subValue).'</li>';
  282. }
  283. }
  284. $personalDataContent .= '</ul>';
  285. break;
  286. case 'sessionCourseSubscriptions':
  287. $personalDataContent .= '<li>'.$key.': </li><ul>';
  288. foreach ($value as $session => $courseList) {
  289. $personalDataContent .= '<li>'.$session.'<ul>';
  290. if (empty($courseList)) {
  291. $personalDataContent .= '<li>'.get_lang('NoData').'</li>';
  292. } else {
  293. foreach ($courseList as $course) {
  294. $personalDataContent .= '<li>'.$course.'</li>';
  295. }
  296. }
  297. $personalDataContent .= '</ul>';
  298. }
  299. $personalDataContent .= '</ul>';
  300. break;
  301. default:
  302. //var_dump($key);
  303. break;
  304. }
  305. /*foreach ($value as $subValue) {
  306. foreach ($subValue as $subSubValue) {
  307. var_dump($subSubValue);
  308. //$personalDataContent .= '<li>'.$subSubValue.'</li>';
  309. }
  310. }*/
  311. //skip in some cases
  312. /*sif (!empty($value['date'])) {
  313. $personalDataContent .= '<li>'.$key.': '.$value['date'].'</li>';
  314. } else {
  315. $personalDataContent .= '<li>'.$key.': '.get_lang('ComplexDataNotShown').'</li>';
  316. }*/
  317. } else {
  318. $personalDataContent .= '<li>'.$key.': '.Security::remove_XSS($value).'</li>';
  319. }
  320. }
  321. $personalDataContent .= '</ul>';
  322. // Check terms acceptation
  323. $permissionBlock = '';
  324. if (api_get_setting('allow_terms_conditions') === 'true') {
  325. $extraFieldValue = new ExtraFieldValue('user');
  326. $value = $extraFieldValue->get_values_by_handler_and_field_variable(
  327. $userId,
  328. 'legal_accept'
  329. );
  330. $permissionBlock .= Display::return_icon('accept_na.png', get_lang('NotAccepted'));
  331. if (isset($value['value']) && !empty($value['value'])) {
  332. list($legalId, $legalLanguageId, $legalTime) = explode(':', $value['value']);
  333. $permissionBlock = '<h4>'.get_lang('CurrentStatus').'</h4>'.
  334. get_lang('LegalAgreementAccepted').' '.Display::return_icon('accept.png', get_lang('LegalAgreementAccepted'), [], ICON_SIZE_TINY).
  335. '<br />';
  336. $permissionBlock .= get_lang('Date').': '.api_get_local_time($legalTime).'<br /><br />';
  337. $permissionBlock .= $formToString;
  338. /*$permissionBlock .= Display::url(
  339. get_lang('DeleteLegal'),
  340. api_get_self().'?action=delete_legal&user_id='.$userId,
  341. ['class' => 'btn btn-danger btn-xs']
  342. );*/
  343. } else {
  344. // @TODO add action handling for button
  345. $permissionBlock .= Display::url(
  346. get_lang('SendLegal'),
  347. api_get_self().'?action=send_legal&user_id='.$userId,
  348. ['class' => 'btn btn-primary btn-xs']
  349. );
  350. }
  351. } else {
  352. $permissionBlock .= get_lang('NoTermsAndConditionsAvailable');
  353. }
  354. //Build the final array to pass to template
  355. $personalData = [];
  356. $personalData['data'] = $personalDataContent;
  357. //$personalData['responsible'] = api_get_setting('personal_data_responsible_org');
  358. $em = Database::getManager();
  359. /** @var LegalRepository $legalTermsRepo */
  360. $legalTermsRepo = $em->getRepository('ChamiloCoreBundle:Legal');
  361. // Get data about the treatment of data
  362. $treatmentTypes = LegalManager::getTreatmentTypeList();
  363. /*foreach ($treatmentTypes as $id => $item) {
  364. $personalData['treatment'][$item]['title'] = get_lang('PersonalData'.ucfirst($item).'Title');
  365. $legalTerm = $legalTermsRepo->findOneByTypeAndLanguage($id, api_get_language_id($user_language));
  366. $legalTermContent = '';
  367. if (!empty($legalTerm[0]) && is_array($legalTerm[0])) {
  368. $legalTermContent = $legalTerm[0]['content'];
  369. }
  370. $personalData['treatment'][$item]['content'] = $legalTermContent;
  371. }*/
  372. $officerName = api_get_configuration_value('data_protection_officer_name');
  373. $officerRole = api_get_configuration_value('data_protection_officer_role');
  374. $officerEmail = api_get_configuration_value('data_protection_officer_email');
  375. if (!empty($officerName)) {
  376. $personalData['officer_name'] = $officerName;
  377. $personalData['officer_role'] = $officerRole;
  378. $personalData['officer_email'] = $officerEmail;
  379. }
  380. $tpl = new Template(null);
  381. $actions = Display::url(
  382. Display::return_icon('excel.png', get_lang('Export'), [], ICON_SIZE_MEDIUM),
  383. api_get_path(WEB_CODE_PATH).'social/personal_data.php?export=1'
  384. );
  385. $tpl->assign('actions', Display::toolbarAction('toolbar', [$actions]));
  386. $termLink = '';
  387. if (api_get_setting('allow_terms_conditions') === 'true') {
  388. $url = api_get_path(WEB_CODE_PATH).'social/terms.php';
  389. $termLink = Display::url(get_lang('ReadTermsAndConditions'), $url);
  390. }
  391. if ($showWarningMessage) {
  392. Display::addFlash(Display::return_message(get_lang('MoreDataAvailableInTheDatabaseButTrunkedForEfficiencyReasons')));
  393. }
  394. // Block Social Avatar
  395. SocialManager::setSocialUserBlock($tpl, api_get_user_id(), 'messages');
  396. if (api_get_setting('allow_social_tool') === 'true') {
  397. $tpl->assign('social_menu_block', $socialMenuBlock);
  398. } else {
  399. $tpl->assign('social_menu_block', '');
  400. $tpl->assign('personal_data_block', $personalDataContent);
  401. }
  402. $tpl->assign('personal_data', $personalData);
  403. $tpl->assign('permission', $permissionBlock);
  404. $tpl->assign('term_link', $termLink);
  405. $socialLayout = $tpl->get_template('social/personal_data.tpl');
  406. $tpl->display($socialLayout);