PageRenderTime 52ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/appLms/modules/public_coursepanel/public_coursepanel.php

https://github.com/wanadli75/cocalms
PHP | 1110 lines | 742 code | 210 blank | 158 comment | 138 complexity | ca48cf30a1df2ed3732ae9e9ba1f25ef MD5 | raw file
Possible License(s): GPL-2.0, CC-BY-3.0
  1. <?php defined("IN_FORMA") or die('Direct access is forbidden.');
  2. /* ======================================================================== \
  3. | FORMA - The E-Learning Suite |
  4. | |
  5. | Copyright (c) 2013 (Forma) |
  6. | http://www.formalms.org |
  7. | License http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt |
  8. | |
  9. | from docebo 4.0.5 CE 2008-2012 (c) docebo |
  10. | License http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt |
  11. \ ======================================================================== */
  12. /**
  13. * COURSE PANEL
  14. *
  15. * This module is a facilitator for the users re-training maded by the public administrators.
  16. * The public administrator will be informed of the users that are approching the expiration date for theirs
  17. * competences and allow the administrator to re-enroll them to courses that refresh those competences in order to keep
  18. * the final users up to date.
  19. */
  20. function coursePanel() {
  21. //check permissions
  22. checkPerm('view');
  23. $can_mod = checkPerm('mod', true);
  24. //required libraries
  25. require_once(_base_.'/lib/lib.form.php');
  26. require_once(_base_.'/lib/lib.table.php');
  27. require_once(_adm_.'/lib/lib.publicadminmanager.php');
  28. require_once(_lms_.'/lib/lib.course.php');
  29. require_once(_lms_.'/lib/lib.date.php');
  30. require_once(_lms_.'/lib/lib.competences.php');
  31. //back page link
  32. $lang =& DoceboLanguage::CreateInstance('public_coursepanel', 'lms');
  33. $back_ui = getBackUi('index.php', $lang->def('_BACK'));
  34. $db = DbConn::getInstance();
  35. $man_competences = new Competences_Manager();
  36. //check the admin level of the current user, if it's not an admin or the idst is invalid, return an error
  37. $id_pa = getLogUserId();
  38. if (!$id_pa) {
  39. //error: the user is invalid
  40. cout($back_ui.$lang->def('_INVALID_ADMIN').$back_ui, 'content');
  41. return;
  42. }
  43. /*
  44. //months considered
  45. $this_month = (int)date("m");
  46. $month_1 = ((int)$this_month-1+1) % 12; $month_1++;
  47. $month_2 = ((int)$this_month-1+2) % 12; $month_2++;
  48. $months = array(
  49. $lang->def('MONTH_'.((int)$this_month<10 ? '0' : '').(int)$this_month),
  50. $lang->def('MONTH_'.((int)$month_1<10 ? '0' : '').(int)$month_1),
  51. $lang->def('MONTH_'.((int)$month_2<10 ? '0' : '').(int)$month_2)
  52. );
  53. */
  54. $acl_man = Docebo::user()->getAclManager();
  55. $admin_manager = new PublicAdminManager();
  56. $array_users = array();
  57. $idst_associated = $admin_manager->getAdminTree($id_pa);
  58. $array_users =& $acl_man->getAllUsersFromIdst($idst_associated);
  59. $array_users = array_unique($array_users);
  60. if (empty($array_users)) {
  61. //error: no users to deal with
  62. cout($back_ui.$lang->def('_NO_USERS').$back_ui, 'content');
  63. return;
  64. }
  65. //already selected competence and course, if exist
  66. $sel_competence = Get::req('sel_competence', DOTY_INT, false);
  67. $sel_course = Get::req('sel_course', DOTY_INT, false);
  68. //$lang_code = Get::req('language', DOTY_ALPHANUM, getLanguage());
  69. $comps_1 = array();
  70. $comps_2 = array();
  71. //retrieve competences list for dropdown menu -- two steps filter
  72. //retrieve competences by users
  73. $query_competences_1 = "SELECT c.id_competence, cu.id_user FROM ".
  74. " %lms_competence as c JOIN ".
  75. " %lms_competence_user as cu ON ".
  76. " (c.id_competence=cu.id_competence AND cu.id_user IN (".implode(",", $array_users)."))";
  77. $res_competences_1 = $db->query($query_competences_1);
  78. while (list($id_comp, $id_user) = $db->fetch_row($res_competences_1)) {
  79. $comps_1[$id_comp] = $id_user;
  80. }
  81. if (empty($comps_1)) {
  82. //error, no competences
  83. cout($back_ui.$lang->def('_NO_COMPETENCES').$back_ui, 'content');
  84. return;
  85. }
  86. //get number of days in which check if a course or a edition is starting
  87. $course_check_time = Docebo::user()->preference->getAdminPreference('admin_rules.course_check_time'); //days from today
  88. //retrieve competences by courses
  89. $courses_dropdown = array();
  90. $query_competences_2 = "(SELECT c.id_competence, t.idCourse, t.name, t.course_type, cc.retraining FROM ".
  91. " %lms_competence as c JOIN ".
  92. " %lms_competence_course as cc JOIN ".
  93. " %lms_course as t ON ".
  94. "(c.id_competence=cc.id_competence AND cc.id_course=t.idCourse) ".
  95. "WHERE t.course_type IN ('classroom', 'elearning') AND c.id_competence IN (".implode(",", array_keys($comps_1)).")".
  96. ")";/*." UNION (SELECT c.id_competence, t.idCourse, t.name, t.course_type, cc.retraining FROM ".
  97. $GLOBALS['prefix_lms']."_competence as c JOIN ".
  98. $GLOBALS['prefix_lms']."_competence_course as cc JOIN ".
  99. $GLOBALS['prefix_lms']."_course as t ON ".
  100. "(c.id_competence=cc.id_competence AND cc.id_course=t.idCourse) ".
  101. "WHERE t.course_type IN ('classroom', 'elearning') AND c.id_competence IN (".implode(",", array_keys($comps_1)).")".
  102. ")";*/
  103. $res_competences_2 = $db->query($query_competences_2);
  104. while (list($id_comp, $id_course, $course_name, $c_type, $retraining) = $db->fetch_row($res_competences_2)) {
  105. $comps_2[$id_comp] = $id_course;
  106. if (!isset($courses_dropdown[$id_comp])) $courses_dropdown[$id_comp] = array();
  107. $courses_dropdown[$id_comp][$id_course] = $course_name.' ('.$c_type.')'.($retraining>0 ? ' ['.$lang->def('_RETRAINING').']' : '');
  108. }
  109. if (empty($comps_2)) {
  110. //error, no competences
  111. cout($back_ui.$lang->def('_NO_COMPETENCES').$back_ui, 'content');
  112. return;
  113. }
  114. $comps = array_keys($comps_2);
  115. unset($comps_1);
  116. unset($comps_2);
  117. $comps_names = $man_competences->getCompetencesName($comps);
  118. //----------------------------------------------------------------------------
  119. //retrieve courses for competences
  120. //$courses_dropdown = array();
  121. //check if selection for competence and course is valid
  122. if (!$sel_competence || !array_key_exists($sel_competence, $comps)) {
  123. $arr = array_keys($courses_dropdown);
  124. $sel_competence = $arr[0];//$comps[0];
  125. }
  126. if (!$sel_course || !isset($courses_dropdown[$sel_competence][$sel_course])) {
  127. foreach ($courses_dropdown as $key=>$val)
  128. if (count($val) > 0) {
  129. $sel_competence = $key;
  130. $arr = array_keys($val);
  131. $sel_course = $arr[0];
  132. break;
  133. }
  134. }
  135. //check the course type (base or retraining)
  136. $is_retraining = $man_competences->isRetrainingCourse($sel_course, $sel_competence);
  137. //make script for courses dropdown auto-updating
  138. require_once(_base_.'/lib/lib.json.php');
  139. $json = new Services_JSON();
  140. $var = array();
  141. foreach ($courses_dropdown as $id_comp=>$courses_list) {
  142. $content = "{id_competence: ".(int)$id_comp.", courses: [";
  143. $clist = array();
  144. foreach ($courses_list as $id_course=>$name) {
  145. $clist[] = '{id_course: '.(int)$id_course.', name: '.$json->encode($name).'}';
  146. }
  147. $content .= implode(',', $clist)."]}";
  148. $var[] = $content;
  149. }
  150. //addYahooJs(array('dom'=>'dom-min.js', 'event'=>'event-min.js', 'selector'=>'selector-beta-min.js'));
  151. YuiLib::load('selector');
  152. cout('<script type="text/javascript">
  153. var sel_options = ['.implode(',', $var).'];
  154. YAHOO.util.Event.onDOMReady(function() {
  155. var s1 = YAHOO.util.Dom.get("competence_selector");
  156. var s2 = YAHOO.util.Dom.get("course_selector");
  157. YAHOO.util.Event.addListener(s1, "change", function(e) {
  158. var opt, id_comp = this.value;
  159. for (var i=0; i<sel_options.length; i++) {
  160. if (sel_options[i].id_competence == id_comp) {
  161. s2.innerHTML = "";
  162. for (var j=0; j<sel_options[i].courses.length; j++) {
  163. opt = new Option(sel_options[i].courses[j].name, sel_options[i].courses[j].id_course);
  164. s2.add(opt, null);
  165. }
  166. break;
  167. }
  168. }
  169. });
  170. });
  171. </script>', 'page_head');
  172. //----------------------------------------------------------------------------
  173. $table_head_style = array('', 'image', 'align_center');
  174. $table_head_content = array($lang->def('_USERNAME'), $lang->def('_MANDATORY'), $lang->def('_DATE_EXPIRE'));
  175. $man_course = new Man_Course();
  176. $date_man = new DateManager();
  177. $course_info = $man_course->getCourseInfo($sel_course);
  178. //echo '<pre>'.print_r($course_info, true).'</pre>';
  179. if ($course_info['course_type'] == 'elearning') {
  180. $editions[] = (int)$sel_course;
  181. $subscribed[$sel_course] = /*$man_course->*/getSubscribed($sel_course);
  182. $table_head_content[] = $course_info['name'];
  183. $table_head_style[] = 'align_center';
  184. } elseif ($course_info['course_type'] == 'classroom') {
  185. //retrieve editions for table columns and subscribed users
  186. $subscribed = array();
  187. $editions = array();
  188. if ($course_check_time > 0) {
  189. $id_list = array();
  190. $query_begindates = "SELECT dy.id_date, MIN(dy.date_begin) as date_begin "
  191. ." FROM %lms_course_date as dt "
  192. ." JOIN %lms_course_date_day as dy ON (dy.id_date = dt.id_date) "
  193. ." WHERE dt.id_course='".(int)$sel_course."' GROUP BY dy.id_date ORDER BY dy.date_begin";
  194. $res = $db->query($query_begindates);
  195. while (list($id_date, $date_begin) = $db->fetch_row($res)) {
  196. if ($date_begin >= date("Y-m-d") && $date_begin <= date("Y-m-d", strtotime("+".$course_check_time." days"))) $id_list[] = $id_date;
  197. }
  198. /*
  199. $query_editions = "SELECT dt.id_date, dt.id_course, dt.code, dt.name, MIN(dy.date_begin) as min "
  200. ." FROM %lms_course_date as dt "
  201. ." JOIN %lms_course_date_day as dy ON (dy.id_date = dt.id_date) "
  202. ." WHERE dt.id_course='".(int)$sel_course."' AND dy.date_begin BETWEEN NOW() AND '"
  203. .date("Y-m-d", strtotime("+".$course_check_time." days"))."' GROUP BY dt.id_date ORDER BY dy.date_begin";
  204. */
  205. $query_editions = "SELECT id_date, id_course, code, name FROM %lms_course_date WHERE "
  206. .(count($id_list) > 0 ? "id_date IN (".implode(",", $id_list).") " : "0");
  207. } else {
  208. $query_editions = "SELECT id_date, id_course, code, name FROM %lms_course_date WHERE id_course='".(int)$sel_course."' ";
  209. }
  210. $res_editions = $db->query($query_editions);
  211. if (sql_num_rows($res_editions) > 0) {
  212. while (list($id_edition, $id_course, $code, $name) = $db->fetch_row($res_editions)) {
  213. $table_head_style[] = 'align_center';
  214. $date_info = $date_man->getDateInfo($id_edition);
  215. $table_head_content[] = $name.'<br />'
  216. .$lang->def('_DATE_BEGIN').': '.Format::date($date_info['date_begin'], 'date').'<br />'
  217. .$lang->def('_DATE_END').': '.Format::date($date_info['date_end'], 'date').'<br />'
  218. .$lang->def('_AVAIL_PLACES').': <span id="available_places_count_'.$id_edition.'">'.(int)($date_info['max_par'] - $date_info['user_subscribed']).'</span> ('.$date_info['max_par'].')';
  219. $editions[] = $id_edition;
  220. $subscribed[$id_edition] = $date_man->getDateSubscribed($id_edition);
  221. }
  222. } else {
  223. }
  224. }
  225. //retrieve expiration time for every user
  226. $expiries = array();
  227. $query_check = "SELECT id_user, date_expire "
  228. ." FROM %lms_competence_user "
  229. ." WHERE id_user IN (".implode(",", $array_users).") AND id_competence='".(int)$sel_competence."'";
  230. $res_check = $db->query($query_check);
  231. while (list($id_user, $date_expire) = $db->fetch_row($res_check)) {
  232. $expiries[$id_user] = $date_expire;
  233. }
  234. //filter array of user ids by competence
  235. $filtered_users = array();
  236. //------------------------------------------------------------------------------
  237. $required_filter = Get::req('required_filter', DOTY_INT, 0);
  238. $expire_duration = $man_competences->getCompetenceExpirationCheckTime($id_comp);
  239. if ($is_retraining || $required_filter > 0) {
  240. $query_filter_time = "";
  241. if ($expire_duration > 0) { //if a time for checking expiration has been set, then filter on a time period
  242. $date_begin = date("Y-m-d", strtotime("-".$expire_duration." days"));
  243. $date_end = date("Y-m-d", strtotime("+".$expire_duration." days"));
  244. $query_filter_time = " AND date_expire>'".$date_begin."' AND date_expire<'".$date_end."'";
  245. }
  246. $query_filter = "SELECT id_user FROM %lms_competence_user WHERE id_user IN (".implode(",", $array_users).") AND id_competence='".(int)$sel_competence."' "
  247. .$query_filter_time;
  248. $res_filter = $db->query($query_filter);
  249. while (list($idst) = $db->fetch_row($res_filter)) {
  250. $filtered_users[] = $idst;
  251. }
  252. }
  253. if (!$is_retraining || $required_filter > 0) {
  254. //get user with required competence which is not yet obtained
  255. $required_users = array();
  256. $req_data = $man_competences->GetCompetence($sel_competence);
  257. $already = array();
  258. $query = "SELECT id_user, score_init, score_got FROM %lms_competence_user WHERE id_competence='".(int)$sel_competence."'";
  259. $res = $db->query($query);
  260. while (list($id_user, $score_init, $score_got) = $db->fetch_row($res)) {
  261. if ($req_data['type'] == 'score') {
  262. //if the competence assignment exists in DB, but the total score is 0, then it's considered as non-assigned
  263. if (((int)$score_init + (int)$score_got) > 0) $already[] = $id_user;
  264. } else {
  265. $already[] = $id_user;
  266. }
  267. }
  268. $already = array_unique($already);
  269. $req_users = array_diff($array_users, $already);
  270. //get required competences not got from users
  271. $query = "";
  272. if ($req_data['type'] == 'score') {
  273. $query = "SELECT u.idst FROM %lms_competence_required as cr "
  274. ." JOIN %adm_user as u ON (cr.idst = u.idst)"
  275. ." WHERE cr.idst IN (".implode(",", $req_users).") AND cr.id_competence=".(int)$sel_competence."";
  276. } else {
  277. $query = "SELECT u.idst FROM %lms_competence_required as cr "
  278. ." JOIN %adm_user as u ON (cr.idst = u.idst) "
  279. ." WHERE cr.idst IN (".implode(",", $req_users).") AND cr.id_competence=".(int)$sel_competence."";
  280. }
  281. $res = $db->query($query);
  282. if (sql_num_rows($res) > 0) {
  283. while (list($idst) = $db->fetch_row($res)) {
  284. $required_users[] = $idst;
  285. }
  286. }
  287. //get users expired from too long time
  288. if ($expire_duration > 0) {
  289. $query = "SELECT id_user FROM %lms_competence_user "
  290. ." WHERE date_expire<'".date("Y-m-d", strtotime("-".$expire_duration." days"))."' AND date_expire<>'0000-00-00 00:00:00' "
  291. ." AND id_competence=".(int)$sel_competence;
  292. $res = $db->query($query);
  293. while (list($idst) = $db->fetch_row($res)) {
  294. $required_users[] = $idst;
  295. }
  296. }
  297. //merge results
  298. if (count($required_users) > 0)
  299. if (count($filtered_users) > 0)
  300. $filtered_users = array_merge($filtered_users, $required_users);
  301. else
  302. $filtered_users = $required_users;
  303. }
  304. //------------------------------------------------------------------------------
  305. $filtered_users = array_unique($filtered_users);
  306. //draw table
  307. $table = new Table(0);
  308. $form = new Form();
  309. $table->addHead($table_head_content, $table_head_style);
  310. $totals = array();
  311. for ($i=0; $i<count($editions); $i++) {
  312. $totals[$i] = 0;
  313. }
  314. //check the expiration time of the current competence
  315. list($expiry_time) = $db->fetch_row($db->query("SELECT expiration FROM %lms_competence WHERE id_competence='".(int)$sel_competence."'"));
  316. if ($expiry_time === false) {
  317. //error, we need a number (it should never enter this branch though)
  318. //error, no competences
  319. cout($back_ui.$lang->def('_NO_EXPIRATION_TIME').$back_ui, 'content');
  320. return;
  321. }
  322. $checkbox_list_script = array();
  323. foreach ($editions as $id_edition) $checkbox_list_script[$id_edition] = array();
  324. $expiring_users_count = 0;
  325. $req_count = 0;
  326. //filtered data to consider in saving operation
  327. $to_consider = array('users'=>array(), 'editions'=>array());
  328. for ($i=0; $i<count($editions); $i++) $to_consider['editions'][] = $editions[$i];
  329. //retrieve users' data for table rows (little fast query)
  330. if (count($filtered_users) > 0) {
  331. $query_users = "SELECT idst, userid, lastname, firstname FROM %adm_user WHERE idst IN (".implode(",", $filtered_users/*$array_users*/).") ORDER BY userid, lastname, firstname";
  332. $res_users = $db->query($query_users);
  333. //retrieve users with required competence
  334. $just_required = array();
  335. $query_req = "SELECT idst FROM %lms_competence_required "
  336. ." WHERE id_competence=".(int)$sel_competence." AND idst IN (".implode(",", $filtered_users).")";
  337. $res_req = $db->query($query_req);
  338. while (list($idst) = $db->fetch_row($res_req)) $just_required[] = $idst;
  339. while (list($idst, $userid, $firstname, $lastname) = $db->fetch_row($res_users)) {
  340. $line = array();
  341. //filtered users to consider in saving operations
  342. $to_consider['users'][] = $idst;
  343. //check if the expiring date of the competence is less than 30 days from now or it's already expired (change bg color then)
  344. $user_expiring = false;
  345. $background = "";
  346. if ($expiry_time>0) {
  347. if (isset($expiries[$idst])) {
  348. //$time1 = fromDateTimeToTimestamp($expiries[$idst]) + $expiry_time * 24 * 3600;
  349. //$time2 = time();
  350. //if (($time2-$time1) < 2592000) $user_expiring = true;
  351. if ($expiries[$idst] < date("Y-m-d H:i:s")) $user_expiring = true;
  352. }
  353. }
  354. if ($user_expiring) {
  355. $background .= 'bg_highlight';
  356. $expiring_users_count++;
  357. }
  358. $line[] = $acl_man->relativeId($userid)."&nbsp;(".$firstname."&nbsp;".$lastname.")"; //swap these
  359. $is_req = in_array($idst, $just_required);
  360. if ($is_req) $req_count++;
  361. $line[] = ($is_req ? '<image src="'.getPathImage('framework').'standard/flag.gif" />' : '');
  362. $line[] = '<div class="'.$background.'">'
  363. .(isset($expiries[$idst]) ? Format::date($expiries[$idst], "date") : '-')
  364. .'</div>';
  365. for ($i=0; $i<count($editions); $i++) {
  366. //check if the actual considered user is subscribed to this class' edition (then flag the checkbox)
  367. $is_subscribed = false;
  368. if (isset($subscribed[$editions[$i]][$idst])) {
  369. $is_subscribed = true;
  370. $totals[$i]++; //update total subscriptions
  371. }
  372. if ($course_info['course_type'] == 'elearning') {
  373. $line[] = '<div class="align_center">'
  374. .$form->getInputCheckbox('subscriptions_'.$idst, 'subscriptions['.$idst.']['.$editions[$i].']', 1, $is_subscribed, false)
  375. .'</div>';
  376. $checkbox_list_script[$editions[$i]][] = '"subscriptions_'.$idst.'"';
  377. } elseif ($course_info['course_type'] == 'classroom') {
  378. $line[] = '<div class="align_center">'
  379. .$form->getInputCheckbox('subscriptions_'.$idst.'_'.$editions[$i], 'subscriptions['.$idst.']['.$editions[$i].']', 1, $is_subscribed, false)
  380. .'</div>';
  381. $checkbox_list_script[$editions[$i]][] = '"subscriptions_'.$idst.'_'.$editions[$i].'"';
  382. }
  383. }
  384. $table->addBody($line);
  385. }
  386. }
  387. //totals line
  388. $line = array();
  389. $line[] = $lang->def('_TOTAL');
  390. $line[] = '<div class="align_center">'.(int)$req_count.'</div>';
  391. $line[] = '<div class="align_center">'.(int)$expiring_users_count.'</div>';
  392. for ($i=0; $i<count($editions); $i++) {
  393. $line[] = '<div class="align_center">'.(int)$totals[$i].'</div>';
  394. }
  395. $table->addFoot($line);
  396. //echo '<pre class="align_left">'.print_r($checkbox_list_script, true).'</pre>';
  397. //script to check available places in real-time
  398. $avail_script = '<script type="text/javascript">
  399. function setupAvailablePlaces() {';
  400. foreach ($editions as $id_edition) {
  401. $date_info = $date_man->getDateInfo($id_edition);
  402. $avail_script .= '
  403. YAHOO.util.Event.addListener(['.implode(',', $checkbox_list_script[$id_edition]).'], "click", function(e, o) {
  404. max_avail_places_'.$id_edition.' = '.(int)($date_info['max_par'] - $date_info['user_subscribed']).';
  405. var i, edition_boxes = YAHOO.util.Dom.get(['.implode(',', $checkbox_list_script[$id_edition]).']);
  406. var edition_count = 0, edition_max = '.(int)$date_info['max_par'].';
  407. for (i=0; i<edition_boxes.length; i++) {
  408. if (edition_boxes[i].checked) edition_count++;
  409. }
  410. YAHOO.util.Dom.get("available_places_count_'.$id_edition.'").innerHTML = ""+(edition_max - edition_count);
  411. if (edition_count >= edition_max) {
  412. for (i=0; i<edition_boxes.length; i++) {
  413. if (!edition_boxes[i].checked) edition_boxes[i].disabled = true;
  414. }
  415. } else {
  416. for (i=0; i<edition_boxes.length; i++) {
  417. if (edition_boxes[i].disabled) edition_boxes[i].disabled = false;
  418. }
  419. }
  420. });';
  421. }
  422. $avail_script .= '}
  423. setupAvailablePlaces();
  424. </script>';
  425. cout($avail_script, 'page_head');
  426. //any error message from previous operations?
  427. $message = "";
  428. $err = Get::req('err', DOTY_MIXED, false);
  429. switch ($err) {
  430. case 'invalid': {
  431. $message .= getErrorUi($lang->def('_ERROR_WHILE_SUBSCRIBING').'.');
  432. } break;
  433. case 'ok': {
  434. $content = $lang->def('_SUBSCRIBE_SUCCESSFULL');
  435. $count = Get::req('count', DOTY_MIXED, false);
  436. if ($count !== false && is_numeric($count)) {
  437. $content .= "&nbsp;(".$lang->def('_NUM_SUBSCRIBED').":&nbsp;".$count.")";
  438. }
  439. $message .= getResultUi($content);
  440. } break;
  441. }
  442. //print page
  443. cout(getTitleArea($lang->def('_COURSEPANEL'), 'coursepanel')
  444. .'<div class="std_block">'.$message
  445. .$back_ui, 'content');
  446. cout('<link rel="stylesheet" type="text/css" href="'./*$GLOBALS['where_framework_relative']*/Get::rel_path('base').'/addons/yui/grids/grids-min.css">', 'page_head');
  447. $comps_list = $man_competences->GetCompetencesList();
  448. //write period of checking for expiration, from beginning date to ending date
  449. $date_1 = ($expire_duration > 0 ? date("Y-m-d H:i:s", strtotime("-".$expire_duration." days")) : "");
  450. $date_2 = ($expire_duration > 0 ? date("Y-m-d H:i:s", strtotime("+".$expire_duration." days")) : "");
  451. if ($date_1 != "" && $date_2 != "")
  452. $date_period = Format::date($date_1, "date").' - '.Format::date($date_2, "date");
  453. else
  454. $date_period = '('.$lang->def('_ALL').')';
  455. $selector = "";
  456. //$selector .= $form->openElementSpace();
  457. $selector .= '<div class="yui-g"><div id="select_1" class="yui-u first align_left">';
  458. $selector .= $form->openForm('action_panel', "index.php?modname=public_coursepanel&op=coursepanel");
  459. $selector .= $form->openElementSpace();
  460. $selector .= '<p class="align_left">'.$lang->def('_EXPIRING_USERS_FOR_PERIOD').':&nbsp;<b>'./*implode(", ", $months)*/$date_period.'</b>;</p>';
  461. //$selector .= $lang->def('_FOR_COMPETENCE').':&nbsp;';
  462. $selector .= $form->getDropDown($lang->def('_FOR_COMPETENCE').':&nbsp;', 'competence_selector', 'sel_competence', $comps_names, $sel_competence, '');
  463. $selector .= $form->getDropDown($lang->def('_FOR_COURSE').':&nbsp;', 'course_selector', 'sel_course', $courses_dropdown[$sel_competence], $sel_course, '');
  464. $selector .= $form->openButtonSpace();
  465. $selector .= $form->getButton('update', 'update', $lang->def('_UPDATE'));
  466. $selector .= $form->closeButtonSpace();
  467. $selector .= $form->closeElementSpace();
  468. $selector .= $form->closeForm();
  469. $selector .= '</div><div id="select_2" class="yui-u align_left">';
  470. //if (count($comps_list)>0) { ...
  471. $selector .= $form->openElementSpace();
  472. $selector .= $form->openForm('action_panel', "index.php?modname=public_coursepanel&op=expired");
  473. $selector .= $form->getHidden('expire_sel_competence', 'sel_competence', $sel_competence);
  474. $selector .= $form->getHidden('expire_sel_course', 'sel_course', $sel_course);
  475. $selector .= $form->getDropdown($lang->def('_CHOOSE_COMPETENCE_TO_SEE_EXPIRED'), 'expired_selector', 'expired_selector', $comps_list/*, $sel_expired*/);
  476. $selector .= $form->openButtonSpace();
  477. $selector .= $form->getButton('update_expired', 'update_expired', $lang->def('_UPDATE'));
  478. $selector .= $form->closeButtonSpace();
  479. $selector .= $form->closeForm();
  480. $selector .= $form->getBreakRow();
  481. $selector .= $form->openForm('action_panel', "index.php?modname=public_coursepanel&op=required");
  482. $selector .= $form->getHidden('expire_sel_competence_req', 'sel_competence_req', $sel_competence);
  483. $selector .= $form->getHidden('expire_sel_course_req', 'sel_course_req', $sel_course);
  484. $selector .= $form->getDropDown($lang->def('_CHOOSE_REQUIRED_COMPETENCES'), 'required_selector', 'required_selector', $comps_list/*, $sel_expired*/);
  485. $selector .= $form->openButtonSpace();
  486. $selector .= $form->getButton('update_required', 'update_required', $lang->def('_UPDATE'));
  487. $selector .= $form->closeButtonSpace();
  488. $selector .= $form->closeForm();
  489. $selector .= $form->closeElementSpace();
  490. $selector .= '</div></div><div class="no_float"></div>';
  491. //$selector .= $form->closeElementSpace();
  492. //legend which explains what highlighted users mean
  493. $legend = '<div class="align_left"><div style="display:inline-block;width:12px;height:12px;" class="bg_highlight"></div> = '
  494. .$lang->def('_EXPIRED_COMPETENCE').'</div>';
  495. cout('<div class="align_center">'.$selector.'</div>', 'content');
  496. cout($form->openForm('comp_panel', "index.php?modname=public_coursepanel&op=savepanel"), 'content');
  497. cout($form->getHidden('sel_competence', 'sel_competence', $sel_competence), 'content');
  498. cout($form->getHidden('sel_course', 'sel_course', $sel_course), 'content');
  499. cout($form->openElementSpace(), 'content');
  500. cout('<div class="align_left">', 'content');
  501. if ($is_retraining)
  502. cout($form->getCheckbox($lang->def('_SHOW_REQUIRED'), 'required_filter', 'required_filter', 1, $required_filter), 'content');
  503. else
  504. cout($form->getCheckbox($lang->def('_SHOW_EXPIRED'), 'required_filter', 'required_filter', 1, $required_filter), 'content');
  505. cout('</div>', 'content');
  506. cout($form->closeElementSpace(), 'content');
  507. cout('<div class="align_left">', 'content');
  508. cout('<p>'.($is_retraining ? $lang->def('_IS_RETRAINING_COURSE') : $lang->def('_IS_TRAINING_COURSE')).'</p>', 'content');
  509. if ($course_info['course_type'] == 'classroom' && $course_check_time > 0){
  510. $check_date_1 = Format::date(date("Y-m-d"), "date");
  511. $check_date_2 = Format::date(date("Y-m-d H:i:s", strtotime("+".$course_check_time." days")), "date");
  512. cout('<p>'.$lang->def('_COURSE_CHECKING_PERIOD').': '.$check_date_1.' - '.$check_date_2.'</p>', 'content');
  513. }
  514. cout('</div>', 'content');
  515. if (empty($editions)) {
  516. //no editions to display (it should have been pre-selected only courses with available editions)
  517. cout('<p>'.$lang->def('_NO_CONTENT').'</p>', 'content');
  518. } else {
  519. cout($table->getTable(), 'content');
  520. }
  521. cout($legend, 'content');
  522. cout($form->getHidden('to_consider', 'to_consider', base64_encode($json->encode($to_consider))), 'content');
  523. cout($form->openButtonSpace()
  524. .$form->getButton('save', 'save', $lang->def('_SAVE'))
  525. .$form->getButton('undo', 'undo', $lang->def('_UNDO'))
  526. .$form->closeButtonSpace(), 'content');
  527. cout($form->closeForm().$back_ui.'</div>', 'content');
  528. cout('<script type="text/javascript">
  529. YAHOO.util.Event.addListener("required_filter", "click", function(e) {
  530. var show_required = this.checked, comp_form = YAHOO.util.Dom.get("comp_panel");
  531. comp_form.action = comp_form.action.replace("&op=savepanel", "&op=coursepanel");
  532. comp_form.submit();
  533. });
  534. </script>', 'page_head');
  535. }
  536. function _removeCourseSubscription($id_course, $id_user, $lv_group, $edition_id=0) {
  537. /*
  538. require_once($GLOBALS["where_framework"]."/lib/resources/lib.timetable.php");
  539. $tt=new TimeTable();
  540. // ----------------------------------------
  541. $resource="user";
  542. $resource_id=$id_user;
  543. if ($edition_id > 0) {
  544. $consumer="course_edition";
  545. $consumer_id=$edition_id;
  546. }
  547. else {
  548. $consumer="course";
  549. $consumer_id=$id_course;
  550. }
  551. // ----------------------------------------
  552. $tt->deleteEvent(FALSE, $resource, $resource_id, $consumer, $consumer_id, $start_date, $end_date);
  553. */
  554. $db = DbConn::getInstance();
  555. $acl_man = Docebo::user()->getAclManager();
  556. $acl_man->removeFromGroup($lv_group, $id_user);
  557. if ($edition_id > 0) {
  558. $group ='/lms/course_edition/'.$edition_id.'/subscribed';
  559. $group_idst =$acl_man->getGroupST($group);
  560. $acl_man->removeFromGroup($group_idst, $id_user);
  561. }
  562. return $db->query("DELETE FROM %adm_courseuser
  563. WHERE idUser = '".$id_user."' AND idCourse = '".(int)$id_course."'
  564. AND edition_id='".(int)$edition_id."'");
  565. }
  566. function savePanel() {
  567. checkPerm('mod');
  568. require_once(_base_.'/lib/lib.form.php');
  569. require_once(_adm_.'/lib/lib.publicadminmanager.php');
  570. require_once(_lms_.'/lib/lib.course.php');
  571. require_once(_lms_.'/lib/lib.date.php');
  572. require_once(_lms_.'/lib/lib.competences.php');
  573. $save = Get::req('save', DOTY_MIXED, false);
  574. $undo = Get::req('undo', DOTY_MIXED, false);
  575. $update = Get::req('update', DOTY_MIXED, false);
  576. $db = DbConn::getInstance();
  577. $lang =& DoceboLanguage::CreateInstance('public_coursepanel', 'lms');
  578. $man_competences = new Competences_Manager();
  579. //back page link
  580. $back_ui = getBackUi('index.php?modname=public_coursepanel&op=coursepanel', $lang->def('_BACK'));
  581. cout(getTitleArea($lang->def('_COURSEPANEL'), 'coursepanel').'<div class="std_block">'.$back_ui, 'content');
  582. $sel_competence = Get::req('sel_competence', DOTY_INT, false);
  583. $sel_course = Get::req('sel_course', DOTY_INT, false);
  584. $required_filter = Get::req('required_filter', DOTY_INT, 0);
  585. $is_retraining = $man_competences->isRetrainingCourse($sel_course, $sel_competence);
  586. $back_url = "index.php?modname=public_coursepanel&op=coursepanel&sel_competence=".(int)$sel_competence."&sel_course=".(int)$sel_course;
  587. if ($required_filter > 0) $back_url .= '&required_filter=1';
  588. $to_consider = Get::req('to_consider', DOTY_MIXED, false);
  589. if ($to_consider) {
  590. require_once(_base_.'/lib/lib.json.php');
  591. $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
  592. $to_consider = $json->decode(base64_decode($to_consider));
  593. } else {
  594. $to_consider = array('users'=>array(), 'editions'=>array());
  595. }
  596. if ($undo) {
  597. Util::jump_to("index.php");
  598. } elseif ($save) {
  599. //change users' subscription to course editions
  600. $data = Get::req('subscriptions', DOTY_MIXED, array());
  601. $man_course = new Man_Course();
  602. $course_info = $man_course->getCourseInfo($sel_course);
  603. if (!$sel_competence || !$sel_course) {
  604. //error ...
  605. Util::jump_to($back_url."&err=invalid");
  606. }
  607. //check the admin level of the current user, if it's not an admin or the idst is invalid, return an error
  608. $id_pa = getLogUserId();
  609. if (!$id_pa) {
  610. Util::jump_to($back_url."&err=invalid");
  611. }
  612. $acl_man = new DoceboACLManager();
  613. $admin_manager = new PublicAdminManager();
  614. $array_users = array();
  615. $idst_associated = $admin_manager->getAdminTree($id_pa);
  616. $array_users =& $acl_man->getAllUsersFromIdst($idst_associated);
  617. $array_users = array_unique($array_users);
  618. if (empty($array_users)) {
  619. Util::jump_to($back_url."&err=invalid");
  620. }
  621. //filter array of user ids by competence
  622. $filtered_users = array();
  623. $query_filter = "SELECT id_user FROM %lms_competence_user WHERE id_user IN (".implode(",", $array_users).") AND id_competence='".(int)$sel_competence."'";
  624. $res_filter = $db->query($query_filter);
  625. while (list($idst) = $db->fetch_row($res_filter)) {
  626. $filtered_users[] = $idst;
  627. }
  628. $subs_limit = array();
  629. $subs_count = array();
  630. if ($course_info['course_type'] == 'elearning') {
  631. $editions[] = $sel_course;
  632. $subscribed[$sel_course] = /*$man_course->*/getSubscribed((int)$sel_course);
  633. $course_info = $man_course->getCourseInfo($sel_course);
  634. $subs_count[$sel_course] = count($data);
  635. } elseif ($course_info['course_type'] == 'classroom') {
  636. //get all combinations id_user - id_date
  637. $date_man = new DateManager();
  638. $editions = array();
  639. $query_editions = "SELECT id_date, id_course, code, name FROM %lms_course_date WHERE id_course='".(int)$sel_course."'";
  640. $res_editions = $db->query($query_editions);
  641. while (list($id_edition, $id_course, $code, $name) = $db->fetch_row($res_editions)) {
  642. $editions[] = $id_edition;
  643. $subscribed[$id_edition] = $date_man->getDateSubscribed($id_edition);
  644. $date_info = $date_man->getDateInfo($id_edition);
  645. $subs_limit[$id_edition] = array('max' => $date_info['max_par'], 'subs' => $date_info['user_subscribed']);
  646. $subs_count[$id_edition] = 0;
  647. }
  648. }
  649. //------------------------------------------------------------------------------
  650. //count the users to be subscribed/unsubscribed and check subscription limits, if any
  651. //subtract users to de-subscribe from courses
  652. foreach ($subscribed as $id_edition => $users_list) {
  653. foreach ($users_list as $id_user) {
  654. if ($course_info['course_type'] == 'elearning') {
  655. if (!isset($data[$id_user])) $subs_count[$id_edition]--;
  656. } elseif ($course_info['course_type'] == 'classroom') {
  657. //check if the current selection match the current subscriptions
  658. if (!isset($data[$id_user][$id_edition])) $subs_count[$id_edition]--;
  659. }
  660. }
  661. }
  662. foreach ($data as $user=>$edition_list) { //id user
  663. foreach ($edition_list as $edition=>$val) { //id date edition
  664. if (isset($subscribed[$edition][$user])) {
  665. //already subscribed, do nothing
  666. } else {
  667. $subs_count[$edition]++;
  668. }
  669. }
  670. }
  671. //check if we have enough room to subscribe users
  672. //{at the moment, rely on js ...}
  673. //------------------------------------------------------------------------------
  674. //unsubscribe deselected users
  675. foreach ($subscribed as $id_edition => $users_list) {
  676. foreach ($users_list as $id_user) {
  677. if ($course_info['course_type'] == 'elearning') {
  678. if (!isset($data[$id_user])) {
  679. if (in_array($id_user, $to_consider['users']) && (in_array($id_edition, $to_consider['editions']))) {
  680. $group_levels = DoceboCourse::getCourseLevel($sel_course);
  681. $user_levels = getSubscribedLevel($sel_course, false, false, 0);
  682. $_res = _removeCourseSubscription($sel_course, $id_user, $group_levels[$user_levels[$id_user]], 0);
  683. }
  684. }
  685. } elseif ($course_info['course_type'] == 'classroom') {
  686. //check if the current selection match the current subscriptions
  687. if (!isset($data[$id_user][$id_edition])) {
  688. if (in_array($id_user, $to_consider['users']) && (in_array($id_edition, $to_consider['editions'])))
  689. $date_man->removeUserFromDate($id_user, $id_edition, $sel_course);
  690. }
  691. }
  692. }
  693. }
  694. //------------------------------------------------------------------------------
  695. //check every single user for inscription
  696. $count = 0;
  697. $lv_sel = 3; //student level
  698. $waiting = 0; //don't subscribe as "waiting for approvation"
  699. //retrive id of group of the course for the varioud level
  700. $level_idst = DoceboCourse::getCourseLevel((int)$sel_course);
  701. //if the group doesn't exists create it
  702. if(count($level_idst) == 0 || $level_idst[1] == '') $level_idst =& DoceboCourse::createCourseLevel((int)$sel_course);
  703. foreach ($data as $user=>$edition_list) { //id user
  704. foreach ($edition_list as $edition=>$val) { //id date edition
  705. if (isset($subscribed[$edition][$user])) {
  706. //already subscribed, do nothing
  707. } else {
  708. //this user is to be subscribed, do it
  709. //add to level group of the course
  710. $acl_man->addToGroup($level_idst[$lv_sel], $user);
  711. // Add in table
  712. $re = $db->query("INSERT INTO %lms_courseuser (idUser, idCourse, edition_id, level, waiting, subscribed_by, date_inscr)"
  713. ." VALUES ( '".(int)$user."', '".(int)$sel_course."', '0', '".$lv_sel."', '".$waiting."', '".getLogUserId()."', '".date("Y-m-d H:i:s")."' ) ");
  714. //additional operations for editions
  715. if ($course_info['course_type'] == 'elearning') {
  716. //...
  717. } elseif ($course_info['course_type'] == 'classroom') {
  718. $ret = $date_man->addUserToDate($edition, $user, getLogUserId());
  719. if ($ret) $count++;
  720. }
  721. }
  722. }
  723. }
  724. Util::jump_to($back_url."&err=ok&count=".(int)$count);
  725. } elseif ($update) {
  726. $sel_competence = Get::req('sel_competence', DOTY_INT, false);
  727. $sel_course = Get::req('sel_course', DOTY_INT, false);
  728. Util::jump_to($back_url);//."&sel_competence=".(int)$sel_competence."&sel_course=".(int)$sel_course);
  729. } else {
  730. //...
  731. }
  732. cout($back_ui.'</div>', 'content');
  733. }
  734. function expired() {
  735. require_once(_base_.'/lib/lib.form.php');
  736. require_once(_base_.'/lib/lib.table.php');
  737. require_once(_adm_.'/lib/lib.publicadminmanager.php');
  738. require_once(_lms_.'/lib/lib.course.php');
  739. require_once(_lms_.'/lib/lib.date.php');
  740. require_once(_lms_.'/lib/lib.competences.php');
  741. $db = DbConn::getInstance();
  742. $lang =& DoceboLanguage::CreateInstance('public_coursepanel', 'lms');
  743. $sel_competence = Get::req('sel_competence', DOTY_INT, false);
  744. $sel_course = Get::req('sel_course', DOTY_INT, false);
  745. $back_url = "index.php?modname=public_coursepanel&op=coursepanel&sel_competence=".(int)$sel_competence."&sel_course=".(int)$sel_course;
  746. $back_ui = getBackUi($back_url, $lang->def('_BACK'));
  747. $sel_comp = Get::req('expired_selector', DOTY_INT, 0);
  748. if ($sel_comp) {
  749. $id_pa = getLogUserId();
  750. if (!$id_pa) {
  751. //...
  752. }
  753. $acl_man = new DoceboACLManager();
  754. $admin_manager = new PublicAdminManager();
  755. $array_users = array();
  756. $idst_associated = $admin_manager->getAdminTree($id_pa);
  757. $array_users =& $acl_man->getAllUsersFromIdst($idst_associated);
  758. $array_users = array_unique($array_users);
  759. if (empty($array_users)) {
  760. //error: no users to deal with
  761. cout($back_ui.$lang->def('_NO_USERS').$back_ui, 'content');
  762. return;
  763. }
  764. cout(getTitleArea($lang->def('_EXPIRING_USERS'), 'coursepanel').'<div class="std_block">', 'content');
  765. $table = new Table();
  766. $head_labels = array($lang->def('_USERNAME'), $lang->def('_NAME'), $lang->def('_DATE_ASSIGN'), $lang->def('_DATE_EXPIRE'));
  767. $head_style = array('', '', 'align_center', 'align_center');
  768. $table->addHead($head_labels, $head_style);
  769. $date = date ("Y-m-d H:i:s", strtotime("+1 months"));
  770. $now = date("Y-m-d H:i:s");
  771. //get expiring competences
  772. $query = "SELECT u.idst, u.userid, u.lastname, u.firstname, cu.date_assign, cu.date_expire FROM %lms_competence_user as cu "
  773. ." JOIN %adm_user as u ON (cu.id_user = u.idst)"
  774. ." WHERE cu.id_user IN (".implode(",", $array_users).") AND date_expire<'".$date."' "
  775. ." AND cu.id_competence=".(int)$sel_comp." ORDER BY u.userid";
  776. $res = $db->query($query);
  777. if (sql_num_rows($res) > 0) {
  778. while (list($idst, $userid, $lastname, $firstname, $assign_date, $expiry_date) = $db->fetch_row($res)) {
  779. $line = array();
  780. $line[] = $acl_man->relativeId($userid);
  781. $line[] = $lastname." ".$firstname;
  782. $line[] = Format::date($assign_date, 'datetime');
  783. $line[] = Format::date($expiry_date, 'datetime');
  784. $table->addBody($line);
  785. }
  786. $man_comp = new Competences_Manager();
  787. $comp_data = $man_comp->GetCompetence($sel_comp);
  788. //cout(cout(getTitleArea($lang->def('_EXPIRING_USERS'), 'coursepanel').'<div class="std_block">'));
  789. cout($lang->def('_COMPETENCE').': <b>'.$comp_data['name'].'</b>', 'content');
  790. cout($back_ui.$table->getTable().$back_ui, 'content');
  791. } else {
  792. cout($back_ui.$lang->def('_NO_EXPIRING_USER').$back_ui, 'content');
  793. }
  794. } else {
  795. //error, no competence selected
  796. cout($back_ui.$lang->def('_NO_COMPETENCE_SELECTED').$back_ui, 'content');
  797. return;
  798. }
  799. }
  800. function required() {
  801. require_once(_base_.'/lib/lib.form.php');
  802. require_once(_base_.'/lib/lib.table.php');
  803. require_once(_adm_.'/lib/lib.publicadminmanager.php');
  804. require_once(_lms_.'/lib/lib.course.php');
  805. require_once(_lms_.'/lib/lib.date.php');
  806. require_once(_lms_.'/lib/lib.competences.php');
  807. $db = DbConn::getInstance();
  808. $lang =& DoceboLanguage::CreateInstance('public_coursepanel', 'lms');
  809. $sel_competence = Get::req('sel_competence_req', DOTY_INT, false);
  810. $sel_course = Get::req('sel_course_req', DOTY_INT, false);
  811. $back_url = "index.php?modname=public_coursepanel&op=coursepanel&sel_competence=".(int)$sel_competence."&sel_course=".(int)$sel_course;
  812. $back_ui = getBackUi($back_url, $lang->def('_BACK'));
  813. $sel_comp = Get::req('required_selector', DOTY_INT, 0);
  814. if ($sel_comp) {
  815. $id_pa = getLogUserId();
  816. if (!$id_pa) {
  817. //...
  818. }
  819. $acl_man = new DoceboACLManager();
  820. $admin_manager = new PublicAdminManager();
  821. $array_users = array();
  822. $idst_associated = $admin_manager->getAdminTree($id_pa);
  823. $array_users =& $acl_man->getAllUsersFromIdst($idst_associated);
  824. $array_users = array_unique($array_users);
  825. if (empty($array_users)) {
  826. //error: no users to deal with
  827. cout($back_ui.$lang->def('_NO_USERS').$back_ui, 'content');
  828. return;
  829. }
  830. cout(getTitleArea($lang->def('_REQUIRED_USERS'), 'coursepanel').'<div class="std_block">', 'content');
  831. $table = new Table();
  832. $head_labels = array($lang->def('_USERNAME'), $lang->def('_NAME'));
  833. $head_style = array('', '', 'align_center', 'align_center');
  834. $table->addHead($head_labels, $head_style);
  835. //$date = date ("Y-m-d H:i:s", strtotime("+1 months"));
  836. //$now = date("Y-m-d H:i:s");
  837. $man_comp = new Competences_Manager();
  838. $comp_data = $man_comp->GetCompetence($sel_comp);
  839. $already = array();
  840. $query = "SELECT id_user, score_init, score_got FROM %lms_competence_user WHERE id_competence='".(int)$sel_comp."'";
  841. $res = $db->query($query);
  842. while (list($id_user, $score_init, $score_got) = $db->fetch_row($res)) {
  843. if ($comp_data['type'] == 'score') {
  844. //if the competence assignment exists in DB, but the total score is 0, then it's considered as non-assigned
  845. if (((int)$score_init + (int)$score_got) > 0) $already[] = $id_user;
  846. } else {
  847. $already[] = $id_user;
  848. }
  849. }
  850. $already = array_unique($already);
  851. $array_users = array_diff($array_users, $already);
  852. //get required competences not got from users
  853. $query = "";
  854. if ($comp_data['type'] == 'score') {
  855. $query = "SELECT u.idst, u.userid, u.lastname, u.firstname FROM %lms_competence_required as cr "
  856. ." JOIN %adm_user as u ON (cr.idst = u.idst)"
  857. ." WHERE cr.idst IN (".implode(",", $array_users).") AND cr.id_competence=".(int)$sel_comp." ORDER BY u.userid";
  858. } else {
  859. $query = "SELECT u.idst, u.userid, u.lastname, u.firstname FROM %lms_competence_required as cr "
  860. ." JOIN %adm_user as u ON (cr.idst = u.idst) "
  861. ." WHERE cr.idst IN (".implode(",", $array_users).") AND cr.id_competence=".(int)$sel_comp." ORDER BY u.userid";
  862. }
  863. $res = $db->query($query);
  864. if (sql_num_rows($res) > 0) {
  865. while (list($idst, $userid, $lastname, $firstname) = $db->fetch_row($res)) {
  866. $line = array();
  867. $line[] = $acl_man->relativeId($userid);
  868. $line[] = $lastname." ".$firstname;
  869. $table->addBody($line);
  870. }
  871. //cout(getTitleArea($lang->def('_EXPIRING_USERS'), 'coursepanel').'<div class="std_block">', 'content');
  872. cout($lang->def('_COMPETENCE').': <b>'.$comp_data['name'].'</b>', 'content');
  873. cout($back_ui.$table->getTable().$back_ui, 'content');
  874. } else {
  875. cout($back_ui.$lang->def('_NO_REQUIRED_USER').$back_ui, 'content');
  876. }
  877. } else {
  878. //error, no competence selected
  879. cout($back_ui.$lang->def('_NO_COMPETENCE_SELECTED').$back_ui, 'content');
  880. return;
  881. }
  882. }
  883. function publicCoursePanelDispatch($op) {
  884. switch ($op) {
  885. case "savepanel": {
  886. savePanel();
  887. } break;
  888. case "coursepanel": {
  889. coursePanel();
  890. } break;
  891. case "expired": {
  892. expired();
  893. } break;
  894. case "required": {
  895. required();
  896. } break;
  897. }
  898. }
  899. ?>