user_list.php 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. @author Bart Mollet
  5. @author Julio Montoya <gugli100@gmail.com> BeezNest 2011
  6. * @package chamilo.admin
  7. */
  8. // name of the language file that needs to be included
  9. $language_file = array ('registration','admin');
  10. $cidReset = true;
  11. require_once '../inc/global.inc.php';
  12. require_once api_get_path(LIBRARY_PATH).'sortabletable.class.php';
  13. require_once api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php';
  14. require_once api_get_path(LIBRARY_PATH).'security.lib.php';
  15. require_once api_get_path(LIBRARY_PATH).'xajax/xajax.inc.php';
  16. require_once api_get_path(LIBRARY_PATH).'usermanager.lib.php';
  17. global $_configuration;
  18. // Blocks the possibility to delete a user
  19. $delete_user_available = true;
  20. if (isset($_configuration['deny_delete_users']) && $_configuration['deny_delete_users']) {
  21. $delete_user_available = false;
  22. }
  23. $htmlHeadXtra[] = api_get_jquery_ui_js();
  24. $htmlHeadXtra[] = '<script type="text/javascript">
  25. function load_course_list (div_course,my_user_id) {
  26. $.ajax({
  27. contentType: "application/x-www-form-urlencoded",
  28. beforeSend: function(objeto) {
  29. $("div#"+div_course).html("<img src=\'../inc/lib/javascript/indicator.gif\' />"); },
  30. type: "POST",
  31. url: "course_user_list.php",
  32. data: "user_id="+my_user_id,
  33. success: function(datos) {
  34. $("div#"+div_course).html(datos);
  35. $("div#div_"+my_user_id).attr("class","blackboard_show");
  36. $("div#div_"+my_user_id).attr("style","");
  37. }
  38. });
  39. }
  40. function active_user(element_div) {
  41. id_image=$(element_div).attr("id");
  42. image_clicked=$(element_div).attr("src");
  43. image_clicked_info = image_clicked.split("/");
  44. image_real_clicked = image_clicked_info[image_clicked_info.length-1];
  45. var status = 1;
  46. if (image_real_clicked == "right.gif") {
  47. status = 0;
  48. }
  49. user_id=id_image.split("_");
  50. ident="#img_"+user_id[1];
  51. if (confirm("'.get_lang('AreYouSureToEditTheUserStatus', '').'")) {
  52. $.ajax({
  53. contentType: "application/x-www-form-urlencoded",
  54. beforeSend: function(objeto) {
  55. $(ident).attr("src","'.api_get_path(WEB_IMG_PATH).'loading1.gif'.'"); }, //candy eye stuff
  56. type: "GET",
  57. url: "'.api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php?a=active_user",
  58. data: "user_id="+user_id[1]+"&status="+status,
  59. success: function(datos) {
  60. if (status == 1) {
  61. $(ident).attr("src","'.api_get_path(WEB_IMG_PATH).'right.gif'.'");
  62. $(ident).attr("title","'.get_lang('Lock').'");
  63. } else {
  64. $(ident).attr("src","'.api_get_path(WEB_IMG_PATH).'wrong.gif'.'");
  65. $(ident).attr("title","'.get_lang('Unlock').'");
  66. }
  67. }
  68. });
  69. }
  70. }
  71. function clear_course_list (div_course) {
  72. $("div#"+div_course).html("&nbsp;");
  73. $("div#"+div_course).hide("");
  74. }
  75. function display_advanced_search_form () {
  76. if ($("#advanced_search_form").css("display") == "none") {
  77. $("#advanced_search_form").css("display","block");
  78. $("#img_plus_and_minus").html(\'&nbsp;'.Display::return_icon('div_hide.gif',get_lang('Hide'),array('style'=>'vertical-align:middle')).'&nbsp;'.get_lang('AdvancedSearch').'\');
  79. } else {
  80. $("#advanced_search_form").css("display","none");
  81. $("#img_plus_and_minus").html(\'&nbsp;'.Display::return_icon('div_show.gif',get_lang('Show'),array('style'=>'vertical-align:middle')).'&nbsp;'.get_lang('AdvancedSearch').'\');
  82. }
  83. }
  84. $(document).ready(function() {
  85. var select_val = $("#input_select_extra_data").val();
  86. if ( document.getElementById(\'extra_data_text\')) {
  87. if (select_val != 0) {
  88. document.getElementById(\'extra_data_text\').style.display="block";
  89. if (document.getElementById(\'input_extra_text\'))
  90. document.getElementById(\'input_extra_text\').value = "";
  91. } else {
  92. document.getElementById(\'extra_data_text\').style.display="none";
  93. }
  94. }
  95. $(".agenda_opener").live("click", function() {
  96. var url = this.href;
  97. var dialog = $("#dialog");
  98. if ($("#dialog").length == 0) {
  99. dialog = $(\'<div id="dialog" style="display:hidden"></div> \').appendTo(\'body\');
  100. }
  101. // load remote content
  102. dialog.load(
  103. url,
  104. {},
  105. function(responseText, textStatus, XMLHttpRequest) {
  106. dialog.dialog({width:720, height:550, modal:true});
  107. }
  108. );
  109. //prevent the browser to follow the link
  110. return false;
  111. });
  112. });
  113. //Load user calendar
  114. function load_calendar(user_id, month, year) {
  115. var url = "'.api_get_path(WEB_AJAX_PATH).'agenda.ajax.php?a=get_user_agenda&user_id=" +user_id + "&month="+month+"&year="+year;
  116. $("#dialog").load( url
  117. );
  118. }
  119. </script>';
  120. $htmlHeadXtra[] = '<style type="text/css" media="screen, projection">
  121. .blackboard_show {
  122. float:left;
  123. position:absolute;
  124. border:1px solid black;
  125. width: 200px;
  126. background-color:white;
  127. z-index:99; padding: 3px;
  128. display: inline;
  129. }
  130. .blackboard_hide {
  131. display: none;
  132. }
  133. </style>';
  134. // xajax
  135. $xajax = new xajax();
  136. $xajax->registerFunction('courses_of_user');
  137. //$xajax->registerFunction('empty_courses_of_user');
  138. $xajax->processRequests();
  139. /**
  140. * Get a formatted list of courses for given user
  141. * @param int User ID
  142. * @return resource XAJAX response
  143. */
  144. function courses_of_user($arg) {
  145. // do some stuff based on $arg like query data from a database and
  146. // put it into a variable like $newContent
  147. //$newContent = 'werkt het? en met een beetje meer text, wordt dat goed opgelost? ';
  148. $personal_course_list = UserManager::get_personal_session_course_list($arg);
  149. $newContent = '';
  150. if(count($personal_course_list)>0)
  151. {
  152. foreach ($personal_course_list as $key=>$course)
  153. {
  154. $newContent .= $course['i'].'<br />';
  155. }
  156. }
  157. else
  158. {
  159. $newContent .= '- '.get_lang('None').' -<br />';
  160. }
  161. $newContent = api_convert_encoding($newContent,'utf-8',api_get_system_encoding());
  162. // Instantiate the xajaxResponse object
  163. $objResponse = new xajaxResponse();
  164. // add a command to the response to assign the innerHTML attribute of
  165. // the element with id="SomeElementId" to whatever the new content is
  166. $objResponse->addAssign("user".$arg,"innerHTML", $newContent);
  167. $objResponse->addReplace("coursesofuser".$arg,"alt", $newContent);
  168. $objResponse->addReplace("coursesofuser".$arg,"title", $newContent);
  169. $objResponse->addAssign("user".$arg,"style.display", "block");
  170. //return the xajaxResponse object
  171. return $objResponse;
  172. }
  173. /**
  174. * Empties the XAJAX object representing the courses list
  175. * @param int User ID
  176. * @return resource XAJAX object
  177. */
  178. function empty_courses_of_user($arg)
  179. {
  180. // do some stuff based on $arg like query data from a database and
  181. // put it into a variable like $newContent
  182. $newContent = '';
  183. // Instantiate the xajaxResponse object
  184. $objResponse = new xajaxResponse();
  185. // add a command to the response to assign the innerHTML attribute of
  186. // the element with id="SomeElementId" to whatever the new content is
  187. $objResponse->addAssign("user".$arg,"innerHTML", $newContent);
  188. //return the xajaxResponse object
  189. return $objResponse;
  190. }
  191. $htmlHeadXtra[] = $xajax->getJavascript('../inc/lib/xajax/');
  192. $htmlHeadXtra[] = '<style>
  193. .tooltipLinkInner {
  194. position:relative;
  195. float:left;
  196. color:blue;
  197. text-decoration:none;
  198. }
  199. </style>';
  200. $this_section = SECTION_PLATFORM_ADMIN;
  201. api_protect_admin_script(true);
  202. /**
  203. * Make sure this function is protected because it does NOT check password!
  204. *
  205. * This function defines globals.
  206. * @param int User ID
  207. * @return bool False on failure, redirection on success
  208. * @author Evie Embrechts
  209. * @author Yannick Warnier <yannick.warnier@dokeos.com>
  210. */
  211. function login_user($user_id) {
  212. //init
  213. //Load $_user to be sure we clean it before logging in
  214. global $uidReset, $loginFailed, $_configuration, $_user;
  215. $main_user_table = Database::get_main_table(TABLE_MAIN_USER);
  216. $main_admin_table = Database::get_main_table(TABLE_MAIN_ADMIN);
  217. $track_e_login_table = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_LOGIN);
  218. //logic
  219. unset($_user['user_id']); // uid not in session ? prevent any hacking
  220. if (!isset ($user_id)) {
  221. $uidReset = true;
  222. return;
  223. }
  224. if ($user_id != strval(intval($user_id))) {
  225. return false;
  226. }
  227. $sql_query = "SELECT * FROM $main_user_table WHERE user_id='$user_id'";
  228. $sql_result = Database::query($sql_query);
  229. $result = Database :: fetch_array($sql_result);
  230. // check if the user is allowed to 'login_as'
  231. $can_login_as = (api_is_platform_admin() OR (api_is_session_admin() && $result['status'] == 5 ));
  232. if (!$can_login_as) { return false; }
  233. $firstname = $result['firstname'];
  234. $lastname = $result['lastname'];
  235. $user_id = $result['user_id'];
  236. //$message = "Attempting to login as ".api_get_person_name($firstname, $lastname)." (id ".$user_id.")";
  237. if (api_is_western_name_order()) {
  238. $message = sprintf(get_lang('AttemptingToLoginAs'),$firstname,$lastname,$user_id);
  239. } else {
  240. $message = sprintf(get_lang('AttemptingToLoginAs'), $lastname, $firstname, $user_id);
  241. }
  242. $loginFailed = false;
  243. $uidReset = false;
  244. if ($user_id) { // a uid is given (log in succeeded)
  245. $sql_query = "SELECT user.*, a.user_id is_admin,
  246. UNIX_TIMESTAMP(login.login_date) login_date
  247. FROM $main_user_table
  248. LEFT JOIN $main_admin_table a
  249. ON user.user_id = a.user_id
  250. LEFT JOIN $track_e_login_table login
  251. ON user.user_id = login.login_user_id
  252. WHERE user.user_id = '".$user_id."'
  253. ORDER BY login.login_date DESC LIMIT 1";
  254. $sql_result = Database::query($sql_query);
  255. if (Database::num_rows($sql_result) > 0) {
  256. // Extracting the user data
  257. $user_data = Database::fetch_array($sql_result);
  258. //Delog the current user
  259. LoginDelete($_SESSION["_user"]["user_id"]);
  260. // Cleaning session variables
  261. unset($_SESSION['_user']);
  262. unset($_SESSION['is_platformAdmin']);
  263. unset($_SESSION['is_allowedCreateCourse']);
  264. unset($_SESSION['_uid']);
  265. $_user['firstName'] = $user_data['firstname'];
  266. $_user['lastName'] = $user_data['lastname'];
  267. $_user['mail'] = $user_data['email'];
  268. $_user['lastLogin'] = $user_data['login_date'];
  269. $_user['official_code'] = $user_data['official_code'];
  270. $_user['picture_uri'] = $user_data['picture_uri'];
  271. $_user['user_id'] = $user_data['user_id'];
  272. $_user['status'] = $user_data['status'];
  273. $is_platformAdmin = (bool) (!is_null($user_data['is_admin']));
  274. $is_allowedCreateCourse = (bool) ($user_data['status'] == 1);
  275. // Filling session variables with new data
  276. $_SESSION['_uid'] = $user_id;
  277. $_SESSION['_user'] = $_user;
  278. $_SESSION['is_platformAdmin'] = $is_platformAdmin;
  279. $_SESSION['is_allowedCreateCourse'] = $is_allowedCreateCourse;
  280. $_SESSION['login_as'] = true; // will be usefull later to know if the user is actually an admin or not (example reporting)s
  281. $target_url = api_get_path(WEB_PATH)."user_portal.php";
  282. //$message .= "<br/>Login successful. Go to <a href=\"$target_url\">$target_url</a>";
  283. $message .= '<br />'.sprintf(get_lang('LoginSuccessfulGoToX'),'<a href="'.$target_url.'">'.$target_url.'</a>');
  284. Display :: display_header(get_lang('UserList'));
  285. Display :: display_normal_message($message,false);
  286. Display :: display_footer();
  287. exit;
  288. } else {
  289. exit ("<br />WARNING UNDEFINED UID !! ");
  290. }
  291. }
  292. }
  293. /**
  294. * Get the total number of users on the platform
  295. * @see SortableTable#get_total_number_of_items()
  296. */
  297. function get_number_of_users() {
  298. $user_table = Database :: get_main_table(TABLE_MAIN_USER);
  299. $sql = "SELECT COUNT(u.user_id) AS total_number_of_items FROM $user_table u";
  300. // adding the filter to see the user's only of the current access_url
  301. if ((api_is_platform_admin() || api_is_session_admin()) && api_get_multiple_access_url()) {
  302. $access_url_rel_user_table= Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
  303. $sql.= " INNER JOIN $access_url_rel_user_table url_rel_user ON (u.user_id=url_rel_user.user_id)";
  304. }
  305. if (isset($_GET['keyword_extra_data'])) {
  306. $keyword_extra_data = Database::escape_string($_GET['keyword_extra_data']);
  307. if (!empty($keyword_extra_data)) {
  308. $extra_info = UserManager::get_extra_field_information_by_name($keyword_extra_data);
  309. $field_id = $extra_info['id'];
  310. $sql.= " INNER JOIN user_field_values ufv ON u.user_id=ufv.user_id AND ufv.field_id=$field_id ";
  311. }
  312. }
  313. if ( isset ($_GET['keyword'])) {
  314. $keyword = Database::escape_string(trim($_GET['keyword']));
  315. $sql .= " WHERE (u.firstname LIKE '%".$keyword."%' OR u.lastname LIKE '%".$keyword."%' OR concat(u.firstname,' ',u.lastname) LIKE '%".$keyword."%' OR concat(u.lastname,' ',u.firstname) LIKE '%".$keyword."%' OR u.username LIKE '%".$keyword."%' OR u.email LIKE '%".$keyword."%' OR u.official_code LIKE '%".$keyword."%') ";
  316. } elseif (isset ($_GET['keyword_firstname'])) {
  317. $admin_table = Database :: get_main_table(TABLE_MAIN_ADMIN);
  318. $keyword_firstname = Database::escape_string($_GET['keyword_firstname']);
  319. $keyword_lastname = Database::escape_string($_GET['keyword_lastname']);
  320. $keyword_email = Database::escape_string($_GET['keyword_email']);
  321. $keyword_officialcode = Database::escape_string($_GET['keyword_officialcode']);
  322. $keyword_username = Database::escape_string($_GET['keyword_username']);
  323. $keyword_status = Database::escape_string($_GET['keyword_status']);
  324. $query_admin_table = '';
  325. $keyword_admin = '';
  326. if ($keyword_status == SESSIONADMIN) {
  327. $keyword_status = '%';
  328. $query_admin_table = " , $admin_table a ";
  329. $keyword_admin = ' AND a.user_id = u.user_id ';
  330. }
  331. $keyword_extra_value = '';
  332. if (isset($_GET['keyword_extra_data'])) {
  333. if (!empty($_GET['keyword_extra_data']) && !empty($_GET['keyword_extra_data_text'])) {
  334. $keyword_extra_data_text = Database::escape_string($_GET['keyword_extra_data_text']);
  335. $keyword_extra_value = " AND ufv.field_value LIKE '%".trim($keyword_extra_data_text)."%' ";
  336. }
  337. }
  338. $keyword_active = isset($_GET['keyword_active']);
  339. $keyword_inactive = isset($_GET['keyword_inactive']);
  340. $sql .= $query_admin_table .
  341. " WHERE (u.firstname LIKE '%".$keyword_firstname."%' " .
  342. "AND u.lastname LIKE '%".$keyword_lastname."%' " .
  343. "AND u.username LIKE '%".$keyword_username."%' " .
  344. "AND u.email LIKE '%".$keyword_email."%' " .
  345. "AND u.official_code LIKE '%".$keyword_officialcode."%'" .
  346. "AND u.status LIKE '".$keyword_status."'" .
  347. $keyword_admin.$keyword_extra_value;
  348. if($keyword_active && !$keyword_inactive) {
  349. $sql .= " AND u.active='1'";
  350. } elseif($keyword_inactive && !$keyword_active) {
  351. $sql .= " AND u.active='0'";
  352. }
  353. $sql .= " ) ";
  354. }
  355. // adding the filter to see the user's only of the current access_url
  356. if ((api_is_platform_admin() || api_is_session_admin()) && api_get_multiple_access_url()) {
  357. $sql.= " AND url_rel_user.access_url_id=".api_get_current_access_url_id();
  358. }
  359. $res = Database::query($sql);
  360. $obj = Database::fetch_object($res);
  361. return $obj->total_number_of_items;
  362. }
  363. /**
  364. * Get the users to display on the current page (fill the sortable-table)
  365. * @param int offset of first user to recover
  366. * @param int Number of users to get
  367. * @param int Column to sort on
  368. * @param string Order (ASC,DESC)
  369. * @see SortableTable#get_table_data($from)
  370. */
  371. function get_user_data($from, $number_of_items, $column, $direction)
  372. {
  373. global $origin;
  374. $user_table = Database :: get_main_table(TABLE_MAIN_USER);
  375. $admin_table = Database :: get_main_table(TABLE_MAIN_ADMIN);
  376. $sql = "SELECT
  377. u.user_id AS col0,
  378. u.official_code AS col2,
  379. ".(api_is_western_name_order()
  380. ? "u.firstname AS col3,
  381. u.lastname AS col4,"
  382. : "u.lastname AS col3,
  383. u.firstname AS col4,")."
  384. u.username AS col5,
  385. u.email AS col6,
  386. u.status AS col7,
  387. u.active AS col8,
  388. u.user_id AS col9 ".
  389. ", u.expiration_date AS exp ".
  390. " FROM $user_table u ";
  391. // adding the filter to see the user's only of the current access_url
  392. if ((api_is_platform_admin() || api_is_session_admin()) && api_get_multiple_access_url()) {
  393. $access_url_rel_user_table= Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
  394. $sql.= " INNER JOIN $access_url_rel_user_table url_rel_user ON (u.user_id=url_rel_user.user_id)";
  395. }
  396. if (isset($_GET['keyword_extra_data'])) {
  397. $keyword_extra_data = Database::escape_string($_GET['keyword_extra_data']);
  398. if (!empty($keyword_extra_data)) {
  399. $extra_info = UserManager::get_extra_field_information_by_name($keyword_extra_data);
  400. $field_id = $extra_info['id'];
  401. $sql.= " INNER JOIN user_field_values ufv ON u.user_id=ufv.user_id AND ufv.field_id=$field_id ";
  402. }
  403. }
  404. if (isset ($_GET['keyword'])) {
  405. $keyword = Database::escape_string(trim($_GET['keyword']));
  406. $sql .= " WHERE (u.firstname LIKE '%".$keyword."%' OR u.lastname LIKE '%".$keyword."%' OR concat(u.firstname,' ',u.lastname) LIKE '%".$keyword."%' OR concat(u.lastname,' ',u.firstname) LIKE '%".$keyword."%' OR u.username LIKE '%".$keyword."%' OR u.official_code LIKE '%".$keyword."%' OR u.email LIKE '%".$keyword."%' )";
  407. } elseif (isset ($_GET['keyword_firstname'])) {
  408. $keyword_firstname = Database::escape_string($_GET['keyword_firstname']);
  409. $keyword_lastname = Database::escape_string($_GET['keyword_lastname']);
  410. $keyword_email = Database::escape_string($_GET['keyword_email']);
  411. $keyword_officialcode = Database::escape_string($_GET['keyword_officialcode']);
  412. $keyword_username = Database::escape_string($_GET['keyword_username']);
  413. $keyword_status = Database::escape_string($_GET['keyword_status']);
  414. $query_admin_table = '';
  415. $keyword_admin = '';
  416. if ($keyword_status == SESSIONADMIN) {
  417. $keyword_status = '%';
  418. $query_admin_table = " , $admin_table a ";
  419. $keyword_admin = ' AND a.user_id = u.user_id ';
  420. }
  421. $keyword_extra_value = '';
  422. if (isset($_GET['keyword_extra_data'])) {
  423. if (!empty($_GET['keyword_extra_data']) && !empty($_GET['keyword_extra_data_text'])) {
  424. $keyword_extra_data_text = Database::escape_string($_GET['keyword_extra_data_text']);
  425. $keyword_extra_value = " AND ufv.field_value LIKE '%".trim($keyword_extra_data_text)."%' ";
  426. }
  427. }
  428. $keyword_active = isset($_GET['keyword_active']);
  429. $keyword_inactive = isset($_GET['keyword_inactive']);
  430. $sql .= $query_admin_table." WHERE (u.firstname LIKE '%".$keyword_firstname."%' " .
  431. "AND u.lastname LIKE '%".$keyword_lastname."%' " .
  432. "AND u.username LIKE '%".$keyword_username."%' " .
  433. "AND u.email LIKE '%".$keyword_email."%' " .
  434. "AND u.official_code LIKE '%".$keyword_officialcode."%' " .
  435. "AND u.status LIKE '".$keyword_status."'" .
  436. $keyword_admin.$keyword_extra_value;
  437. if ($keyword_active && !$keyword_inactive) {
  438. $sql .= " AND u.active='1'";
  439. } elseif($keyword_inactive && !$keyword_active) {
  440. $sql .= " AND u.active='0'";
  441. }
  442. $sql .= " ) ";
  443. }
  444. // adding the filter to see the user's only of the current access_url
  445. if ((api_is_platform_admin() || api_is_session_admin()) && api_get_multiple_access_url()) {
  446. $sql.= " AND url_rel_user.access_url_id=".api_get_current_access_url_id();
  447. }
  448. if (!in_array($direction, array('ASC','DESC'))) {
  449. $direction = 'ASC';
  450. }
  451. $column = intval($column);
  452. $from = intval($from);
  453. $number_of_items = intval($number_of_items);
  454. $sql .= " ORDER BY col$column $direction ";
  455. $sql .= " LIMIT $from,$number_of_items";
  456. $res = Database::query($sql);
  457. $users = array ();
  458. $t = time();
  459. while ($user = Database::fetch_row($res)) {
  460. $image_path = UserManager::get_user_picture_path_by_id($user[0], 'web', false, true);
  461. $user_profile = UserManager::get_picture_user($user[0], $image_path['file'], 22, USER_IMAGE_SIZE_SMALL, ' width="22" height="22" ');
  462. if (!api_is_anonymous()) {
  463. $photo = '<center><a href="'.api_get_path(WEB_PATH).'whoisonline.php?origin=user_list&id='.$user[0].'" title="'.get_lang('Info').'" ><img src="'.$user_profile['file'].'" '.$user_profile['style'].' alt="'.api_get_person_name($user[2],$user[3]).'" title="'.api_get_person_name($user[2], $user[3]).'" /></a></center>';
  464. } else {
  465. $photo = '<center><img src="'.$user_profile['file'].'" '.$user_profile['style'].' alt="'.api_get_person_name($user[2], $user[3]).'" title="'.api_get_person_name($user[2], $user[3]).'" /></center>';
  466. }
  467. if ($user[7] == 1 && $user[9] != '0000-00-00 00:00:00') {
  468. // check expiration date
  469. $expiration_time = convert_mysql_date($user[9]);
  470. // if expiration date is passed, store a special value for active field
  471. if ($expiration_time < $t) {
  472. $user[7] = '-1';
  473. }
  474. }
  475. // forget about the expiration date field
  476. $users[] = array($user[0],$photo,$user[1],$user[2],$user[3],$user[4],$user[5],$user[6],$user[7],$user[8]);
  477. }
  478. return $users;
  479. }
  480. /**
  481. * Returns a mailto-link
  482. * @param string $email An email-address
  483. * @return string HTML-code with a mailto-link
  484. */
  485. function email_filter($email)
  486. {
  487. return Display :: encrypted_mailto_link($email, $email);
  488. }
  489. /**
  490. * Returns a mailto-link
  491. * @param string $email An email-address
  492. * @return string HTML-code with a mailto-link
  493. */
  494. function user_filter($name, $params, $row) {
  495. return '<a href="'.api_get_path(WEB_PATH).'whoisonline.php?origin=user_list&id='.$row[0].'">'.$name.'</a>';
  496. }
  497. /**
  498. * Build the modify-column of the table
  499. * @param int The user id
  500. * @param string URL params to add to table links
  501. * @param array Row of elements to alter
  502. * @return string Some HTML-code with modify-buttons
  503. */
  504. function modify_filter($user_id,$url_params,$row) {
  505. global $charset, $_user, $_admins_list, $delete_user_available;
  506. $is_admin = in_array($user_id,$_admins_list);
  507. $statusname = api_get_status_langvars();
  508. $user_is_anonymous = false;
  509. if ($row['7'] == $statusname[ANONYMOUS]) {
  510. $user_is_anonymous =true;
  511. }
  512. $result = '';
  513. if (!$user_is_anonymous) {
  514. $result .= '<a href="javascript:void(0)" onclick="load_course_list(\'div_'.$user_id.'\','.$user_id.')">
  515. <img onclick="load_course_list(\'div_'.$user_id.'\','.$user_id.')" onmouseout="clear_course_list (\'div_'.$user_id.'\')" src="../img/course.gif" title="'.get_lang('Courses').'" alt="'.get_lang('Courses').'"/>
  516. <div class="blackboard_hide" id="div_'.$user_id.'">&nbsp;&nbsp;</div>
  517. </a>&nbsp;&nbsp;';
  518. } else {
  519. $result .= Display::return_icon('course_na.gif',get_lang('Courses')).'&nbsp;&nbsp;';
  520. }
  521. if (api_is_platform_admin()) {
  522. if (!$user_is_anonymous) {
  523. $result .= '<a href="user_information.php?user_id='.$user_id.'">'.Display::return_icon('synthese_view.gif', get_lang('Info')).'</a>&nbsp;&nbsp;';
  524. } else {
  525. $result .= Display::return_icon('synthese_view_na.gif', get_lang('Info')).'&nbsp;&nbsp;';
  526. }
  527. }
  528. //only allow platform admins to login_as, or session admins only for students (not teachers nor other admins)
  529. if (api_is_platform_admin() || (api_is_session_admin() && $row['7'] == $statusname[STUDENT])) {
  530. if (!$user_is_anonymous) {
  531. $result .= '<a href="user_list.php?action=login_as&amp;user_id='.$user_id.'&amp;sec_token='.$_SESSION['sec_token'].'">'.Display::return_icon('login_as.gif', get_lang('LoginAs')).'</a>&nbsp;&nbsp;';
  532. } else {
  533. $result .= Display::return_icon('login_as_na.gif', get_lang('LoginAs')).'&nbsp;&nbsp;';
  534. }
  535. } else {
  536. $result .= Display::return_icon('login_as_na.gif', get_lang('LoginAs')).'&nbsp;&nbsp;';
  537. }
  538. if ($row['7'] != $statusname[STUDENT]) {
  539. $result .= Display::return_icon('statistics_na.gif', get_lang('Reporting')).'&nbsp;&nbsp;';
  540. } else {
  541. $result .= '<a href="../mySpace/myStudents.php?student='.$user_id.'">'.Display::return_icon('statistics.gif', get_lang('Reporting')).'</a>&nbsp;&nbsp;';
  542. }
  543. if (api_is_platform_admin()) {
  544. if (!$user_is_anonymous) {
  545. $result .= '<a href="user_edit.php?user_id='.$user_id.'">'.Display::return_icon('edit.png', get_lang('Edit'), array(), 22).'</a>&nbsp;';
  546. } else {
  547. $result .= Display::return_icon('edit_na.png', get_lang('Edit'), array(), 22).'</a>&nbsp;';
  548. }
  549. }
  550. if ($is_admin) {
  551. $result .= Display::return_icon('admin_star.png', get_lang('IsAdministrator'),array('width'=> 22, 'heigth'=> 22));
  552. } else {
  553. $result .= Display::return_icon('admin_star_na.png', get_lang('IsNotAdministrator'));
  554. }
  555. // actions for assigning sessions, courses or users
  556. if (api_is_session_admin()) {
  557. /*if ($row[0] == api_get_user_id()) {
  558. $result .= '<a href="dashboard_add_sessions_to_user.php?user='.$user_id.'">'.Display::return_icon('view_more_stats.gif', get_lang('AssignSessions')).'</a>&nbsp;&nbsp;';
  559. }*/
  560. } else {
  561. if ($row['7'] == $statusname[DRH] || UserManager::is_admin($row[0])) {
  562. $result .= '<a href="dashboard_add_users_to_user.php?user='.$user_id.'">'.Display::return_icon('user_subscribe_course.png', get_lang('AssignUsers'),'','22').'</a>';
  563. $result .= '<a href="dashboard_add_courses_to_user.php?user='.$user_id.'">'.Display::return_icon('course_add.gif', get_lang('AssignCourses')).'</a>&nbsp;&nbsp;';
  564. $result .= '<a href="dashboard_add_sessions_to_user.php?user='.$user_id.'">'.Display::return_icon('view_more_stats.gif', get_lang('AssignSessions')).'</a>&nbsp;&nbsp;';
  565. } else if ($row['7'] == $statusname[SESSIONADMIN]) {
  566. $result .= '<a href="dashboard_add_sessions_to_user.php?user='.$user_id.'">'.Display::return_icon('view_more_stats.gif', get_lang('AssignSessions')).'</a>&nbsp;&nbsp;';
  567. }
  568. }
  569. if (api_is_platform_admin()) {
  570. $result .= ' <a href="'.api_get_path(WEB_AJAX_PATH).'agenda.ajax.php?a=get_user_agenda&amp;user_id='.$user_id.'" class="agenda_opener">'.Display::return_icon('month.png', get_lang('FreeBusyCalendar'), array(), 22).'</a>';
  571. if ($delete_user_available) {
  572. if ($row[0] != $_user['user_id'] && !$user_is_anonymous) {
  573. // you cannot lock yourself out otherwise you could disable all the accounts including your own => everybody is locked out and nobody can change it anymore.
  574. $result .= ' <a href="user_list.php?action=delete_user&amp;user_id='.$user_id.'&amp;'.$url_params.'&amp;sec_token='.$_SESSION['sec_token'].'" onclick="javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang("ConfirmYourChoice"),ENT_QUOTES,$charset))."'".')) return false;">'.Display::return_icon('delete.png', get_lang('Delete'), array(), 22).'</a>';
  575. } else {
  576. $result .= Display::return_icon('delete_na.png', get_lang('Delete'), array(), 22);
  577. }
  578. }
  579. }
  580. return $result;
  581. }
  582. /**
  583. * Build the active-column of the table to lock or unlock a certain user
  584. * lock = the user can no longer use this account
  585. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  586. * @param int $active the current state of the account
  587. * @param int $user_id The user id
  588. * @param string $url_params
  589. * @return string Some HTML-code with the lock/unlock button
  590. */
  591. function active_filter($active, $url_params, $row) {
  592. global $_user;
  593. if ($active=='1') {
  594. $action='Lock';
  595. $image='right';
  596. } elseif ($active=='-1') {
  597. $action='edit';
  598. $image='expired';
  599. } elseif ($active=='0') {
  600. $action='Unlock';
  601. $image='wrong';
  602. }
  603. $result = '';
  604. if ($action=='edit') {
  605. $result = Display::return_icon($image.'.gif', get_lang('AccountExpired'));
  606. } elseif ($row['0']<>$_user['user_id']) {
  607. // you cannot lock yourself out otherwise you could disable all the accounts including your own => everybody is locked out and nobody can change it anymore.
  608. //$result = '<a href="user_list.php?action='.$action.'&amp;user_id='.$row['0'].'&amp;'.$url_params.'&amp;sec_token='.$_SESSION['sec_token'].'">'.Display::return_icon($image.'.gif', get_lang(ucfirst($action))).'</a>';
  609. //$result = '<a href="'.api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php?action=active_user&amp;user_id='.$row['0'].'&amp;'.$url_params.'&amp;sec_token='.$_SESSION['sec_token'].'">';
  610. $result = Display::return_icon($image.'.gif', get_lang(ucfirst($action)), array('onclick'=>'active_user(this);', 'id'=>'img_'.$row['0'])).'</a>';
  611. //$result .= '<div>';
  612. }
  613. return $result;
  614. }
  615. /**
  616. * Lock or unlock a user
  617. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  618. * @param int $status, do we want to lock the user ($status=lock) or unlock it ($status=unlock)
  619. * @param int $user_id The user id
  620. * @return language variable
  621. */
  622. function lock_unlock_user($status,$user_id)
  623. {
  624. $user_table = Database :: get_main_table(TABLE_MAIN_USER);
  625. if ($status=='lock')
  626. {
  627. $status_db='0';
  628. $return_message=get_lang('UserLocked');
  629. }
  630. if ($status=='unlock')
  631. {
  632. $status_db='1';
  633. $return_message=get_lang('UserUnlocked');
  634. }
  635. if(($status_db=='1' OR $status_db=='0') AND is_numeric($user_id))
  636. {
  637. $sql="UPDATE $user_table SET active='".Database::escape_string($status_db)."' WHERE user_id='".Database::escape_string($user_id)."'";
  638. $result = Database::query($sql);
  639. }
  640. if ($result)
  641. {
  642. return $return_message;
  643. }
  644. }
  645. /**
  646. * Instead of displaying the integer of the status, we give a translation for the status
  647. *
  648. * @param integer $status
  649. * @return string translation
  650. *
  651. * @version march 2008
  652. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  653. */
  654. function status_filter($status)
  655. {
  656. $statusname = api_get_status_langvars();
  657. return $statusname[$status];
  658. }
  659. /** INIT SECTION */
  660. $action = $_GET["action"];
  661. $login_as_user_id = $_GET["user_id"];
  662. // Login as ...
  663. if ($_GET['action'] == "login_as" && isset ($login_as_user_id)) {
  664. login_user($login_as_user_id);
  665. }
  666. if (isset($_GET['keyword']) || isset($_GET['keyword_firstname'])) {
  667. $interbreadcrumb[] = array ("url" => 'index.php', "name" => get_lang('PlatformAdmin'));
  668. $interbreadcrumb[] = array ("url" => 'user_list.php', "name" => get_lang('UserList'));
  669. $tool_name = get_lang('SearchUsers');
  670. } else {
  671. $interbreadcrumb[] = array ("url" => 'index.php', "name" => get_lang('PlatformAdmin'));
  672. $tool_name = get_lang('UserList');
  673. }
  674. Display :: display_header($tool_name, "");
  675. //api_display_tool_title($tool_name);
  676. if (isset ($_GET['action'])) {
  677. $check = Security::check_token('get');
  678. if ($check) {
  679. switch ($_GET['action']) {
  680. case 'show_message' :
  681. if (!empty($_GET['warn'])) {
  682. // to prevent too long messages
  683. if ($_GET['warn'] == 'session_message'){
  684. $_GET['warn'] = $_SESSION['session_message_import_users'];
  685. }
  686. Display::display_warning_message(urldecode($_GET['warn']),false);
  687. }
  688. if (!empty($_GET['message'])) {
  689. Display :: display_confirmation_message(stripslashes($_GET['message']));
  690. }
  691. break;
  692. case 'delete_user' :
  693. if (api_is_platform_admin()) {
  694. if ($delete_user_available) {
  695. if ($user_id != $_user['user_id'] && UserManager :: delete_user($_GET['user_id'])) {
  696. Display :: display_confirmation_message(get_lang('UserDeleted'));
  697. } else {
  698. Display :: display_error_message(get_lang('CannotDeleteUserBecauseOwnsCourse'));
  699. }
  700. } else {
  701. Display :: display_error_message(get_lang('CannotDeleteUser'));
  702. }
  703. }
  704. break;
  705. case 'lock' :
  706. $message=lock_unlock_user('lock',$_GET['user_id']);
  707. Display :: display_normal_message($message);
  708. break;
  709. case 'unlock';
  710. $message=lock_unlock_user('unlock',$_GET['user_id']);
  711. Display :: display_normal_message($message);
  712. break;
  713. }
  714. Security::clear_token();
  715. }
  716. }
  717. if (isset ($_POST['action'])) {
  718. $check = Security::check_token('get');
  719. if ($check) {
  720. switch ($_POST['action']) {
  721. case 'delete' :
  722. if (api_is_platform_admin()) {
  723. $number_of_selected_users = count($_POST['id']);
  724. $number_of_deleted_users = 0;
  725. if (is_array($_POST['id'])) {
  726. foreach ($_POST['id'] as $index => $user_id)
  727. {
  728. if($user_id != $_user['user_id'])
  729. {
  730. if(UserManager :: delete_user($user_id))
  731. {
  732. $number_of_deleted_users++;
  733. }
  734. }
  735. }
  736. }
  737. if($number_of_selected_users == $number_of_deleted_users)
  738. {
  739. Display :: display_confirmation_message(get_lang('SelectedUsersDeleted'));
  740. }
  741. else
  742. {
  743. Display :: display_error_message(get_lang('SomeUsersNotDeleted'));
  744. }
  745. }
  746. break;
  747. }
  748. Security::clear_token();
  749. }
  750. }
  751. // Create a search-box
  752. $form = new FormValidator('search_simple','get','','',null,false);
  753. $renderer =& $form->defaultRenderer();
  754. $renderer->setElementTemplate('<span>{element}</span> ');
  755. $form->addElement('text','keyword',get_lang('keyword'));
  756. $form->addElement('style_submit_button', 'submit',get_lang('Search'),'class="search"');
  757. //$form->addElement('static','search_advanced_link',null,'<a href="user_list.php?search=advanced">'.get_lang('AdvancedSearch').'</a>');
  758. $form->addElement('static','search_advanced_link',null,'<a href="javascript://" class = "advanced_parameters" onclick="display_advanced_search_form();"><span id="img_plus_and_minus">&nbsp;'.Display::return_icon('div_show.gif',get_lang('Show'),array('style'=>'vertical-align:middle')).' '.get_lang('AdvancedSearch').'</span></a>');
  759. echo '<div class="actions" style="width:100%;">';
  760. if (api_is_platform_admin()) {
  761. echo '<span style="float:right; padding-top:7px;">'.
  762. '<a href="'.api_get_path(WEB_CODE_PATH).'admin/user_add.php">'.Display::return_icon('new_user.png',get_lang('AddUsers'),'','32').'</a>'.
  763. '</span>';
  764. }
  765. $form->display();
  766. echo '</div>';
  767. if (isset ($_GET['keyword'])) {
  768. $parameters = array ('keyword' => Security::remove_XSS($_GET['keyword']));
  769. } elseif (isset ($_GET['keyword_firstname'])) {
  770. $parameters['keyword_firstname'] = Security::remove_XSS($_GET['keyword_firstname']);
  771. $parameters['keyword_lastname'] = Security::remove_XSS($_GET['keyword_lastname']);
  772. $parameters['keyword_email'] = Security::remove_XSS($_GET['keyword_email']);
  773. $parameters['keyword_officialcode'] = Security::remove_XSS($_GET['keyword_officialcode']);
  774. $parameters['keyword_status'] = Security::remove_XSS($_GET['keyword_status']);
  775. $parameters['keyword_active'] = Security::remove_XSS($_GET['keyword_active']);
  776. $parameters['keyword_inactive'] = Security::remove_XSS($_GET['keyword_inactive']);
  777. }
  778. // Create a sortable table with user-data
  779. $parameters['sec_token'] = Security::get_token();
  780. // get the list of all admins to mark them in the users list
  781. $admin_table = Database::get_main_table(TABLE_MAIN_ADMIN);
  782. $sql_admin = "SELECT user_id FROM $admin_table";
  783. $res_admin = Database::query($sql_admin);
  784. $_admins_list = array();
  785. while ($row_admin = Database::fetch_row($res_admin)) {
  786. $_admins_list[] = $row_admin[0];
  787. }
  788. // display advaced search form
  789. $form = new FormValidator('advanced_search','get');
  790. $form->addElement('html','<div id="advanced_search_form" style="display:none;">');
  791. $form->addElement('header', '', get_lang('AdvancedSearch'));
  792. //$form->addElement('html', '<strong>'.get_lang('SearchAUser').'</strong>');
  793. $form->addElement('html', '<table>');
  794. $form->addElement('html', '<tr><td>');
  795. $form->add_textfield('keyword_firstname',get_lang('FirstName'),false,array('style'=>'margin-left:17px'));
  796. $form->addElement('html', '</td><td width="200px;">');
  797. $form->add_textfield('keyword_lastname',get_lang('LastName'),false,array('style'=>'margin-left:17px'));
  798. $form->addElement('html', '</td></tr>');
  799. $form->addElement('html', '<tr><td>');
  800. $form->add_textfield('keyword_username',get_lang('LoginName'),false,array('style'=>'margin-left:17px'));
  801. $form->addElement('html', '</td>');
  802. $form->addElement('html', '<td>');
  803. $form->add_textfield('keyword_email',get_lang('Email'),false,array('style'=>'margin-left:17px'));
  804. $form->addElement('html', '</td></tr>');
  805. $form->addElement('html', '<tr><td>');
  806. $form->add_textfield('keyword_officialcode',get_lang('OfficialCode'),false,array('style'=>'margin-left:17px'));
  807. $form->addElement('html', '</td><td>');
  808. $status_options = array();
  809. $status_options['%'] = get_lang('All');
  810. $status_options[STUDENT] = get_lang('Student');
  811. $status_options[COURSEMANAGER] = get_lang('Teacher');
  812. $status_options[DRH] = get_lang('Drh');
  813. $status_options[SESSIONADMIN] = get_lang('Administrator');
  814. $form->addElement('select','keyword_status',get_lang('Profile'),$status_options, array('style'=>'margin-left:17px'));
  815. $form->addElement('html', '</td></tr>');
  816. $form->addElement('html', '<tr><td>');
  817. $active_group = array();
  818. $active_group[] = $form->createElement('checkbox','keyword_active','',get_lang('Active'), array('style'=>'margin-left:17px'));
  819. $active_group[] = $form->createElement('checkbox','keyword_inactive','',get_lang('Inactive'),array('style'=>'margin-left:17px'));
  820. $form->addGroup($active_group,'',get_lang('ActiveAccount'),'<br/>',false);
  821. $form->addElement('html', '</td><td>');
  822. /*
  823. * @todo fix this code
  824. $extra_data = UserManager::get_extra_fields( 0,10,5, 'ASC', true, 1);
  825. var_dump($extra_data);
  826. $extra_options = array();
  827. if (!empty($extra_data)) {
  828. $extra_options[0] = get_lang('All');
  829. // get information about extra data for adding to input select
  830. foreach ($extra_data as $field_variable => $field_value) {
  831. $extra = UserManager::get_extra_field_information_by_name($field_variable);
  832. $extra_options[$field_variable] = $extra['field_display_text'];
  833. }
  834. $form->addElement('select', 'keyword_extra_data', get_lang('ExtraData'), $extra_options, array('id'=>'input_select_extra_data', 'style'=>'margin-left:17px', 'onchange'=>'if(this.value!=0){document.getElementById(\'extra_data_text\').style.display=\'block\';document.getElementById(\'input_extra_text\').value = "";}else{document.getElementById(\'extra_data_text\').style.display=\'none\';}'));
  835. $form->addElement('html', '<div id="extra_data_text" style="display:none;">');
  836. $form->add_textfield('keyword_extra_data_text', '', false, array('style'=>'margin-left:17px', 'id'=>'input_extra_text'));
  837. $form->addElement('html', '</div>');
  838. } else {
  839. $form->addElement('html', '<div id="extra_data_text" style="display:none;">');
  840. }*/
  841. $form->addElement('html', '</td></tr>');
  842. $form->addElement('html', '<tr><td>');
  843. $form->addElement('style_submit_button', 'submit',get_lang('SearchUsers'),'class="search"');
  844. $form->addElement('html', '</td></tr>');
  845. $form->addElement('html', '</table>');
  846. $defaults['keyword_active'] = 1;
  847. $defaults['keyword_inactive'] = 1;
  848. $form->setDefaults($defaults);
  849. $form->addElement('html','</div>');
  850. $form->display();
  851. $table = new SortableTable('users', 'get_number_of_users', 'get_user_data', (api_is_western_name_order() xor api_sort_by_first_name()) ? 3 : 2);
  852. $table->set_additional_parameters($parameters);
  853. $table->set_header(0, '', false, 'width="18px"');
  854. $table->set_header(1, get_lang('Photo'), false);
  855. $table->set_header(2, get_lang('OfficialCode'));
  856. if (api_is_western_name_order()) {
  857. $table->set_header(3, get_lang('FirstName'));
  858. $table->set_header(4, get_lang('LastName'));
  859. } else {
  860. $table->set_header(3, get_lang('LastName'));
  861. $table->set_header(4, get_lang('FirstName'));
  862. }
  863. $table->set_header(5, get_lang('LoginName'));
  864. $table->set_header(6, get_lang('Email'));
  865. $table->set_header(7, get_lang('Profile'));
  866. $table->set_header(8, get_lang('Active'),true, 'width="15px"');
  867. $table->set_header(9, get_lang('Action'), false,'width="220px"');
  868. $table->set_column_filter(3, 'user_filter');
  869. $table->set_column_filter(4, 'user_filter');
  870. $table->set_column_filter(6, 'email_filter');
  871. $table->set_column_filter(7, 'status_filter');
  872. $table->set_column_filter(8, 'active_filter');
  873. $table->set_column_filter(9, 'modify_filter');
  874. if (api_is_platform_admin())
  875. $table->set_form_actions(array ('delete' => get_lang('DeleteFromPlatform')));
  876. $table->display();
  877. Display :: display_footer();