user_list_consent.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use ChamiloSession as Session;
  4. /**
  5. * @author Bart Mollet
  6. * @author Julio Montoya <gugli100@gmail.com> BeezNest 2011
  7. *
  8. * @package chamilo.admin
  9. */
  10. $cidReset = true;
  11. require_once __DIR__.'/../inc/global.inc.php';
  12. $urlId = api_get_current_access_url_id();
  13. $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
  14. api_protect_admin_script();
  15. $this_section = SECTION_PLATFORM_ADMIN;
  16. $extraFields = UserManager::createDataPrivacyExtraFields();
  17. Session::write('data_privacy_extra_fields', $extraFields);
  18. /**
  19. * Prepares the shared SQL query for the user table.
  20. * See get_user_data() and get_number_of_users().
  21. *
  22. * @param bool $getCount Whether to count, or get data
  23. *
  24. * @return string SQL query
  25. */
  26. function prepare_user_sql_query($getCount)
  27. {
  28. $sql = '';
  29. $user_table = Database::get_main_table(TABLE_MAIN_USER);
  30. $admin_table = Database::get_main_table(TABLE_MAIN_ADMIN);
  31. if ($getCount) {
  32. $sql .= "SELECT COUNT(u.id) AS total_number_of_items FROM $user_table u";
  33. } else {
  34. $sql .= 'SELECT u.id AS col0, u.official_code AS col2, ';
  35. if (api_is_western_name_order()) {
  36. $sql .= 'u.firstname AS col3, u.lastname AS col4, ';
  37. } else {
  38. $sql .= 'u.lastname AS col3, u.firstname AS col4, ';
  39. }
  40. $sql .= " u.username AS col5,
  41. u.email AS col6,
  42. u.status AS col7,
  43. u.active AS col8,
  44. u.id AS col9,
  45. u.registration_date AS col10,
  46. u.expiration_date AS exp,
  47. u.password,
  48. v.field_id,
  49. v.updated_at
  50. FROM $user_table u";
  51. }
  52. // adding the filter to see the user's only of the current access_url
  53. if ((api_is_platform_admin() || api_is_session_admin()) && api_get_multiple_access_url()) {
  54. $access_url_rel_user_table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
  55. $sql .= " INNER JOIN $access_url_rel_user_table url_rel_user
  56. ON (u.id=url_rel_user.user_id)";
  57. }
  58. $extraFields = Session::read('data_privacy_extra_fields');
  59. $extraFieldId = $extraFields['delete_legal'];
  60. $extraFieldIdDeleteAccount = $extraFields['delete_account_extra_field'];
  61. $extraFieldValue = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
  62. $sql .= " INNER JOIN $extraFieldValue v
  63. ON (
  64. u.id = v.item_id AND
  65. (field_id = $extraFieldId OR field_id = $extraFieldIdDeleteAccount) AND
  66. v.value = 1
  67. ) ";
  68. $keywordList = [
  69. 'keyword_firstname',
  70. 'keyword_lastname',
  71. 'keyword_username',
  72. 'keyword_email',
  73. 'keyword_officialcode',
  74. 'keyword_status',
  75. 'keyword_active',
  76. 'keyword_inactive',
  77. 'check_easy_passwords',
  78. ];
  79. $keywordListValues = [];
  80. $atLeastOne = false;
  81. foreach ($keywordList as $keyword) {
  82. $keywordListValues[$keyword] = null;
  83. if (isset($_GET[$keyword]) && !empty($_GET[$keyword])) {
  84. $keywordListValues[$keyword] = $_GET[$keyword];
  85. $atLeastOne = true;
  86. }
  87. }
  88. if ($atLeastOne == false) {
  89. $keywordListValues = [];
  90. }
  91. if (isset($_GET['keyword']) && !empty($_GET['keyword'])) {
  92. $keywordFiltered = Database::escape_string("%".$_GET['keyword']."%");
  93. $sql .= " WHERE (
  94. u.firstname LIKE '$keywordFiltered' OR
  95. u.lastname LIKE '$keywordFiltered' OR
  96. concat(u.firstname, ' ', u.lastname) LIKE '$keywordFiltered' OR
  97. concat(u.lastname,' ',u.firstname) LIKE '$keywordFiltered' OR
  98. u.username LIKE '$keywordFiltered' OR
  99. u.official_code LIKE '$keywordFiltered' OR
  100. u.email LIKE '$keywordFiltered'
  101. )
  102. ";
  103. } elseif (isset($keywordListValues) && !empty($keywordListValues)) {
  104. $query_admin_table = '';
  105. $keyword_admin = '';
  106. if (isset($keywordListValues['keyword_status']) &&
  107. $keywordListValues['keyword_status'] == PLATFORM_ADMIN
  108. ) {
  109. $query_admin_table = " , $admin_table a ";
  110. $keyword_admin = ' AND a.user_id = u.id ';
  111. $keywordListValues['keyword_status'] = '%';
  112. }
  113. $keyword_extra_value = '';
  114. $sql .= " $query_admin_table
  115. WHERE (
  116. u.firstname LIKE '".Database::escape_string("%".$keywordListValues['keyword_firstname']."%")."' AND
  117. u.lastname LIKE '".Database::escape_string("%".$keywordListValues['keyword_lastname']."%")."' AND
  118. u.username LIKE '".Database::escape_string("%".$keywordListValues['keyword_username']."%")."' AND
  119. u.email LIKE '".Database::escape_string("%".$keywordListValues['keyword_email']."%")."' AND
  120. u.status LIKE '".Database::escape_string($keywordListValues['keyword_status'])."' ";
  121. if (!empty($keywordListValues['keyword_officialcode'])) {
  122. $sql .= " AND u.official_code LIKE '".Database::escape_string("%".$keywordListValues['keyword_officialcode']."%")."' ";
  123. }
  124. $sql .= "
  125. $keyword_admin
  126. $keyword_extra_value
  127. ";
  128. if (isset($keywordListValues['keyword_active']) &&
  129. !isset($keywordListValues['keyword_inactive'])
  130. ) {
  131. $sql .= " AND u.active = 1";
  132. } elseif (isset($keywordListValues['keyword_inactive']) &&
  133. !isset($keywordListValues['keyword_active'])
  134. ) {
  135. $sql .= " AND u.active = 0";
  136. }
  137. $sql .= " ) ";
  138. }
  139. $preventSessionAdminsToManageAllUsers = api_get_setting('prevent_session_admins_to_manage_all_users');
  140. if (api_is_session_admin() && $preventSessionAdminsToManageAllUsers === 'true') {
  141. $sql .= " AND u.creator_id = ".api_get_user_id();
  142. }
  143. // adding the filter to see the user's only of the current access_url
  144. if ((api_is_platform_admin() || api_is_session_admin()) &&
  145. api_get_multiple_access_url()
  146. ) {
  147. $sql .= " AND url_rel_user.access_url_id = ".api_get_current_access_url_id();
  148. }
  149. return $sql;
  150. }
  151. /**
  152. * Get the total number of users on the platform.
  153. *
  154. * @see SortableTable#get_total_number_of_items()
  155. */
  156. function get_number_of_users()
  157. {
  158. $sql = prepare_user_sql_query(true);
  159. $res = Database::query($sql);
  160. $obj = Database::fetch_object($res);
  161. return $obj->total_number_of_items;
  162. }
  163. /**
  164. * Get the users to display on the current page (fill the sortable-table).
  165. *
  166. * @param int offset of first user to recover
  167. * @param int Number of users to get
  168. * @param int Column to sort on
  169. * @param string Order (ASC,DESC)
  170. *
  171. * @return array Users list
  172. *
  173. * @see SortableTable#get_table_data($from)
  174. */
  175. function get_user_data($from, $number_of_items, $column, $direction)
  176. {
  177. $sql = prepare_user_sql_query(false);
  178. if (!in_array($direction, ['ASC', 'DESC'])) {
  179. $direction = 'ASC';
  180. }
  181. $column = (int) $column;
  182. $from = (int) $from;
  183. $number_of_items = (int) $number_of_items;
  184. $sql .= " ORDER BY col$column $direction ";
  185. $sql .= " LIMIT $from,$number_of_items";
  186. $res = Database::query($sql);
  187. $users = [];
  188. $t = time();
  189. while ($user = Database::fetch_row($res)) {
  190. $userPicture = UserManager::getUserPicture(
  191. $user[0],
  192. USER_IMAGE_SIZE_SMALL
  193. );
  194. $photo = '<img
  195. src="'.$userPicture.'" width="22" height="22"
  196. alt="'.api_get_person_name($user[2], $user[3]).'"
  197. title="'.api_get_person_name($user[2], $user[3]).'" />';
  198. if ($user[7] == 1 && !empty($user[10])) {
  199. // check expiration date
  200. $expiration_time = convert_sql_date($user[10]);
  201. // if expiration date is passed, store a special value for active field
  202. if ($expiration_time < $t) {
  203. $user[7] = '-1';
  204. }
  205. }
  206. // forget about the expiration date field
  207. $users[] = [
  208. $user[0],
  209. $photo,
  210. $user[1],
  211. $user[2],
  212. $user[3],
  213. $user[4],
  214. $user[5],
  215. $user[6],
  216. $user[7],
  217. api_get_local_time($user[9]),
  218. $user[12],
  219. Display::dateToStringAgoAndLongDate($user[13]),
  220. $user[0],
  221. ];
  222. }
  223. return $users;
  224. }
  225. /**
  226. * Returns a mailto-link.
  227. *
  228. * @param string $email An email-address
  229. *
  230. * @return string HTML-code with a mailto-link
  231. */
  232. function email_filter($email)
  233. {
  234. return Display::encrypted_mailto_link($email, $email);
  235. }
  236. /**
  237. * Returns a mailto-link.
  238. *
  239. * @param string $email An email-address
  240. * @param array $params Deprecated
  241. * @param array $row
  242. *
  243. * @return string HTML-code with a mailto-link
  244. */
  245. function user_filter($name, $params, $row)
  246. {
  247. return '<a href="'.api_get_path(WEB_PATH).'whoisonline.php?origin=user_list&id='.$row[0].'">'.$name.'</a>';
  248. }
  249. function requestTypeFilter($fieldId, $url_params, $row)
  250. {
  251. $extraFields = Session::read('data_privacy_extra_fields');
  252. $extraFieldId = $extraFields['delete_legal'];
  253. if ($fieldId == $extraFieldId) {
  254. return get_lang('Delete legal agreement');
  255. } else {
  256. return get_lang('Delete account');
  257. }
  258. }
  259. /**
  260. * Build the modify-column of the table.
  261. *
  262. * @param int The user id
  263. * @param string URL params to add to table links
  264. * @param array Row of elements to alter
  265. *
  266. * @throws Exception
  267. *
  268. * @return string Some HTML-code with modify-buttons
  269. */
  270. function modify_filter($user_id, $url_params, $row)
  271. {
  272. $_admins_list = Session::read('admin_list', []);
  273. $is_admin = in_array($user_id, $_admins_list);
  274. $token = Security::getTokenFromSession();
  275. $result = '';
  276. $result .= '<a href="user_information.php?user_id='.$user_id.'">'.
  277. Display::return_icon('info2.png', get_lang('Information')).'</a>&nbsp;&nbsp;';
  278. $result .= Display::url(
  279. Display::return_icon('message_new.png', get_lang('Send message')),
  280. api_get_path(WEB_CODE_PATH).'messages/new_message.php?send_to_user='.$user_id
  281. );
  282. $result .= '&nbsp;&nbsp;';
  283. $extraFields = Session::read('data_privacy_extra_fields');
  284. $extraFieldId = $extraFields['delete_legal'];
  285. if ($row[10] == $extraFieldId) {
  286. $result .= Display::url(
  287. Display::return_icon('delete_terms.png', get_lang('Remove legal agreement')),
  288. api_get_self().'?user_id='.$user_id.'&action=delete_terms&sec_token='.$token
  289. );
  290. $result .= '&nbsp;&nbsp;';
  291. }
  292. if ($user_id != api_get_user_id()) {
  293. $result .= ' <a href="'.api_get_self().'?action=anonymize&user_id='.$user_id.'&'.$url_params.'&sec_token='.$token.'" onclick="javascript:if(!confirm('."'".addslashes(
  294. api_htmlentities(get_lang('Please confirm your choice'))
  295. )."'".')) return false;">'.
  296. Display::return_icon(
  297. 'anonymous.png',
  298. get_lang('Anonymize'),
  299. [],
  300. ICON_SIZE_SMALL
  301. ).
  302. '</a>';
  303. $result .= ' <a href="'.api_get_self().'?action=delete_user&user_id='.$user_id.'&'.$url_params.'&sec_token='.$token.'" onclick="javascript:if(!confirm('."'".addslashes(
  304. api_htmlentities(get_lang('Please confirm your choice'))
  305. )."'".')) return false;">'.
  306. Display::return_icon(
  307. 'delete.png',
  308. get_lang('Delete'),
  309. [],
  310. ICON_SIZE_SMALL
  311. ).
  312. '</a>';
  313. }
  314. $editProfileUrl = Display::getProfileEditionLink($user_id, true);
  315. $result .= '<a href="'.$editProfileUrl.'">'.
  316. Display::return_icon(
  317. 'edit.png',
  318. get_lang('Edit'),
  319. [],
  320. ICON_SIZE_SMALL
  321. ).
  322. '</a>&nbsp;';
  323. if ($is_admin) {
  324. $result .= Display::return_icon(
  325. 'admin_star.png',
  326. get_lang('Is administrator'),
  327. ['width' => ICON_SIZE_SMALL, 'heigth' => ICON_SIZE_SMALL]
  328. );
  329. } else {
  330. $result .= Display::return_icon(
  331. 'admin_star_na.png',
  332. get_lang('Is not administrator')
  333. );
  334. }
  335. return $result;
  336. }
  337. /**
  338. * Build the active-column of the table to lock or unlock a certain user
  339. * lock = the user can no longer use this account.
  340. *
  341. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  342. *
  343. * @param int $active the current state of the account
  344. * @param string $params
  345. * @param array $row
  346. *
  347. * @return string Some HTML-code with the lock/unlock button
  348. */
  349. function active_filter($active, $params, $row)
  350. {
  351. $_user = api_get_user_info();
  352. if ($active == '1') {
  353. $action = 'Lock';
  354. $image = 'accept';
  355. } elseif ($active == '-1') {
  356. $action = 'edit';
  357. $image = 'warning';
  358. } elseif ($active == '0') {
  359. $action = 'Unlock';
  360. $image = 'error';
  361. }
  362. $result = '';
  363. if ($action === 'edit') {
  364. $result = Display::return_icon(
  365. $image.'.png',
  366. get_lang('Account expired'),
  367. [],
  368. 16
  369. );
  370. } elseif ($row['0'] != $_user['user_id']) {
  371. // you cannot lock yourself out otherwise you could disable all the
  372. // accounts including your own => everybody is locked out and nobody
  373. // can change it anymore.
  374. $result = Display::return_icon(
  375. $image.'.png',
  376. get_lang(ucfirst($action)),
  377. ['onclick' => 'active_user(this);', 'id' => 'img_'.$row['0']],
  378. 16
  379. );
  380. }
  381. return $result;
  382. }
  383. /**
  384. * Instead of displaying the integer of the status, we give a translation for the status.
  385. *
  386. * @param int $status
  387. *
  388. * @return string translation
  389. *
  390. * @version march 2008
  391. *
  392. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  393. */
  394. function status_filter($status)
  395. {
  396. $statusname = api_get_status_langvars();
  397. return $statusname[$status];
  398. }
  399. if (isset($_GET['keyword']) || isset($_GET['keyword_firstname'])) {
  400. $interbreadcrumb[] = ['url' => 'index.php', 'name' => get_lang('Administration')];
  401. $interbreadcrumb[] = ['url' => 'user_list_consent.php', 'name' => get_lang('User list')];
  402. $tool_name = get_lang('Search users');
  403. } else {
  404. $interbreadcrumb[] = ['url' => 'index.php', 'name' => get_lang('Administration')];
  405. $tool_name = get_lang('User list');
  406. }
  407. $message = '';
  408. if (!empty($action)) {
  409. $check = Security::check_token('get');
  410. if ($check) {
  411. switch ($action) {
  412. case 'delete_terms':
  413. UserManager::cleanUserRequestsOfRemoval($_GET['user_id']);
  414. Display::addFlash(Display::return_message(get_lang('Deleted')));
  415. header('Location: '.api_get_self());
  416. exit;
  417. break;
  418. case 'delete_user':
  419. $message = UserManager::deleteUserWithVerification($_GET['user_id']);
  420. Display::addFlash($message);
  421. header('Location: '.api_get_self());
  422. exit;
  423. break;
  424. case 'delete':
  425. if (api_is_platform_admin()) {
  426. $number_of_selected_users = count($_POST['id']);
  427. $number_of_affected_users = 0;
  428. if (is_array($_POST['id'])) {
  429. foreach ($_POST['id'] as $index => $user_id) {
  430. if ($user_id != $_user['user_id']) {
  431. if (UserManager::delete_user($user_id)) {
  432. $number_of_affected_users++;
  433. }
  434. }
  435. }
  436. }
  437. if ($number_of_selected_users == $number_of_affected_users) {
  438. $message = Display::return_message(
  439. get_lang('Selected users deleted'),
  440. 'confirmation'
  441. );
  442. } else {
  443. $message = Display::return_message(
  444. get_lang('Some of the selected users have not been deleted. We recommend you confirm which, by using the advanced search.'),
  445. 'error'
  446. );
  447. }
  448. }
  449. break;
  450. case 'anonymize':
  451. $message = UserManager::anonymizeUserWithVerification($_GET['user_id']);
  452. Display::addFlash($message);
  453. header('Location: '.api_get_self());
  454. exit;
  455. break;
  456. }
  457. Security::clear_token();
  458. }
  459. }
  460. // Create a search-box
  461. $form = new FormValidator('search_simple', 'get', null, null, null, 'inline');
  462. $form->addText(
  463. 'keyword',
  464. get_lang('Search'),
  465. false,
  466. [
  467. 'aria-label' => get_lang('Search users'),
  468. ]
  469. );
  470. $form->addButtonSearch(get_lang('Search'));
  471. $actionsLeft = '';
  472. $actionsCenter = '';
  473. $actionsRight = '';
  474. $actionsLeft .= $form->returnForm();
  475. if (isset($_GET['keyword'])) {
  476. $parameters = ['keyword' => Security::remove_XSS($_GET['keyword'])];
  477. } elseif (isset($_GET['keyword_firstname'])) {
  478. $parameters['keyword_firstname'] = Security::remove_XSS($_GET['keyword_firstname']);
  479. $parameters['keyword_lastname'] = Security::remove_XSS($_GET['keyword_lastname']);
  480. $parameters['keyword_username'] = Security::remove_XSS($_GET['keyword_username']);
  481. $parameters['keyword_email'] = Security::remove_XSS($_GET['keyword_email']);
  482. $parameters['keyword_officialcode'] = Security::remove_XSS($_GET['keyword_officialcode']);
  483. $parameters['keyword_status'] = Security::remove_XSS($_GET['keyword_status']);
  484. $parameters['keyword_active'] = Security::remove_XSS($_GET['keyword_active']);
  485. $parameters['keyword_inactive'] = Security::remove_XSS($_GET['keyword_inactive']);
  486. }
  487. // Create a sortable table with user-data
  488. $parameters['sec_token'] = Security::get_token();
  489. $_admins_list = array_keys(UserManager::get_all_administrators());
  490. Session::write('admin_list', $_admins_list);
  491. // Display Advanced search form.
  492. $form = new FormValidator(
  493. 'advanced_search',
  494. 'get',
  495. '',
  496. '',
  497. [],
  498. FormValidator::LAYOUT_HORIZONTAL
  499. );
  500. $form->addElement('html', '<div id="advanced_search_form" style="display:none;">');
  501. $form->addElement('header', get_lang('Advanced search'));
  502. $form->addText('keyword_firstname', get_lang('First name'), false);
  503. $form->addText('keyword_lastname', get_lang('Last name'), false);
  504. $form->addText('keyword_username', get_lang('Login'), false);
  505. $form->addText('keyword_email', get_lang('e-mail'), false);
  506. $form->addText('keyword_officialcode', get_lang('Code'), false);
  507. $status_options = [];
  508. $status_options['%'] = get_lang('All');
  509. $status_options[STUDENT] = get_lang('Learner');
  510. $status_options[COURSEMANAGER] = get_lang('Trainer');
  511. $status_options[DRH] = get_lang('Human Resources Manager');
  512. $status_options[SESSIONADMIN] = get_lang('Sessions administrator');
  513. $status_options[PLATFORM_ADMIN] = get_lang('Administrator');
  514. $form->addElement(
  515. 'select',
  516. 'keyword_status',
  517. get_lang('Profile'),
  518. $status_options
  519. );
  520. $form->addButtonSearch(get_lang('Search users'));
  521. $defaults = [];
  522. $defaults['keyword_active'] = 1;
  523. $defaults['keyword_inactive'] = 1;
  524. $form->setDefaults($defaults);
  525. $form->addElement('html', '</div>');
  526. $form = $form->returnForm();
  527. $table = new SortableTable(
  528. 'users',
  529. 'get_number_of_users',
  530. 'get_user_data',
  531. (api_is_western_name_order() xor api_sort_by_first_name()) ? 3 : 2
  532. );
  533. $table->set_additional_parameters($parameters);
  534. $table->set_header(0, '', false, 'width="18px"');
  535. $table->set_header(1, get_lang('Photo'), false);
  536. $table->set_header(2, get_lang('Code'));
  537. if (api_is_western_name_order()) {
  538. $table->set_header(3, get_lang('First name'));
  539. $table->set_header(4, get_lang('Last name'));
  540. } else {
  541. $table->set_header(3, get_lang('Last name'));
  542. $table->set_header(4, get_lang('First name'));
  543. }
  544. $table->set_header(5, get_lang('Login'));
  545. $table->set_header(6, get_lang('e-mail'));
  546. $table->set_header(7, get_lang('Profile'));
  547. $table->set_header(8, get_lang('active'), true, 'width="15px"');
  548. $table->set_header(9, get_lang('Registration date'), true, 'width="90px"');
  549. $table->set_header(10, get_lang('Request type'), true, 'width="15px"');
  550. $table->set_header(11, get_lang('Request date'), true, 'width="15px"');
  551. $table->set_header(12, get_lang('Action'), false, 'width="220px"');
  552. $table->set_column_filter(3, 'user_filter');
  553. $table->set_column_filter(4, 'user_filter');
  554. $table->set_column_filter(6, 'email_filter');
  555. $table->set_column_filter(7, 'status_filter');
  556. $table->set_column_filter(8, 'active_filter');
  557. $table->set_column_filter(12, 'modify_filter');
  558. $table->set_column_filter(10, 'requestTypeFilter');
  559. // Only show empty actions bar if delete users has been blocked
  560. $actionsList = [];
  561. if (api_is_platform_admin() &&
  562. !api_get_configuration_value('deny_delete_users')
  563. ) {
  564. $actionsList['delete'] = get_lang('Remove from portal');
  565. }
  566. $table->set_form_actions($actionsList);
  567. $table_result = $table->return_table();
  568. $extra_search_options = '';
  569. $toolbarActions = Display::toolbarAction(
  570. 'toolbarUser',
  571. [$actionsLeft, $actionsCenter, $actionsRight],
  572. [4, 4, 4]
  573. );
  574. $noticeMessage = sprintf(
  575. get_lang('InformationrmationRightToBeForgottenLinkX'),
  576. '<a href="https://gdpr-info.eu/art-17-gdpr/">https://gdpr-info.eu/art-17-gdpr/</a>'
  577. );
  578. $notice = Display::return_message($noticeMessage, 'normal', false);
  579. $tpl = new Template($tool_name);
  580. $tpl->assign('actions', $toolbarActions);
  581. $tpl->assign('message', $message);
  582. $tpl->assign('content', $form.$table_result.$extra_search_options.$notice);
  583. $tpl->display_one_col_template();