userLog.php 33 KB

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