userLog.php 32 KB

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