userLog.php 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. <?php // $Id: userLog.php 12263 2007-05-03 13:34:40Z elixir_julian $
  2. /*
  3. ==============================================================================
  4. Dokeos - elearning and course management software
  5. Copyright (c) 2004 Dokeos S.A.
  6. Copyright (c) 2003 Ghent University (UGent)
  7. Copyright (c) 2001 Universite catholique de Louvain (UCL)
  8. Copyright (c) Roan Embrechts (Vrije Universiteit Brussel)
  9. Copyright (c) Sebastien Piraux <piraux_seb@hotmail.com>
  10. For a full list of contributors, see "credits.txt".
  11. The full license can be read in "license.txt".
  12. This program is free software; you can redistribute it and/or
  13. modify it under the terms of the GNU General Public License
  14. as published by the Free Software Foundation; either version 2
  15. of the License, or (at your option) any later version.
  16. See the GNU General Public License for more details.
  17. Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
  18. ==============================================================================
  19. */
  20. /**
  21. ==============================================================================
  22. * @package dokeos.tracking
  23. * @todo clean code - structure is unclear and difficult to modify
  24. ==============================================================================
  25. */
  26. /*
  27. ==============================================================================
  28. INIT SECTION
  29. ==============================================================================
  30. */
  31. $uInfo = $_REQUEST['uInfo'];
  32. $view = $_REQUEST['view'];
  33. // name of the language file that needs to be included
  34. $language_file = 'tracking';
  35. include('../inc/global.inc.php');
  36. // Roles and rights system
  37. $user_id = api_get_user_id();
  38. $course_id = api_get_course_id();
  39. /*
  40. $role_id = RolesRights::get_local_user_role_id($user_id, $course_id);
  41. $location_id = RolesRights::get_course_tool_location_id($course_id, TOOL_TRACKING);
  42. $is_allowed = RolesRights::is_allowed_which_rights($role_id, $location_id);
  43. //block users without view right
  44. RolesRights::protect_location($role_id, $location_id);
  45. */
  46. //YW Hack security to quick fix RolesRights bug
  47. $is_allowed = true;
  48. /*
  49. -----------------------------------------------------------
  50. Libraries
  51. -----------------------------------------------------------
  52. */
  53. include(api_get_path(LIBRARY_PATH).'statsUtils.lib.inc.php');
  54. include(api_get_path(LIBRARY_PATH).'course.lib.php');
  55. include(api_get_path(SYS_CODE_PATH).'resourcelinker/resourcelinker.inc.php');
  56. require_once(api_get_path(SYS_CODE_PATH).'exercice/hotpotatoes.lib.php');
  57. /*
  58. -----------------------------------------------------------
  59. Header
  60. -----------------------------------------------------------
  61. */
  62. // charset determination
  63. if ($_GET['scormcontopen'])
  64. {
  65. $tbl_lp = Database::get_course_table('lp');
  66. $contopen = (int) $_GET['scormcontopen'];
  67. $sql = "SELECT default_encoding FROM $tbl_lp WHERE id = ".$contopen;
  68. $res = api_sql_query($sql,__FILE__,__LINE__);
  69. $row = Database::fetch_array($res);
  70. $lp_charset = $row['default_encoding'];
  71. //header('Content-Type: text/html; charset='. $row['default_encoding']);
  72. }
  73. /*
  74. $interbreadcrumb[]= array ("url"=>"../group/group.php", "name"=> get_lang('BredCrumpGroups'));
  75. $interbreadcrumb[]= array ("url"=>"../group/group_space.php?gidReq=$_gid", "name"=> get_lang('BredCrumpGroupSpace'));
  76. */
  77. if($uInfo)
  78. {
  79. $interbreadcrumb[]= array ("url"=>"../user/userInfo.php?uInfo=$uInfo", "name"=> ucfirst(get_lang('Users')));
  80. }
  81. $nameTools = get_lang('ToolName');
  82. $htmlHeadXtra[] = "<style type='text/css'>
  83. /*<![CDATA[*/
  84. .secLine {background-color : #E6E6E6;}
  85. .content {padding-left : 15px;padding-right : 15px; }
  86. .specialLink{color : #0000FF;}
  87. /*]]>*/
  88. </style>
  89. <style media='print' type='text/css'>
  90. /*<![CDATA[*/
  91. td {border-bottom: thin dashed gray;}
  92. /*]]>*/
  93. </style>";
  94. Display::display_header($nameTools,"Tracking");
  95. /*
  96. -----------------------------------------------------------
  97. Constants and variables
  98. -----------------------------------------------------------
  99. */
  100. $is_allowedToTrack = $is_courseAdmin;
  101. $is_course_member = CourseManager::is_user_subscribed_in_real_or_linked_course($user_id, $course_id);
  102. // Database Table Definitions
  103. $TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER);
  104. $TABLEUSER = Database::get_main_table(TABLE_MAIN_USER);
  105. $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  106. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  107. $TABLETRACK_ACCESS = $_configuration['statistics_database']."`.`track_e_access";
  108. $TABLETRACK_LINKS = $_configuration['statistics_database']."`.`track_e_links";
  109. $TABLETRACK_LOGIN = $_configuration['statistics_database']."`.`track_e_login";
  110. $TABLETRACK_DOWNLOADS = $_configuration['statistics_database']."`.`track_e_downloads";
  111. $TABLETRACK_UPLOADS = $_configuration['statistics_database']."`.`track_e_uploads";
  112. $TABLETRACK_EXERCICES = $_configuration['statistics_database']."`.`track_e_exercices";
  113. $TABLECOURSE_LINKS = Database::get_course_table(TABLE_LINK);
  114. $TABLECOURSE_WORK = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
  115. $TABLECOURSE_GROUPSUSER = Database::get_course_table(TABLE_GROUP_USER);
  116. $TABLECOURSE_EXERCICES = Database::get_course_table(TABLE_QUIZ_TEST);
  117. $TBL_TRACK_HOTPOTATOES = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_HOTPOTATOES);
  118. if(api_get_setting('use_session_mode') == "true") {
  119. $sql = "SELECT 1
  120. FROM $tbl_session_course_user AS session_course_user
  121. INNER JOIN $tbl_session AS session
  122. ON session_course_user.id_session = session.id
  123. AND ((date_start<=NOW()
  124. AND date_end>=NOW())
  125. OR (date_start='0000-00-00' AND date_end='0000-00-00'))
  126. WHERE id_session='".$_SESSION['id_session']."' AND course_code='$_cid'";
  127. //echo $sql;
  128. $result=api_sql_query($sql,__FILE__,__LINE__);
  129. if(!mysql_num_rows($result)){
  130. $disabled = true;
  131. }
  132. }
  133. $tbl_learnpath_main = Database::get_course_table('lp');
  134. $tbl_learnpath_item = Database::get_course_table('lp_item');
  135. $tbl_learnpath_view = Database::get_course_table('lp_view');
  136. $tbl_learnpath_item_view = Database::get_course_table('lp_item_view');
  137. $documentPath=api_get_path(SYS_COURSE_PATH).$_course['path'].'/document';
  138. // the variables for the days and the months
  139. // Defining the shorts for the days
  140. $DaysShort = array (myEnc(get_lang("SundayShort")), myEnc(get_lang("MondayShort")), myEnc(get_lang("TuesdayShort")), myEnc(get_lang("WednesdayShort")), myEnc(get_lang("ThursdayShort")), myEnc(get_lang("FridayShort")), myEnc(get_lang("SaturdayShort")));
  141. // Defining the days of the week to allow translation of the days
  142. $DaysLong = array (myEnc(get_lang("SundayLong")), myEnc(get_lang("MondayLong")), myEnc(get_lang("TuesdayLong")), myEnc(get_lang("WednesdayLong")), myEnc(get_lang("ThursdayLong")), myEnc(get_lang("FridayLong")), myEnc(get_lang("SaturdayLong")));
  143. // Defining the months of the year to allow translation of the months
  144. $MonthsLong = array (myEnc(get_lang("JanuaryLong")), myEnc(get_lang("FebruaryLong")), myEnc(get_lang("MarchLong")), myEnc(get_lang("AprilLong")), myEnc(get_lang("MayLong")), myEnc(get_lang("JuneLong")), myEnc(get_lang("JulyLong")), myEnc(get_lang("AugustLong")), myEnc(get_lang("SeptemberLong")), myEnc(get_lang("OctoberLong")), myEnc(get_lang("NovemberLong")), myEnc(get_lang("DecemberLong")));
  145. // Defining the months of the year to allow translation of the months
  146. $MonthsShort = array (myEnc(get_lang("JanuaryShort")), myEnc(get_lang("FebruaryShort")), myEnc(get_lang("MarchShort")), myEnc(get_lang("AprilShort")), myEnc(get_lang("MayShort")), myEnc(get_lang("JuneShort")), myEnc(get_lang("JulyShort")), myEnc(get_lang("AugustShort")), myEnc(get_lang("SeptemberShort")), myEnc(get_lang("OctoberShort")), myEnc(get_lang("NovemberShort")), myEnc(get_lang("DecemberShort")));
  147. //$is_allowedToTrack = $is_groupTutor; // allowed to track only user of one group
  148. //$is_allowedToTrackEverybodyInCourse = $is_allowed[EDIT_RIGHT]; // allowed to track all students in course
  149. //YW hack security to fix RolesRights bug
  150. $is_allowedToTrack = true; // allowed to track only user of one group
  151. $is_allowedToTrackEverybodyInCourse = $is_allowedToTrack; // allowed to track all students in course
  152. /*
  153. ==============================================================================
  154. FUNCTIONS
  155. ==============================================================================
  156. */
  157. /**
  158. * Shortcut function to use htmlentities on many, many strings in this script
  159. * @param string String in a supposed encoding
  160. * @param string Supposed initial encoding (default: 'ISO-8859-15')
  161. * @return string HTML string (no encoding dependency)
  162. * @author Yannick Warnier <yannick.warnier@dokeos.com>
  163. */
  164. function myEnc($isostring,$supposed_encoding='ISO-8859-15')
  165. {
  166. return htmlentities($isostring,ENT_QUOTES,$supposed_encoding);
  167. }
  168. /**
  169. * Displays the number of logins every month for a specific user in a specific course.
  170. */
  171. function display_login_tracking_info($view, $user_id, $course_id)
  172. {
  173. $MonthsLong = $GLOBALS['MonthsLong'];
  174. $track_access_table = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ACCESS);
  175. $tempView = $view;
  176. if(substr($view,0,1) == '1')
  177. {
  178. $new_view = substr_replace($view,'0',0,1);
  179. echo "
  180. <tr>
  181. <td valign='top'>
  182. <font color='#0000FF'>-&nbsp;&nbsp;&nbsp;</font><b>".myEnc(get_lang('LoginsAndAccessTools'))."</b>&nbsp;&nbsp;&nbsp;[<a href='".api_get_self()."?uInfo=$user_id&view=".$new_view."'>".myEnc(get_lang('Close'))."</a>]&nbsp;&nbsp;&nbsp;[<a href='userLogCSV.php?".api_get_cidreq()."&uInfo=".$_GET['uInfo']."&view=10000'>".get_lang('ExportAsCSV')."</a>]
  183. </td>
  184. </tr>
  185. ";
  186. echo "<tr><td style='padding-left : 40px;' valign='top'>".myEnc(get_lang('LoginsDetails'))."<br>";
  187. $sql = "SELECT UNIX_TIMESTAMP(`access_date`), count(`access_date`)
  188. FROM $track_access_table
  189. WHERE `access_user_id` = '$user_id'
  190. AND `access_cours_code` = '".$course_id."'
  191. GROUP BY YEAR(`access_date`),MONTH(`access_date`)
  192. ORDER BY YEAR(`access_date`),MONTH(`access_date`) ASC";
  193. echo "<tr><td style='padding-left : 40px;padding-right : 40px;'>";
  194. //$results = getManyResults2Col($sql);
  195. $results = getManyResults3Col($sql);
  196. echo "<table cellpadding='2' cellspacing='1' border='0' align=center>";
  197. echo "<tr>
  198. <td class='secLine'>
  199. ".myEnc(get_lang('LoginsTitleMonthColumn'))."
  200. </td>
  201. <td class='secLine'>
  202. ".myEnc(get_lang('LoginsTitleCountColumn'))."
  203. </td>
  204. </tr>";
  205. $total = 0;
  206. if (is_array($results))
  207. {
  208. for($j = 0 ; $j < count($results) ; $j++)
  209. {
  210. echo "<tr>";
  211. //echo "<td class='content'><a href='logins_details.php?uInfo=$user_id&reqdate=".$results[$j][0]."'>".$langMonthNames['long'][date("n", $results[$j][0])-1]." ".date("Y", $results[$j][0])."</a></td>";
  212. echo "<td class='content'><a href='logins_details.php?uInfo=$user_id&reqdate=".$results[$j][0]."&view=$view'>".$MonthsLong[date('n', $results[$j][0])-1].' '.date('Y', $results[$j][0])."</a></td>";
  213. echo "<td valign='top' align='right' class='content'>".$results[$j][1]."</td>";
  214. echo"</tr>";
  215. $total = $total + $results[$j][1];
  216. }
  217. echo "<tr>";
  218. echo "<td>".myEnc(get_lang('Total'))."</td>";
  219. echo "<td align='right' class='content'>".$total."</td>";
  220. echo"</tr>";
  221. }
  222. else
  223. {
  224. echo "<tr>";
  225. echo "<td colspan='2'><center>".myEnc(get_lang('NoResult'))."</center></td>";
  226. echo"</tr>";
  227. }
  228. echo "</table>";
  229. echo "</td></tr>";
  230. }
  231. else
  232. {
  233. $new_view = substr_replace($view,'1',0,1);
  234. echo "
  235. <tr>
  236. <td valign='top'>
  237. +<font color='#0000FF'>&nbsp;&nbsp;</font><a href='".api_get_self()."?uInfo=$user_id&view=".$new_view."' class='specialLink'>".myEnc(get_lang('LoginsAndAccessTools'))."</a>
  238. </td>
  239. </tr>
  240. ";
  241. }
  242. }
  243. /**
  244. * Displays the exercise results for a specific user in a specific course.
  245. * @todo remove globals
  246. */
  247. function display_exercise_tracking_info($view, $user_id, $course_id)
  248. {
  249. global $TABLECOURSE_EXERCICES, $TABLETRACK_EXERCICES;
  250. if(substr($view,1,1) == '1')
  251. {
  252. $new_view = substr_replace($view,'0',1,1);
  253. echo "
  254. <tr>
  255. <td valign='top'>
  256. <font color='#0000FF'>-&nbsp;&nbsp;&nbsp;</font><b>".myEnc(get_lang('ExercicesResults'))."</b>&nbsp;&nbsp;&nbsp;[<a href='".api_get_self()."?uInfo=$user_id&view=".$new_view."'>".myEnc(get_lang('Close'))."</a>]&nbsp;&nbsp;&nbsp;[<a href='userLogCSV.php?".api_get_cidreq()."&uInfo=".$_GET['uInfo']."&view=01000'>".get_lang('ExportAsCSV')."</a>]
  257. </td>
  258. </tr>
  259. ";
  260. echo "<tr><td style='padding-left : 40px;' valign='top'>".myEnc(get_lang('ExercicesDetails'))."<br />";
  261. $sql = "SELECT `ce`.`title`, `te`.`exe_result` , `te`.`exe_weighting`, UNIX_TIMESTAMP(`te`.`exe_date`)
  262. FROM $TABLECOURSE_EXERCICES AS ce , `$TABLETRACK_EXERCICES` AS te
  263. WHERE `te`.`exe_cours_id` = '$course_id'
  264. AND `te`.`exe_user_id` = '$user_id'
  265. AND `te`.`exe_exo_id` = `ce`.`id`
  266. ORDER BY `ce`.`title` ASC, `te`.`exe_date` ASC";
  267. $hpsql = "SELECT `te`.`exe_name`, `te`.`exe_result` , `te`.`exe_weighting`, UNIX_TIMESTAMP(`te`.`exe_date`)
  268. FROM $TBL_TRACK_HOTPOTATOES AS te
  269. WHERE `te`.`exe_user_id` = '$user_id' AND `te`.`exe_cours_id` = '$course_id'
  270. ORDER BY `te`.`exe_cours_id` ASC, `te`.`exe_date` ASC";
  271. $hpresults = getManyResultsXCol($hpsql, 4);
  272. $NoTestRes = 0;
  273. $NoHPTestRes = 0;
  274. echo "<tr>\n<td style='padding-left : 40px;padding-right : 40px;'>\n";
  275. $results = getManyResultsXCol($sql, 4);
  276. echo "<table cellpadding='2' cellspacing='1' border='0' align='center'>\n";
  277. echo "
  278. <tr bgcolor='#E6E6E6'>
  279. <td>
  280. ".myEnc(get_lang('ExercicesTitleExerciceColumn'))."
  281. </td>
  282. <td>
  283. ".myEnc(get_lang('Date'))."
  284. </td>
  285. <td>
  286. ".myEnc(get_lang('ExercicesTitleScoreColumn'))."
  287. </td>
  288. </tr>";
  289. if (is_array($results))
  290. {
  291. for($i = 0; $i < sizeof($results); $i++)
  292. {
  293. $display_date = format_locale_date(get_lang('dateTimeFormatLong'), $results[$i][3]);
  294. echo "<tr>\n";
  295. echo "<td class='content'>".$results[$i][0]."</td>\n";
  296. echo "<td class='content'>".$display_date."</td>\n";
  297. echo "<td valign='top' align='right' class='content'>".$results[$i][1]." / ".$results[$i][2]."</td>\n";
  298. echo "</tr>\n";
  299. }
  300. }
  301. else // istvan begin
  302. {
  303. $NoTestRes = 1;
  304. }
  305. // The Result of Tests
  306. if(is_array($hpresults))
  307. {
  308. for($i = 0; $i < sizeof($hpresults); $i++)
  309. {
  310. $title = GetQuizName($hpresults[$i][0],'');
  311. if ($title == '')
  312. $title = GetFileName($hpresults[$i][0]);
  313. $display_date = format_locale_date(get_lang('dateTimeFormatLong'), $hpresults[$i][3]);
  314. ?>
  315. <tr>
  316. <td class="content"><?php echo $title; ?></td>
  317. <td class="content" align="center"><?php echo $display_date; ?></td>
  318. <td class="content" align="center"><?php echo $hpresults[$i][1]; ?> / <?php echo $hpresults[$i][2]; ?></td>
  319. </tr>
  320. <?php }
  321. }
  322. else
  323. {
  324. $NoHPTestRes = 1;
  325. }
  326. if ($NoTestRes == 1 && $NoHPTestRes == 1)
  327. {
  328. echo "<tr>\n";
  329. echo "<td colspan='3'><center>".myEnc(get_lang('NoResult'))."</center></td>\n";
  330. echo "</tr>\n";
  331. }
  332. echo "</table>";
  333. echo "</td>\n</tr>\n";
  334. }
  335. else
  336. {
  337. $new_view = substr_replace($view,'1',1,1);
  338. echo "
  339. <tr>
  340. <td valign='top'>
  341. +<font color='#0000FF'>&nbsp;&nbsp;</font><a href='".api_get_self()."?uInfo=$user_id&view=".$new_view."' class='specialLink'>".myEnc(get_lang('ExercicesResults'))."</a>
  342. </td>
  343. </tr>
  344. ";
  345. }
  346. }
  347. /**
  348. * Displays the student publications for a specific user in a specific course.
  349. * @todo remove globals
  350. */
  351. function display_student_publications_tracking_info($view, $user_id, $course_id)
  352. {
  353. global $TABLETRACK_UPLOADS, $TABLECOURSE_WORK, $dateTimeFormatLong;
  354. if(substr($view,2,1) == '1')
  355. {
  356. $new_view = substr_replace($view,'0',2,1);
  357. echo "
  358. <tr>
  359. <td valign='top'>
  360. <font color='#0000FF'>-&nbsp;&nbsp;&nbsp;</font><b>".myEnc(get_lang('WorkUploads'))."</b>&nbsp;&nbsp;&nbsp;[<a href='".api_get_self()."?uInfo=$user_id&view=".$new_view."'>".myEnc(get_lang('Close'))."</a>]&nbsp;&nbsp;&nbsp;[<a href='userLogCSV.php?".api_get_cidreq()."&uInfo=".$_GET['uInfo']."&view=00100'>".get_lang('ExportAsCSV')."</a>]
  361. </td>
  362. </tr>
  363. ";
  364. echo "<tr><td style='padding-left : 40px;' valign='top'>".myEnc(get_lang('WorksDetails'))."<br>";
  365. $sql = "SELECT `u`.`upload_date`, `w`.`title`, `w`.`author`,`w`.`url`
  366. FROM `$TABLETRACK_UPLOADS` `u` , $TABLECOURSE_WORK `w`
  367. WHERE `u`.`upload_work_id` = `w`.`id`
  368. AND `u`.`upload_user_id` = '$user_id'
  369. AND `u`.`upload_cours_id` = '$course_id'
  370. ORDER BY `u`.`upload_date` DESC";
  371. echo "<tr><td style='padding-left : 40px;padding-right : 40px;'>";
  372. $results = getManyResultsXCol($sql,4);
  373. echo "<table cellpadding='2' cellspacing='1' border='0' align=center>";
  374. echo "<tr>
  375. <td class='secLine' width='40%'>
  376. ".myEnc(get_lang('WorkTitle'))."
  377. </td>
  378. <td class='secLine' width='30%'>
  379. ".myEnc(get_lang('WorkAuthors'))."
  380. </td>
  381. <td class='secLine' width='30%'>
  382. ".myEnc(get_lang('Date'))."
  383. </td>
  384. </tr>";
  385. if (is_array($results))
  386. {
  387. for($j = 0 ; $j < count($results) ; $j++)
  388. {
  389. $pathToFile = api_get_path(WEB_COURSE_PATH).$_course['path']."/".$results[$j][3];
  390. $timestamp = strtotime($results[$j][0]);
  391. $beautifulDate = format_locale_date($dateTimeFormatLong,$timestamp);
  392. echo "<tr>";
  393. echo "<td class='content'>"
  394. ."<a href ='".$pathToFile."'>".$results[$j][1]."</a>"
  395. ."</td>";
  396. echo "<td class='content'>".$results[$j][2]."</td>";
  397. echo "<td class='content'>".$beautifulDate."</td>";
  398. echo"</tr>";
  399. }
  400. }
  401. else
  402. {
  403. echo "<tr>";
  404. echo "<td colspan='3'><center>".myEnc(get_lang('NoResult'))."</center></td>";
  405. echo"</tr>";
  406. }
  407. echo "</table>";
  408. echo "</td></tr>";
  409. }
  410. else
  411. {
  412. $new_view = substr_replace($view,'1',2,1);
  413. echo "
  414. <tr>
  415. <td valign='top'>
  416. +<font color='#0000FF'>&nbsp;&nbsp;</font><a href='".api_get_self()."?uInfo=$user_id&view=".$new_view."' class='specialLink'>".myEnc(get_lang('WorkUploads'))."</a>
  417. </td>
  418. </tr>
  419. ";
  420. }
  421. }
  422. /**
  423. * Displays the links followed for a specific user in a specific course.
  424. * @todo remove globals
  425. */
  426. function display_links_tracking_info($view, $user_id, $course_id)
  427. {
  428. global $TABLETRACK_LINKS, $TABLECOURSE_LINKS;
  429. if(substr($view,3,1) == '1')
  430. {
  431. $new_view = substr_replace($view,'0',3,1);
  432. echo "
  433. <tr>
  434. <td valign='top'>
  435. <font color='#0000FF'>-&nbsp;&nbsp;&nbsp;</font><b>".myEnc(get_lang('LinksAccess'))."</b>&nbsp;&nbsp;&nbsp;[<a href='".api_get_self()."?uInfo=$user_id&view=".$new_view."'>".myEnc(get_lang('Close'))."</a>]&nbsp;&nbsp;&nbsp;[<a href='userLogCSV.php?".api_get_cidreq()."&uInfo=".$_GET['uInfo']."&view=00010'>".get_lang('ExportAsCSV')."</a>]
  436. </td>
  437. </tr>
  438. ";
  439. echo "<tr><td style='padding-left : 40px;' valign='top'>".myEnc(get_lang('LinksDetails'))."<br>";
  440. $sql = "SELECT `cl`.`title`, `cl`.`url`
  441. FROM `$TABLETRACK_LINKS` AS sl, $TABLECOURSE_LINKS AS cl
  442. WHERE `sl`.`links_link_id` = `cl`.`id`
  443. AND `sl`.`links_cours_id` = '$course_id'
  444. AND `sl`.`links_user_id` = '$user_id'
  445. GROUP BY `cl`.`title`, `cl`.`url`";
  446. echo "<tr><td style='padding-left : 40px;padding-right : 40px;'>";
  447. $results = getManyResults2Col($sql);
  448. echo "<table cellpadding='2' cellspacing='1' border='0' align=center>";
  449. echo "<tr>
  450. <td class='secLine'>
  451. ".myEnc(get_lang('LinksTitleLinkColumn'))."
  452. </td>
  453. </tr>";
  454. if (is_array($results))
  455. {
  456. for($j = 0 ; $j < count($results) ; $j++)
  457. {
  458. echo "<tr>";
  459. echo "<td class='content'><a href='".$results[$j][1]."'>".$results[$j][0]."</a></td>";
  460. echo"</tr>";
  461. }
  462. }
  463. else
  464. {
  465. echo "<tr>";
  466. echo "<td ><center>".myEnc(get_lang('NoResult'))."</center></td>";
  467. echo"</tr>";
  468. }
  469. echo "</table>";
  470. echo "</td></tr>";
  471. }
  472. else
  473. {
  474. $new_view = substr_replace($view,'1',3,1);
  475. echo "
  476. <tr>
  477. <td valign='top'>
  478. +<font color='#0000FF'>&nbsp;&nbsp;</font><a href='".api_get_self()."?uInfo=$user_id&view=".$new_view."' class='specialLink'>".myEnc(get_lang('LinksAccess'))."</a>
  479. </td>
  480. </tr>
  481. ";
  482. }
  483. }
  484. /**
  485. * Displays the documents downloaded for a specific user in a specific course.
  486. */
  487. function display_document_tracking_info($view, $user_id, $course_id)
  488. {
  489. $downloads_table = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_DOWNLOADS);
  490. if(substr($view,4,1) == '1')
  491. {
  492. $new_view = substr_replace($view,'0',4,1);
  493. echo "
  494. <tr>
  495. <td valign='top'>
  496. <font color='#0000FF'>-&nbsp;&nbsp;&nbsp;</font><b>".myEnc(get_lang('DocumentsAccess'))."</b>&nbsp;&nbsp;&nbsp;[<a href='".api_get_self()."?uInfo=$user_id&view=".$new_view."'>".myEnc(get_lang('Close'))."</a>]&nbsp;&nbsp;&nbsp;[<a href='userLogCSV.php?".api_get_cidreq()."&uInfo=".$_GET['uInfo']."&view=00001'>".get_lang('ExportAsCSV')."</a>]
  497. </td>
  498. </tr>
  499. ";
  500. echo "<tr><td style='padding-left : 40px;' valign='top'>".myEnc(get_lang('DocumentsDetails'))."<br>";
  501. $sql = "SELECT `down_doc_path`
  502. FROM $downloads_table
  503. WHERE `down_cours_id` = '$course_id'
  504. AND `down_user_id` = '$user_id'
  505. GROUP BY `down_doc_path`";
  506. echo "<tr><td style='padding-left : 40px;padding-right : 40px;'>";
  507. $results = getManyResults1Col($sql);
  508. echo "<table cellpadding='2' cellspacing='1' border='0' align='center'>";
  509. echo "<tr>
  510. <td class='secLine'>
  511. ".myEnc(get_lang('DocumentsTitleDocumentColumn'))."
  512. </td>
  513. </tr>";
  514. if (is_array($results))
  515. {
  516. for($j = 0 ; $j < count($results) ; $j++)
  517. {
  518. echo "<tr>";
  519. echo "<td class='content'>".$results[$j]."</td>";
  520. echo"</tr>";
  521. }
  522. }
  523. else
  524. {
  525. echo "<tr>";
  526. echo "<td><center>".myEnc(get_lang('NoResult'))."</center></td>";
  527. echo"</tr>";
  528. }
  529. echo "</table>";
  530. echo "</td></tr>";
  531. }
  532. else
  533. {
  534. $new_view = substr_replace($view,'1',4,1);
  535. echo "
  536. <tr>
  537. <td valign='top'>
  538. +<font color='#0000FF'>&nbsp;&nbsp;</font><a href='".api_get_self()."?uInfo=$user_id&view=".$new_view."' class='specialLink'>".myEnc(get_lang('DocumentsAccess'))."</a>
  539. </td>
  540. </tr>
  541. ";
  542. }
  543. }
  544. /*
  545. ==============================================================================
  546. MAIN SECTION
  547. ==============================================================================
  548. */
  549. ?>
  550. <h3>
  551. <?php echo $nameTools ?>
  552. </h3>
  553. <h4>
  554. <?php echo myEnc(get_lang('StatsOfUser')); ?>
  555. </h4>
  556. <table width="100%" cellpadding="2" cellspacing="3" border="0">
  557. <?php
  558. // check if uid is tutor of this group
  559. if( ( $is_allowedToTrack || $is_allowedToTrackEverybodyInCourse ) && $_configuration['tracking_enabled'] )
  560. {
  561. if(!$uInfo && !isset($uInfo) )
  562. {
  563. /***************************************************************************
  564. *
  565. * Display list of user of this group
  566. *
  567. ***************************************************************************/
  568. echo "<h4>".myEnc(get_lang('ListStudents'))."</h4>";
  569. if( $is_allowedToTrackEverybodyInCourse )
  570. {
  571. // if user can track everybody : list user of course
  572. if(api_get_setting('use_session_mode')) {
  573. $sql = "SELECT count(user_id)
  574. FROM $TABLECOURSUSER
  575. WHERE `course_code` = '$_cid'";
  576. }
  577. else {
  578. $sql = "SELECT count(id_user)
  579. FROM $tbl_session_course_user
  580. WHERE `course_code` = '$_cid'";
  581. }
  582. }
  583. else
  584. {
  585. // if user can only track one group : list users of this group
  586. $sql = "SELECT count(user)
  587. FROM $TABLECOURSE_GROUPSUSER
  588. WHERE `group_id` = '$_gid'";
  589. }
  590. $userGroupNb = getOneResult($sql);
  591. $step = 25; // number of student per page
  592. if ($userGroupNb > $step)
  593. {
  594. if(!isset($offset))
  595. {
  596. $offset=0;
  597. }
  598. $next = $offset + $step;
  599. $previous = $offset - $step;
  600. $navLink = "<table width='100%' border='0'>\n"
  601. ."<tr>\n"
  602. ."<td align='left'>";
  603. if ($previous >= 0)
  604. {
  605. $navLink .= "<a href='".api_get_self()."?offset=$previous'>&lt;&lt; ".myEnc(get_lang('PreviousPage'))."</a>";
  606. }
  607. $navLink .= "</td>\n"
  608. ."<td align='right'>";
  609. if ($next < $userGroupNb)
  610. {
  611. $navLink .= "<a href='".api_get_self()."?offset=$next'>".myEnc(get_lang('NextPage'))." &gt;&gt;</a>";
  612. }
  613. $navLink .= "</td>\n"
  614. ."</tr>\n"
  615. ."</table>\n";
  616. }
  617. else
  618. {
  619. $offset = 0;
  620. }
  621. echo $navLink;
  622. if (!settype($offset, 'integer') || !settype($step, 'integer')) die('Offset or step variables are not integers.'); //sanity check of integer vars
  623. if( $is_allowedToTrackEverybodyInCourse )
  624. {
  625. // list of users in this course
  626. $sql = "SELECT `u`.`user_id`, `u`.`firstname`,`u`.`lastname`
  627. FROM $TABLECOURSUSER cu , $TABLEUSER u
  628. WHERE `cu`.`user_id` = `u`.`user_id`
  629. AND `cu`.`course_code` = '$_cid'
  630. LIMIT $offset,$step";
  631. }
  632. else
  633. {
  634. // list of users of this group
  635. $sql = "SELECT `u`.`user_id`, `u`.`firstname`,`u`.`lastname`
  636. FROM $TABLECOURSE_GROUPSUSER gu , $TABLEUSER u
  637. WHERE `gu`.`user_id` = `u`.`user_id`
  638. AND `gu`.`group_id` = '$_gid'
  639. LIMIT $offset,$step";
  640. }
  641. $list_users = getManyResults3Col($sql);
  642. echo "<table width='100%' cellpadding='2' cellspacing='1' border='0'>\n"
  643. ."<tr align='center' valign='top' bgcolor='#E6E6E6'>\n"
  644. ."<td align='left'>",myEnc(get_lang('UserName')),"</td>\n"
  645. ."</tr>\n";
  646. for($i = 0 ; $i < sizeof($list_users) ; $i++)
  647. {
  648. echo "<tr valign='top' align='center'>\n"
  649. ."<td align='left'>"
  650. ."<a href='".api_get_self()."?uInfo=",$list_users[$i][0],"'>"
  651. .$list_users[$i][1]," ",$list_users[$i][2]
  652. ."</a>".
  653. "</td>\n";
  654. }
  655. echo "</table>\n";
  656. echo $navLink;
  657. }
  658. else // if uInfo is set
  659. {
  660. /***************************************************************************
  661. *
  662. * Informations about student uInfo
  663. *
  664. ***************************************************************************/
  665. // these checks exists for security reasons, neither a prof nor a tutor can see statistics of a user from
  666. // another course, or group
  667. if( $is_allowedToTrackEverybodyInCourse )
  668. {
  669. // check if user is in this course
  670. $tracking_is_accepted = $is_course_member;
  671. $tracked_user_info = Database::get_user_info_from_id($uInfo);
  672. }
  673. else
  674. {
  675. // check if user is in the group of this tutor
  676. $sql = "SELECT `u`.`firstname`,`u`.`lastname`, `u`.`email`
  677. FROM $TABLECOURSE_GROUPSUSER gu , $TABLEUSER u
  678. WHERE `gu`.`user_id` = `u`.`user_id`
  679. AND `gu`.`group_id` = '$_gid'
  680. AND `u`.`user_id` = '$uInfo'";
  681. $query = api_sql_query($sql,__FILE__,__LINE__);
  682. $tracked_user_info = @mysql_fetch_assoc($query);
  683. if(is_array($tracked_user_info)) $tracking_is_accepted = true;
  684. }
  685. if ($tracking_is_accepted)
  686. {
  687. $tracked_user_info['email'] == '' ? $mail_link = myEnc(get_lang('NoEmail')) : $mail_link = Display::encrypted_mailto_link($tracked_user_info['email']);
  688. echo "<tr><td>";
  689. echo get_lang('informationsAbout').' :';
  690. echo "<ul>\n"
  691. ."<li>".myEnc(get_lang('FirstName'))." : ".$tracked_user_info['firstname']."</li>\n"
  692. ."<li>".myEnc(get_lang('LastName'))." : ".$tracked_user_info['lastname']."</li>\n"
  693. ."<li>".myEnc(get_lang('Email'))." : ".$mail_link."</li>\n"
  694. ."</ul>";
  695. echo "</td></tr>\n";
  696. // show all : number of 1 is equal to or bigger than number of categories
  697. // show none : number of 0 is equal to or bigger than number of categories
  698. echo "<tr>
  699. <td>
  700. [<a href='".api_get_self()."?uInfo=$uInfo&view=1111111'>".myEnc(get_lang('ShowAll'))."</a>]
  701. [<a href='".api_get_self()."?uInfo=$uInfo&view=0000000'>".myEnc(get_lang('ShowNone'))."</a>]".
  702. //"||[<a href='".api_get_self()."'>".myEnc(get_lang('BackToList'))."</a>]".
  703. "</td>
  704. </tr>
  705. ";
  706. if(!isset($view))
  707. {
  708. $view ='0000000';
  709. }
  710. //Logins
  711. display_login_tracking_info($view, $uInfo, $_cid);
  712. //Exercise results
  713. display_exercise_tracking_info($view, $uInfo, $_cid);
  714. //Student publications uploaded
  715. display_student_publications_tracking_info($view, $uInfo, $_cid);
  716. //Links usage
  717. display_links_tracking_info($view, $uInfo, $_cid);
  718. //Documents downloaded
  719. display_document_tracking_info($view, $uInfo, $_cid);
  720. }
  721. else
  722. {
  723. echo myEnc(get_lang('ErrorUserNotInGroup'));
  724. }
  725. /***************************************************************************
  726. *
  727. * Scorm contents and Learning Path
  728. *
  729. ***************************************************************************/
  730. if(substr($view,5,1) == '1')
  731. {
  732. $new_view = substr_replace($view,'0',5,1);
  733. echo "
  734. <tr>
  735. <td valign='top'>
  736. <font color='#0000FF'>-&nbsp;&nbsp;&nbsp;</font><b>".myEnc(get_lang('ScormAccess'))."</b>&nbsp;&nbsp;&nbsp;[<a href='".api_get_self()."?view=$new_view&uInfo=$uInfo'>".myEnc(get_lang('Close'))."</a>]&nbsp;&nbsp;&nbsp;[<a href='userLogCSV.php?".api_get_cidreq()."&uInfo=".$_GET['uInfo']."&view=000001'>".get_lang('ExportAsCSV')."</a>]
  737. </td>
  738. </tr>
  739. ";
  740. $sql = "SELECT id, name FROM $tbl_learnpath_main";
  741. $result=api_sql_query($sql,__FILE__,__LINE__);
  742. $ar=Database::fetch_array($result);
  743. echo "<tr><td style='padding-left : 40px;padding-right : 40px;'>";
  744. echo "<table cellpadding='2' cellspacing='1' border='0' align='center'><tr>
  745. <td class='secLine'>
  746. &nbsp;".myEnc(get_lang('ScormContentColumn'))."&nbsp;
  747. </td>
  748. </tr>";
  749. if (is_array($ar))
  750. {
  751. while ($ar['id'] != '') {
  752. $lp_title = stripslashes($ar['name']);
  753. echo "<tr><td>";
  754. echo "<a href='".api_get_self()."?view=".$view."&scormcontopen=".$ar['id']."&uInfo=$uInfo' class='specialLink'>$lp_title</a>";
  755. echo "</td></tr>";
  756. if ($ar['id']==$scormcontopen) { //have to list the students here
  757. $contentId=$ar['id'];
  758. $sql3 = "SELECT iv.status, iv.score, i.title, iv.total_time " .
  759. "FROM $tbl_learnpath_item i " .
  760. "INNER JOIN $tbl_learnpath_item_view iv ON i.id=iv.lp_item_id " .
  761. "INNER JOIN $tbl_learnpath_view v ON iv.lp_view_id=v.id " .
  762. "WHERE (v.user_id=$uInfo and v.lp_id=$contentId) ORDER BY v.id, i.id";
  763. $result3=api_sql_query($sql3,__FILE__,__LINE__);
  764. $ar3=Database::fetch_array($result3);
  765. if (is_array($ar3)) {
  766. echo "<tr><td>&nbsp;&nbsp;&nbsp;</td>
  767. <td class='secLine'>
  768. &nbsp;".myEnc(get_lang('ScormTitleColumn'))."&nbsp;
  769. </td>
  770. <td class='secLine'>
  771. &nbsp;".myEnc(get_lang('ScormStatusColumn'))."&nbsp;
  772. </td>
  773. <td class='secLine'>
  774. &nbsp;".myEnc(get_lang('ScormScoreColumn'))."&nbsp;
  775. </td>
  776. <td class='secLine'>
  777. &nbsp;".myEnc(get_lang('ScormTimeColumn'))."&nbsp;
  778. </td>
  779. </tr>";
  780. while ($ar3['status'] != '') {
  781. require_once('../newscorm/learnpathItem.class.php');
  782. $time = learnpathItem::get_scorm_time('php',$ar3['total_time']);
  783. $title = htmlentities($ar3['title'],ENT_QUOTES,$lp_charset);
  784. echo "<tr><td>&nbsp;&nbsp;&nbsp;</td><td>";
  785. echo "$title</td><td align=right>{$ar3['status']}</td><td align=right>{$ar3['score']}</td><td align=right>$time</td>";
  786. echo "</tr>";
  787. $ar3=Database::fetch_array($result3);
  788. }
  789. } else {
  790. echo "<tr>";
  791. echo "<td colspan='3'><center>".myEnc(get_lang('ScormNeverOpened'))."</center></td>";
  792. echo"</tr>";
  793. }
  794. }
  795. $ar=Database::fetch_array($result);
  796. }
  797. }
  798. else
  799. {
  800. $noscorm=true;
  801. }
  802. if ($noscorm) {
  803. echo "<tr>";
  804. echo "<td colspan='3'><center>".myEnc(get_lang('NoResult'))."</center></td>";
  805. echo "</tr>";
  806. }
  807. echo "</table>";
  808. echo "</td></tr>";
  809. }
  810. else
  811. {
  812. $new_view = substr_replace($view,'1',5,1);
  813. echo "
  814. <tr>
  815. <td valign='top'>
  816. +<font color='#0000FF'>&nbsp;&nbsp;</font><a href='".api_get_self()."?view=$new_view&uInfo=$uInfo' class='specialLink'>".myEnc(get_lang('ScormAccess'))."</a>
  817. </td>
  818. </tr>
  819. ";
  820. }
  821. }
  822. }
  823. // not allowed
  824. else
  825. {
  826. if(!$_configuration['tracking_enabled'])
  827. {
  828. echo myEnc(get_lang('TrackingDisabled'));
  829. }
  830. else
  831. {
  832. api_not_allowed();
  833. }
  834. }
  835. ?>
  836. </table>
  837. <?php
  838. Display::display_footer();
  839. ?>