personal_data.php 17 KB

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