myspace.lib.php 143 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use CpChart\Classes\pCache as pCache;
  4. use CpChart\Classes\pData as pData;
  5. use CpChart\Classes\pImage as pImage;
  6. /**
  7. * Class MySpace
  8. * @package chamilo.reporting
  9. */
  10. class MySpace
  11. {
  12. /**
  13. * Get admin actions
  14. * @return string
  15. */
  16. public static function getAdminActions()
  17. {
  18. $actions = array(
  19. //array('url' => api_get_path(WEB_CODE_PATH).'mySpace/index.php', 'content' => get_lang('Home')),
  20. array('url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=coaches', 'content' => get_lang('DisplayCoaches')),
  21. array('url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=user', 'content' => get_lang('DisplayUserOverview')),
  22. array('url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=session', 'content' => get_lang('DisplaySessionOverview')),
  23. array('url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=course', 'content' => get_lang('DisplayCourseOverview')),
  24. array('url' => api_get_path(WEB_CODE_PATH).'tracking/question_course_report.php?view=admin', 'content' => get_lang('LPQuestionListResults')),
  25. array('url' => api_get_path(WEB_CODE_PATH).'tracking/course_session_report.php?view=admin', 'content' => get_lang('LPExerciseResultsBySession')),
  26. ['url' => api_get_path(WEB_CODE_PATH) . 'mySpace/admin_view.php?display=accessoverview', 'content' => get_lang('DisplayAccessOverview') . ' (' . get_lang('Beta') . ')']
  27. );
  28. return Display :: actions($actions, null);
  29. }
  30. public static function getTopMenu()
  31. {
  32. $menu_items = array();
  33. $menu_items[] = Display::url(Display::return_icon('stats.png', get_lang('MyStats'),'',ICON_SIZE_MEDIUM),api_get_path(WEB_CODE_PATH)."auth/my_progress.php" );
  34. $menu_items[] = Display::url(Display::return_icon('teacher.png', get_lang('TeacherInterface'), array(), 32), api_get_path(WEB_CODE_PATH).'mySpace/?view=teacher');
  35. $menu_items[] = Display::url(Display::return_icon('star_na.png', get_lang('AdminInterface'), array(), 32), '#');
  36. $menu_items[] = Display::url(Display::return_icon('quiz.png', get_lang('ExamTracking'), array(), 32), api_get_path(WEB_CODE_PATH).'tracking/exams.php');
  37. $menu = null;
  38. foreach ($menu_items as $item) {
  39. $menu .= $item;
  40. }
  41. $menu .= '<br />';
  42. return $menu;
  43. }
  44. /**
  45. * This function serves exporting data in CSV format.
  46. * @param array $header The header labels.
  47. * @param array $data The data array.
  48. * @param string $file_name The name of the file which contains exported data.
  49. * @return string mixed Returns a message (string) if an error occurred.
  50. */
  51. function export_csv($header, $data, $file_name = 'export.csv')
  52. {
  53. $archive_path = api_get_path(SYS_ARCHIVE_PATH);
  54. $archive_url = api_get_path(WEB_CODE_PATH).'course_info/download.php?archive=';
  55. if (!$open = fopen($archive_path.$file_name, 'w+')) {
  56. $message = get_lang('noOpen');
  57. } else {
  58. $info = '';
  59. foreach ($header as $value) {
  60. $info .= $value.';';
  61. }
  62. $info .= "\r\n";
  63. foreach ($data as $row) {
  64. foreach ($row as $value) {
  65. $info .= $value.';';
  66. }
  67. $info .= "\r\n";
  68. }
  69. fwrite($open, $info);
  70. fclose($open);
  71. @chmod($file_name, api_get_permissions_for_new_files());
  72. header("Location:".$archive_url.$file_name);
  73. }
  74. return $message;
  75. }
  76. /**
  77. * Gets the connections to a course as an array of login and logout time
  78. *
  79. * @param int User ud
  80. * @param int $courseId
  81. * @param int Session id (optional, default = 0)
  82. * @return array Conections
  83. */
  84. static function get_connections_to_course($user_id, $courseId, $session_id = 0)
  85. {
  86. // Database table definitions
  87. $tbl_track_course = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
  88. // protect data
  89. $user_id = intval($user_id);
  90. $courseId = intval($courseId);
  91. $session_id = intval($session_id);
  92. $sql = 'SELECT login_course_date, logout_course_date
  93. FROM ' . $tbl_track_course . '
  94. WHERE
  95. user_id = '.$user_id.' AND
  96. c_id = '.$courseId.' AND
  97. session_id = '.$session_id.'
  98. ORDER BY login_course_date ASC';
  99. $rs = Database::query($sql);
  100. $connections = array();
  101. while ($row = Database::fetch_array($rs)) {
  102. $timestamp_login_date = api_strtotime($row['login_course_date'], 'UTC');
  103. $timestamp_logout_date = api_strtotime($row['logout_course_date'], 'UTC');
  104. $connections[] = array('login' => $timestamp_login_date, 'logout' => $timestamp_logout_date);
  105. }
  106. return $connections;
  107. }
  108. /**
  109. * @param $user_id
  110. * @param $course_list
  111. * @param int $session_id
  112. * @return array|bool
  113. */
  114. static function get_connections_from_course_list($user_id, $course_list, $session_id = 0)
  115. {
  116. // Database table definitions
  117. $tbl_track_course = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
  118. if (empty($course_list)) {
  119. return false;
  120. }
  121. // protect data
  122. $user_id = intval($user_id);
  123. $session_id = intval($session_id);
  124. $new_course_list = array();
  125. foreach ($course_list as $course_item) {
  126. $courseInfo = api_get_course_info($course_item['code']);
  127. $courseId = $courseInfo['real_id'];
  128. $new_course_list[] = '"'.$courseId.'"';
  129. }
  130. $course_list = implode(', ', $new_course_list);
  131. if (empty($course_list)) {
  132. return false;
  133. }
  134. $sql = 'SELECT login_course_date, logout_course_date, c_id
  135. FROM ' . $tbl_track_course . '
  136. WHERE
  137. user_id = '.$user_id.' AND
  138. c_id IN ('.$course_list.') AND
  139. session_id = '.$session_id.'
  140. ORDER BY login_course_date ASC';
  141. $rs = Database::query($sql);
  142. $connections = array();
  143. while ($row = Database::fetch_array($rs)) {
  144. $timestamp_login_date = api_strtotime($row['login_course_date'], 'UTC');
  145. $timestamp_logout_date = api_strtotime($row['logout_course_date'], 'UTC');
  146. $connections[] = array(
  147. 'login' => $timestamp_login_date,
  148. 'logout' => $timestamp_logout_date,
  149. 'c_id' => $row['c_id']
  150. );
  151. }
  152. return $connections;
  153. }
  154. /**
  155. * Creates a small table in the last column of the table with the user overview
  156. *
  157. * @param integer $user_id the id of the user
  158. * @param array $url_params additonal url parameters
  159. * @param array $row the row information (the other columns)
  160. * @return string html code
  161. */
  162. public static function course_info_tracking_filter($user_id, $url_params, $row)
  163. {
  164. // the table header
  165. $return = '<table class="data_table" style="width: 100%;border:0;padding:0;border-collapse:collapse;table-layout: fixed">';
  166. /*$return .= ' <tr>';
  167. $return .= ' <th>'.get_lang('Course').'</th>';
  168. $return .= ' <th>'.get_lang('AvgTimeSpentInTheCourse').'</th>';
  169. $return .= ' <th>'.get_lang('AvgStudentsProgress').'</th>';
  170. $return .= ' <th>'.get_lang('AvgCourseScore').'</th>';
  171. $return .= ' <th>'.get_lang('AvgExercisesScore').'</th>';
  172. $return .= ' <th>'.get_lang('AvgMessages').'</th>';
  173. $return .= ' <th>'.get_lang('AvgAssignments').'</th>';
  174. $return .= ' <th>'.get_lang('TotalExercisesScoreObtained').'</th>';
  175. $return .= ' <th>'.get_lang('TotalExercisesScorePossible').'</th>';
  176. $return .= ' <th>'.get_lang('TotalExercisesAnswered').'</th>';
  177. $return .= ' <th>'.get_lang('TotalExercisesScorePercentage').'</th>';
  178. $return .= ' <th>'.get_lang('FirstLogin').'</th>';
  179. $return .= ' <th>'.get_lang('LatestLogin').'</th>';
  180. $return .= ' </tr>';*/
  181. // database table definition
  182. $tbl_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  183. // getting all the courses of the user
  184. $sql = "SELECT * FROM $tbl_course_user
  185. WHERE
  186. user_id = '".intval($user_id)."' AND
  187. relation_type<>".COURSE_RELATION_TYPE_RRHH." ";
  188. $result = Database::query($sql);
  189. while ($row = Database::fetch_array($result)) {
  190. $courseInfo = api_get_course_info_by_id($row['c_id']);
  191. if (empty($courseInfo)) {
  192. continue;
  193. }
  194. $courseCode = $courseInfo['code'];
  195. $courseId = $courseInfo['real_id'];
  196. $return .= '<tr>';
  197. // course code
  198. $return .= ' <td width="157px" >'.cut($courseCode, 20, true).'</td>';
  199. // time spent in the course
  200. $return .= ' <td><div>'.api_time_to_hms(Tracking :: get_time_spent_on_the_course($user_id, $courseId)).'</div></td>';
  201. // student progress in course
  202. $return .= ' <td><div>'.round(Tracking :: get_avg_student_progress($user_id, $courseCode), 2).'</div></td>';
  203. // student score
  204. $avg_score = Tracking :: get_avg_student_score($user_id, $courseCode);
  205. if (is_numeric($avg_score)) {
  206. $avg_score = round($avg_score,2);
  207. } else {
  208. $$avg_score = '-';
  209. }
  210. $return .= ' <td><div>'.$avg_score.'</div></td>';
  211. // student tes score
  212. //$return .= ' <td><div style="width:40px">'.round(Tracking :: get_avg_student_exercise_score ($user_id, $courseCode),2).'%</div></td>';
  213. // student messages
  214. $return .= ' <td><div>'.Tracking :: count_student_messages($user_id, $courseCode).'</div></td>';
  215. // student assignments
  216. $return .= ' <td><div>'.Tracking :: count_student_assignments($user_id, $courseCode).'</div></td>';
  217. // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
  218. $exercises_results = MySpace::exercises_results($user_id, $courseCode);
  219. $return .= ' <td width="105px"><div>'.(is_null($exercises_results['percentage']) ? '' : $exercises_results['score_obtained'].'/'.$exercises_results['score_possible'].' ( '.$exercises_results['percentage'].'% )').'</div></td>';
  220. //$return .= ' <td><div>'.$exercises_results['score_possible'].'</div></td>';
  221. $return .= ' <td><div>'.$exercises_results['questions_answered'].'</div></td>';
  222. $return .= ' <td><div>'.Tracking :: get_last_connection_date_on_the_course($user_id, $courseInfo).'</div></td>';
  223. $return .= '<tr>';
  224. }
  225. $return .= '</table>';
  226. return $return;
  227. }
  228. /**
  229. * Display a sortable table that contains an overview off all the reporting progress of all users and all courses the user is subscribed to
  230. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  231. * @version Dokeos 1.8.6
  232. * @since October 2008
  233. */
  234. public static function display_tracking_user_overview()
  235. {
  236. MySpace::display_user_overview_export_options();
  237. $t_head = ' <table style="width: 100%;border:0;padding:0;border-collapse:collapse;table-layout: fixed">';
  238. //$t_head .= ' <caption>'.get_lang('CourseInformation').'</caption>';
  239. $t_head .= '<tr>';
  240. $t_head .= ' <th width="155px" style="border-left:0;border-bottom:0"><span>'.get_lang('Course').'</span></th>';
  241. $t_head .= ' <th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgTimeSpentInTheCourse'), 6, true).'</span></th>';
  242. $t_head .= ' <th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgStudentsProgress'), 6, true).'</span></th>';
  243. $t_head .= ' <th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgCourseScore'), 6, true).'</span></th>';
  244. //$t_head .= ' <th><div style="width:40px">'.get_lang('AvgExercisesScore').'</div></th>';
  245. $t_head .= ' <th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalNumberOfMessages'), 6, true).'</span></th>';
  246. $t_head .= ' <th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalNumberOfAssignments'), 6, true).'</span></th>';
  247. $t_head .= ' <th width="105px" style="border-bottom:0"><span>'.get_lang('TotalExercisesScoreObtained').'</span></th>';
  248. //$t_head .= ' <th><div>'.get_lang('TotalExercisesScorePossible').'</div></th>';
  249. $t_head .= ' <th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalExercisesAnswered'), 6, true).'</span></th>';
  250. //$t_head .= ' <th><div>'.get_lang('TotalExercisesScorePercentage').'</div></th>';
  251. //$t_head .= ' <th><div style="width:60px">'.get_lang('FirstLogin').'</div></th>';
  252. $t_head .= ' <th style="padding:0;border-bottom:0;border-right:0;"><span>'.get_lang('LatestLogin').'</span></th>';
  253. $t_head .= ' </tr></table>';
  254. $addparams = array('view' => 'admin', 'display' => 'user');
  255. $table = new SortableTable('tracking_user_overview', array('MySpace','get_number_of_users_tracking_overview'), array('MySpace','get_user_data_tracking_overview'), 0);
  256. $table->additional_parameters = $addparams;
  257. $table->set_header(0, get_lang('OfficialCode'), true, array('style' => 'font-size:8pt'), array('style' => 'font-size:8pt'));
  258. if (api_is_western_name_order()) {
  259. $table->set_header(1, get_lang('FirstName'), true, array('style' => 'font-size:8pt'), array('style' => 'font-size:8pt'));
  260. $table->set_header(2, get_lang('LastName'), true, array('style' => 'font-size:8pt'), array('style' => 'font-size:8pt'));
  261. } else {
  262. $table->set_header(1, get_lang('LastName'), true, array('style' => 'font-size:8pt'), array('style' => 'font-size:8pt'));
  263. $table->set_header(2, get_lang('FirstName'), true, array('style' => 'font-size:8pt'), array('style' => 'font-size:8pt'));
  264. }
  265. $table->set_header(3, get_lang('LoginName'), true, array('style' => 'font-size:8pt'), array('style' => 'font-size:8pt'));
  266. $table->set_header(4, $t_head, false, array('style' => 'width:90%;border:0;padding:0;font-size:7.5pt;'), array('style' => 'width:90%;padding:0;font-size:7.5pt;'));
  267. $table->set_column_filter(4, array('MySpace','course_info_tracking_filter'));
  268. $table->display();
  269. }
  270. public static function display_tracking_coach_overview($export_csv)
  271. {
  272. global $charset;
  273. if ($export_csv) {
  274. $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
  275. } else {
  276. $is_western_name_order = api_is_western_name_order();
  277. }
  278. $sort_by_first_name = api_sort_by_first_name();
  279. $tracking_column = isset($_GET['tracking_list_coaches_column']) ? $_GET['tracking_list_coaches_column'] : ($is_western_name_order xor $sort_by_first_name) ? 1 : 0;
  280. $tracking_direction = (isset($_GET['tracking_list_coaches_direction']) && in_array(strtoupper($_GET['tracking_list_coaches_direction']), array('ASC', 'DESC', 'ASCENDING', 'DESCENDING', '0', '1'))) ? $_GET['tracking_list_coaches_direction'] : 'DESC';
  281. // Prepare array for column order - when impossible, use some of user names.
  282. if ($is_western_name_order) {
  283. $order = array(0 => 'firstname', 1 => 'lastname', 2 => ($sort_by_first_name ? 'firstname' : 'lastname'), 3 => 'login_date', 4 => ($sort_by_first_name ? 'firstname' : 'lastname'), 5 => ($sort_by_first_name ? 'firstname' : 'lastname'));
  284. } else {
  285. $order = array(0 => 'lastname', 1 => 'firstname', 2 => ($sort_by_first_name ? 'firstname' : 'lastname'), 3 => 'login_date', 4 => ($sort_by_first_name ? 'firstname' : 'lastname'), 5 => ($sort_by_first_name ? 'firstname' : 'lastname'));
  286. }
  287. $table = new SortableTable(
  288. 'tracking_list_coaches_myspace',
  289. array('MySpace', 'count_coaches'),
  290. null,
  291. ($is_western_name_order xor $sort_by_first_name) ? 1 : 0
  292. );
  293. $parameters['view'] = 'admin';
  294. $table->set_additional_parameters($parameters);
  295. if ($is_western_name_order) {
  296. $table -> set_header(0, get_lang('FirstName'), true);
  297. $table -> set_header(1, get_lang('LastName'), true);
  298. } else {
  299. $table -> set_header(0, get_lang('LastName'), true);
  300. $table -> set_header(1, get_lang('FirstName'), true);
  301. }
  302. $table -> set_header(2, get_lang('TimeSpentOnThePlatform'), false);
  303. $table -> set_header(3, get_lang('LastConnexion'), false);
  304. $table -> set_header(4, get_lang('NbStudents'), false);
  305. $table -> set_header(5, get_lang('CountCours'), false);
  306. $table -> set_header(6, get_lang('NumberOfSessions'), false);
  307. $table -> set_header(7, get_lang('Sessions'), false);
  308. if ($is_western_name_order) {
  309. $csv_header[] = array (
  310. get_lang('FirstName', ''),
  311. get_lang('LastName', ''),
  312. get_lang('TimeSpentOnThePlatform', ''),
  313. get_lang('LastConnexion', ''),
  314. get_lang('NbStudents', ''),
  315. get_lang('CountCours', ''),
  316. get_lang('NumberOfSessions', '')
  317. );
  318. } else {
  319. $csv_header[] = array (
  320. get_lang('LastName', ''),
  321. get_lang('FirstName', ''),
  322. get_lang('TimeSpentOnThePlatform', ''),
  323. get_lang('LastConnexion', ''),
  324. get_lang('NbStudents', ''),
  325. get_lang('CountCours', ''),
  326. get_lang('NumberOfSessions', '')
  327. );
  328. }
  329. $tbl_track_login = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
  330. $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
  331. $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  332. $tbl_sessions = Database::get_main_table(TABLE_MAIN_SESSION);
  333. $sqlCoachs = "SELECT DISTINCT
  334. scu.user_id as id_coach,
  335. u.id as user_id,
  336. lastname,
  337. firstname,
  338. MAX(login_date) as login_date
  339. FROM $tbl_user u, $tbl_session_course_user scu, $tbl_track_login
  340. WHERE
  341. scu.user_id = u.id AND scu.status=2 AND login_user_id=u.id
  342. GROUP BY user_id ";
  343. if (api_is_multiple_url_enabled()) {
  344. $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
  345. $access_url_id = api_get_current_access_url_id();
  346. if ($access_url_id != -1) {
  347. $sqlCoachs = "SELECT DISTINCT
  348. scu.user_id as id_coach,
  349. u.id as user_id,
  350. lastname,
  351. firstname,
  352. MAX(login_date) as login_date
  353. FROM $tbl_user u,
  354. $tbl_session_course_user scu,
  355. $tbl_track_login ,
  356. $tbl_session_rel_access_url session_rel_url
  357. WHERE
  358. scu.user_id = u.id AND
  359. scu.status = 2 AND
  360. login_user_id = u.id AND
  361. access_url_id = $access_url_id AND
  362. session_rel_url.session_id = scu.session_id
  363. GROUP BY u.id";
  364. }
  365. }
  366. if (!empty($order[$tracking_column])) {
  367. $sqlCoachs .= "ORDER BY ".$order[$tracking_column]." ".$tracking_direction;
  368. }
  369. $result_coaches = Database::query($sqlCoachs);
  370. $total_no_coaches = Database::num_rows($result_coaches);
  371. $global_coaches = array();
  372. while ($coach = Database::fetch_array($result_coaches)) {
  373. $global_coaches[$coach['user_id']] = $coach;
  374. }
  375. $sql_session_coach = 'SELECT session.id_coach, u.id as user_id, lastname, firstname, MAX(login_date) as login_date
  376. FROM '.$tbl_user.' u ,'.$tbl_sessions.' as session,'.$tbl_track_login.'
  377. WHERE id_coach = u.id AND login_user_id = u.id
  378. GROUP BY u.id
  379. ORDER BY login_date '.$tracking_direction;
  380. if (api_is_multiple_url_enabled()) {
  381. $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
  382. $access_url_id = api_get_current_access_url_id();
  383. if ($access_url_id != -1) {
  384. $sql_session_coach = 'SELECT session.id_coach, u.id as user_id, lastname, firstname, MAX(login_date) as login_date
  385. FROM '.$tbl_user.' u ,'.$tbl_sessions.' as session, '.$tbl_track_login.' , '.$tbl_session_rel_access_url.' as session_rel_url
  386. WHERE
  387. id_coach = u.id AND
  388. login_user_id = u.id AND
  389. access_url_id = '.$access_url_id.' AND
  390. session_rel_url.session_id = session.id
  391. GROUP BY u.id
  392. ORDER BY login_date '.$tracking_direction;
  393. }
  394. }
  395. $result_sessions_coach = Database::query($sql_session_coach);
  396. $total_no_coaches += Database::num_rows($result_sessions_coach);
  397. while ($coach = Database::fetch_array($result_sessions_coach)) {
  398. $global_coaches[$coach['user_id']] = $coach;
  399. }
  400. $all_datas = array();
  401. foreach ($global_coaches as $id_coach => $coaches) {
  402. $time_on_platform = api_time_to_hms(Tracking :: get_time_spent_on_the_platform($coaches['user_id']));
  403. $last_connection = Tracking :: get_last_connection_date($coaches['user_id']);
  404. $nb_students = count(Tracking :: get_student_followed_by_coach($coaches['user_id']));
  405. $nb_courses = count(Tracking :: get_courses_followed_by_coach($coaches['user_id']));
  406. $nb_sessions = count(Tracking :: get_sessions_coached_by_user($coaches['user_id']));
  407. $table_row = array();
  408. if ($is_western_name_order) {
  409. $table_row[] = $coaches['firstname'];
  410. $table_row[] = $coaches['lastname'];
  411. } else {
  412. $table_row[] = $coaches['lastname'];
  413. $table_row[] = $coaches['firstname'];
  414. }
  415. $table_row[] = $time_on_platform;
  416. $table_row[] = $last_connection;
  417. $table_row[] = $nb_students;
  418. $table_row[] = $nb_courses;
  419. $table_row[] = $nb_sessions;
  420. $table_row[] = '<a href="session.php?id_coach='.$coaches['user_id'].'">
  421. '.Display::return_icon('2rightarrow.png').'
  422. </a>';
  423. $all_datas[] = $table_row;
  424. if ($is_western_name_order) {
  425. $csv_content[] = array(
  426. api_html_entity_decode($coaches['firstname'], ENT_QUOTES),
  427. api_html_entity_decode($coaches['lastname'], ENT_QUOTES),
  428. $time_on_platform,
  429. $last_connection,
  430. $nb_students,
  431. $nb_courses,
  432. $nb_sessions
  433. );
  434. } else {
  435. $csv_content[] = array(
  436. api_html_entity_decode($coaches['lastname'], ENT_QUOTES),
  437. api_html_entity_decode($coaches['firstname'], ENT_QUOTES),
  438. $time_on_platform,
  439. $last_connection,
  440. $nb_students,
  441. $nb_courses,
  442. $nb_sessions
  443. );
  444. }
  445. }
  446. if ($tracking_column != 3) {
  447. if ($tracking_direction == 'DESC') {
  448. usort($all_datas, array('MySpace','rsort_users'));
  449. } else {
  450. usort($all_datas, array('MySpace','sort_users'));
  451. }
  452. }
  453. if ($export_csv && $tracking_column != 3) {
  454. usort($csv_content, 'sort_users');
  455. }
  456. if ($export_csv) {
  457. $csv_content = array_merge($csv_header, $csv_content);
  458. }
  459. foreach ($all_datas as $row) {
  460. $table -> addRow($row, 'align="right"');
  461. }
  462. $table -> display();
  463. }
  464. public static function count_coaches() {
  465. global $total_no_coaches;
  466. return $total_no_coaches;
  467. }
  468. public static function sort_users($a, $b) {
  469. return api_strcmp(trim(api_strtolower($a[$_SESSION['tracking_column']])), trim(api_strtolower($b[$_SESSION['tracking_column']])));
  470. }
  471. public static function rsort_users($a, $b) {
  472. return api_strcmp(trim(api_strtolower($b[$_SESSION['tracking_column']])), trim(api_strtolower($a[$_SESSION['tracking_column']])));
  473. }
  474. /**
  475. * Display a sortable table that contains an overview off all the progress of the user in a session
  476. * @author César Perales <cesar.perales@beeznest.com>, Beeznest Team
  477. */
  478. public static function display_tracking_lp_progress_overview($sessionId = '', $courseId = '', $date_from, $date_to)
  479. {
  480. $course = api_get_course_info_by_id($courseId);
  481. /**
  482. * Column name
  483. * The order is important you need to check the $column variable in the model.ajax.php file
  484. */
  485. $columns = array(
  486. get_lang('Username'),
  487. get_lang('FirstName'),
  488. get_lang('LastName'),
  489. );
  490. //add lessons of course
  491. $lessons = LearnpathList::get_course_lessons($course['code'], $sessionId);
  492. //create columns array
  493. foreach ($lessons as $lesson_id => $lesson) {
  494. $columns[] = $lesson['name'];
  495. }
  496. $columns[] = get_lang('Total');
  497. /**
  498. * Column config
  499. */
  500. $column_model = array(
  501. array(
  502. 'name' => 'username',
  503. 'index' => 'username',
  504. 'align' => 'left',
  505. 'search' => 'true',
  506. 'wrap_cell' => "true",
  507. ),
  508. array(
  509. 'name' => 'firstname',
  510. 'index' => 'firstname',
  511. 'align' => 'left',
  512. 'search' => 'true',
  513. ),
  514. array(
  515. 'name' => 'lastname',
  516. 'index' => 'lastname',
  517. 'align' => 'left',
  518. 'search' => 'true',
  519. ),
  520. );
  521. // Get dinamic column names
  522. foreach ($lessons as $lesson_id => $lesson) {
  523. $column_model[] = array(
  524. 'name' => $lesson['id'],
  525. 'index' => $lesson['id'],
  526. 'align' => 'left',
  527. 'search' => 'true',
  528. );
  529. }
  530. $column_model[] = array(
  531. 'name' => 'total',
  532. 'index' => 'total',
  533. 'align' => 'left',
  534. 'search' => 'true',
  535. );
  536. $action_links = '';
  537. // jqgrid will use this URL to do the selects
  538. $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_session_lp_progress&session_id=' . $sessionId . '&course_id=' . $courseId . '&date_to=' . $date_to . '&date_from=' . $date_from;
  539. //Table Id
  540. $tableId = 'lpProgress';
  541. //Autowidth
  542. $extra_params['autowidth'] = 'true';
  543. //height auto
  544. $extra_params['height'] = 'auto';
  545. $table = Display::grid_js(
  546. $tableId,
  547. $url,
  548. $columns,
  549. $column_model,
  550. $extra_params,
  551. array(),
  552. $action_links,
  553. true
  554. );
  555. $return = '<script>$(function() {'. $table .
  556. 'jQuery("#'.$tableId.'").jqGrid("navGrid","#'.$tableId.'_pager",{view:false, edit:false, add:false, del:false, search:false, excel:true});
  557. jQuery("#'.$tableId.'").jqGrid("navButtonAdd","#'.$tableId.'_pager",{
  558. caption:"",
  559. title:"' . get_lang('ExportExcel') . '",
  560. onClickButton : function () {
  561. jQuery("#'.$tableId.'").jqGrid("excelExport",{"url":"'.$url.'&export_format=xls"});
  562. }
  563. });
  564. });</script>';
  565. $return .= Display::grid_html($tableId);
  566. return $return;
  567. }
  568. /**
  569. * Display a sortable table that contains an overview off all the progress of the user in a session
  570. * @param int $sessionId The session ID
  571. * @param int $courseId The course ID
  572. * @param int $exerciseId The quiz ID
  573. * @param int $answer Answer status (0 = incorrect, 1 = correct, 2 = both)
  574. * @return string HTML array of results formatted for gridJS
  575. * @author César Perales <cesar.perales@beeznest.com>, Beeznest Team
  576. */
  577. static function display_tracking_exercise_progress_overview(
  578. $sessionId = 0,
  579. $courseId = 0,
  580. $exerciseId = 0,
  581. $date_from = null,
  582. $date_to = null
  583. ) {
  584. $date_from = Security::remove_XSS($date_from);
  585. $date_to = Security::remove_XSS($date_to);
  586. /**
  587. * Column names
  588. * The column order is important. Check $column variable in the main/inc/ajax/model.ajax.php file
  589. */
  590. $columns = array(
  591. get_lang('Session'),
  592. get_lang('ExerciseId'),
  593. get_lang('ExerciseName'),
  594. get_lang('Username'),
  595. get_lang('LastName'),
  596. get_lang('FirstName'),
  597. get_lang('Time'),
  598. get_lang('QuestionId'),
  599. get_lang('QuestionTitle'),
  600. get_lang('WorkDescription'),
  601. get_lang('Answer'),
  602. get_lang('Correct'),
  603. );
  604. /**
  605. * Column config
  606. */
  607. $column_model = array(
  608. array('name'=>'session', 'index'=>'session', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
  609. array('name'=>'exercise_id', 'index'=>'exercise_id', 'align'=>'left', 'search' => 'true'),
  610. array('name'=>'quiz_title', 'index'=>'quiz_title', 'align'=>'left', 'search' => 'true'),
  611. array('name'=>'username', 'index'=>'username', 'align'=>'left', 'search' => 'true'),
  612. array('name'=>'lastname', 'index'=>'lastname', 'align'=>'left', 'search' => 'true'),
  613. array('name'=>'firstname', 'index'=>'firstname', 'align'=>'left', 'search' => 'true'),
  614. array('name'=>'time', 'index'=>'time', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
  615. array('name'=>'question_id', 'index'=>'question_id', 'align'=>'left', 'search' => 'true'),
  616. array('name'=>'question', 'index'=>'question', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
  617. array('name'=>'description', 'index'=>'description', 'align'=>'left', 'width' => '550', 'search' => 'true', 'wrap_cell' => "true"),
  618. array('name'=>'answer', 'index'=>'answer', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
  619. array('name'=>'correct', 'index'=>'correct', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
  620. );
  621. //get dynamic column names
  622. // jqgrid will use this URL to do the selects
  623. $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_exercise_progress&session_id=' . $sessionId . '&course_id=' . $courseId . '&exercise_id=' . $exerciseId . '&date_to=' . $date_to . '&date_from=' . $date_from;
  624. // Autowidth
  625. $extra_params['autowidth'] = 'true';
  626. // height auto
  627. $extra_params['height'] = 'auto';
  628. $tableId = 'exerciseProgressOverview';
  629. $table = Display::grid_js($tableId, $url, $columns, $column_model, $extra_params, array(), '', true);
  630. $return = '<script>$(function() {'. $table .
  631. 'jQuery("#'.$tableId.'").jqGrid("navGrid","#'.$tableId.'_pager",{view:false, edit:false, add:false, del:false, search:false, excel:true});
  632. jQuery("#'.$tableId.'").jqGrid("navButtonAdd","#'.$tableId.'_pager",{
  633. caption:"",
  634. title:"' . get_lang('ExportExcel') . '",
  635. onClickButton : function () {
  636. jQuery("#'.$tableId.'").jqGrid("excelExport",{"url":"'.$url.'&export_format=xls"});
  637. }
  638. });
  639. });</script>';
  640. $return .= Display::grid_html($tableId);
  641. return $return;
  642. }
  643. /**
  644. * Display a sortable table that contains an overview off all the progress of the user in a session
  645. * @param int $sessionId The session ID
  646. * @param int $courseId The course ID
  647. * @param null $date_from
  648. * @param null $date_to
  649. * @internal param int $exerciseId The quiz ID
  650. * @internal param int $answer Answer status (0 = incorrect, 1 = correct, 2 = both)
  651. * @return string HTML array of results formatted for gridJS
  652. * @author Francis Gonzales <francis.gonzales@beeznest.com>, Beeznest Team
  653. */
  654. static function display_tracking_grade_overview($sessionId = 0, $courseId = 0, $date_from = null, $date_to = null)
  655. {
  656. /**
  657. * Column names
  658. * The column order is important. Check $column variable in the main/inc/ajax/model.ajax.php file
  659. */
  660. $objExercise = new Exercise();
  661. $exercises = $objExercise->getExercisesByCouseSession($courseId, $sessionId);
  662. $cntExer = 4;
  663. if (!empty($exercises)) {
  664. $cntExer += count($exercises);
  665. }
  666. $column = array();
  667. $column_model = array();
  668. $i = 1;
  669. //Get dynamic column names
  670. foreach (range(1, $cntExer) as $cnt) {
  671. switch ($cnt) {
  672. case 1:
  673. $column[] = get_lang('Section');
  674. $column_model[] = array(
  675. 'name' => 'session',
  676. 'index' => 'session',
  677. 'align' => 'center',
  678. 'search' => 'true',
  679. );
  680. break;
  681. case 2:
  682. $column[] = get_lang('Username');
  683. $column_model[] = array(
  684. 'name' => 'username',
  685. 'index' => 'username',
  686. 'align' => 'center',
  687. 'search' => 'true',
  688. );
  689. break;
  690. case 3:
  691. $column[] = get_lang('FirstName');
  692. $column_model[] = array(
  693. 'name' => 'name',
  694. 'index' => 'name',
  695. 'align' => 'left',
  696. 'search' => 'true',
  697. );
  698. break;
  699. case $cntExer:
  700. $column[] = get_lang('FinalScore');
  701. $column_model[] = array(
  702. 'name' => 'finalscore',
  703. 'index' => 'finalscore',
  704. 'align' => 'center',
  705. 'search' => 'true',
  706. 'wrap_cell' => "true"
  707. );
  708. break;
  709. default:
  710. $title = "";
  711. if (!empty($exercises[$cnt - 4]['title'])) {
  712. $title = ucwords(strtolower(trim($exercises[$cnt - 4]['title'])));
  713. }
  714. $column[] = $title;
  715. $column_model[] = array(
  716. 'name' => 'exer' . $i,
  717. 'index' => 'exer' . $i,
  718. 'align' => 'center',
  719. 'search' => 'true',
  720. 'wrap_cell' => "true"
  721. );
  722. $i++;
  723. break;
  724. }
  725. }
  726. //end get dynamic column names
  727. // jqgrid will use this URL to do the selects
  728. $url = api_get_path(WEB_AJAX_PATH) . 'model.ajax.php?a=get_exercise_grade&session_id=' . $sessionId . '&course_id=' . $courseId;
  729. // Autowidth
  730. $extra_params['autowidth'] = 'true';
  731. // height auto
  732. $extra_params['height'] = 'auto';
  733. $tableId = 'exerciseGradeOverview';
  734. $table = Display::grid_js($tableId, $url, $column, $column_model, $extra_params, array(), '', true);
  735. $return = '<script>$(function() {' . $table .
  736. 'jQuery("#' . $tableId . '").jqGrid("navGrid","#' . $tableId . '_pager",{view:false, edit:false, add:false, del:false, search:false, excel:true});
  737. jQuery("#' . $tableId . '").jqGrid("navButtonAdd","#' . $tableId . '_pager",{
  738. caption:"",
  739. title:"' . get_lang('ExportExcel') . '",
  740. onClickButton : function () {
  741. jQuery("#' . $tableId . '").jqGrid("excelExport",{"url":"' . $url . '&export_format=xls"});
  742. }
  743. });
  744. });</script>';
  745. $return .= Display::grid_html($tableId);
  746. return $return;
  747. }
  748. /**
  749. * Display a sortable table that contains an overview off all the progress of the user in a session
  750. * @author César Perales <cesar.perales@beeznest.com>, Beeznest Team
  751. */
  752. function display_survey_overview($sessionId = 0, $courseId = 0, $surveyId = 0, $date_from, $date_to)
  753. {
  754. /**
  755. * Column name
  756. * The order is important you need to check the $column variable in the model.ajax.php file
  757. */
  758. $columns = array(
  759. get_lang('Username'),
  760. get_lang('FirstName'),
  761. get_lang('LastName'),
  762. );
  763. //add lessons of course
  764. $questions = SurveyManager::get_questions($surveyId, $courseId);
  765. foreach ($questions as $question) {
  766. $columns[] = $question['question'];
  767. }
  768. /**
  769. * Column config
  770. */
  771. $column_model = array(
  772. array('name'=>'username', 'index'=>'username', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
  773. array('name'=>'firstname', 'index'=>'firstname', 'align'=>'left', 'search' => 'true'),
  774. array('name'=>'lastname', 'index'=>'lastname', 'align'=>'left', 'search' => 'true'),
  775. );
  776. //get dinamic column names
  777. foreach ($questions as $question_id => $question) {
  778. $column_model[] = array(
  779. 'name'=> $question_id,
  780. 'index'=>$question_id,
  781. 'width'=>'70',
  782. 'align'=>'left',
  783. 'search' => 'true'
  784. );
  785. }
  786. $action_links = '';
  787. // jqgrid will use this URL to do the selects
  788. $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_survey_overview&session_id=' . $sessionId . '&course_id=' . $courseId . '&survey_id=' . $surveyId . '&date_to=' . $date_to . '&date_from=' . $date_from;
  789. // Table Id
  790. $tableId = 'lpProgress';
  791. //Autowidth
  792. $extra_params['autowidth'] = 'true';
  793. // height auto
  794. $extra_params['height'] = 'auto';
  795. $table = Display::grid_js(
  796. $tableId,
  797. $url,
  798. $columns,
  799. $column_model,
  800. $extra_params,
  801. array(),
  802. $action_links,
  803. true
  804. );
  805. $return = '<script>$(function() {'. $table .
  806. 'jQuery("#'.$tableId.'").jqGrid("navGrid","#'.$tableId.'_pager",{view:false, edit:false, add:false, del:false, search:false, excel:true});
  807. jQuery("#'.$tableId.'").jqGrid("navButtonAdd","#'.$tableId.'_pager",{
  808. caption:"",
  809. title:"' . get_lang('ExportExcel') . '",
  810. onClickButton : function () {
  811. jQuery("#'.$tableId.'").jqGrid("excelExport",{"url":"'.$url.'&export_format=xls"});
  812. }
  813. });
  814. });</script>';
  815. $return .= Display::grid_html($tableId);
  816. return $return;
  817. }
  818. /**
  819. * Display a sortable table that contains an overview off all the progress of the user in a session
  820. * @author César Perales <cesar.perales@beeznest.com>, Beeznest Team
  821. */
  822. static function display_tracking_progress_overview($sessionId = 0, $courseId = 0, $date_from, $date_to)
  823. {
  824. //The order is important you need to check the the $column variable in the model.ajax.php file
  825. $columns = array(
  826. get_lang('LastName'),
  827. get_lang('FirstName'),
  828. get_lang('Username'),
  829. #get_lang('Profile'),
  830. get_lang('Total'),
  831. get_lang('Courses'),
  832. get_lang('LearningPaths'),
  833. get_lang('Exercises'),
  834. get_lang('Forums'),
  835. get_lang('Assignments'),
  836. get_lang('ToolWiki'),
  837. get_lang('ToolSurvey'),
  838. //Learning paths
  839. get_lang('LearnpathsTotal'),
  840. get_lang('LearnpathsDone'),
  841. get_lang('LearnpathsLeft'),
  842. get_lang('LearnpathsProgress'),
  843. //Exercises
  844. get_lang('ExercisesTotal'),
  845. get_lang('ExercisesDone'),
  846. get_lang('ExercisesLeft'),
  847. get_lang('ExercisesProgress'),
  848. //Forums
  849. get_lang('ForumsTotal'),
  850. get_lang('ForumsDone'),
  851. get_lang('ForumsLeft'),
  852. get_lang('ForumsProgress'),
  853. //Assignments
  854. get_lang('AssignmentsTotal'),
  855. get_lang('AssignmentsDone'),
  856. get_lang('AssignmentsLeft'),
  857. get_lang('AssignmentsProgress'),
  858. //Wiki
  859. get_lang('WikiTotal'),
  860. get_lang('WikiRevisions'),
  861. get_lang('WikiRead'),
  862. get_lang('WikiUnread'),
  863. get_lang('WikiProgress'),
  864. //Surveys
  865. get_lang('SurveysTotal'),
  866. get_lang('SurveysDone'),
  867. get_lang('SurveysLeft'),
  868. get_lang('SurveysProgress'),
  869. );
  870. //Column config
  871. $column_model = array(
  872. array('name'=>'lastname', 'index'=>'lastname', 'align'=>'left'),
  873. array('name'=>'firstname', 'index'=>'firstname', 'align'=>'left'),
  874. array('name'=>'username', 'index'=>'username', 'align'=>'left'),
  875. #array('name'=>'profile', 'index'=>'username', 'align'=>'left'),
  876. array('name'=>'total', 'index'=>'total', 'align'=>'left'),
  877. array('name'=>'courses', 'index'=>'courses', 'align'=>'left', 'sortable' => 'false'),
  878. array('name'=>'lessons', 'index'=>'lessons', 'align'=>'left', 'sortable' => 'false'),
  879. array('name'=>'exercises', 'index'=>'exercises', 'align'=>'left', 'sortable' => 'false'),
  880. array('name'=>'forums', 'index'=>'forums', 'align'=>'left', 'sortable' => 'false'),
  881. array('name'=>'homeworks', 'index'=>'homeworks', 'align'=>'left', 'sortable' => 'false'),
  882. array('name'=>'wikis', 'index'=>'wikis', 'align'=>'left', 'sortable' => 'false'),
  883. array('name'=>'surveys', 'index'=>'surveys', 'align'=>'left', 'sortable' => 'false'),
  884. //Lessons
  885. array('name'=>'lessons_total', 'index'=>'lessons_total', 'align'=>'center', 'sortable' => 'false'),
  886. array('name'=>'lessons_done', 'index'=>'lessons_done', 'align'=>'center', 'sortable' => 'false'),
  887. array('name'=>'lessons_left', 'index'=>'lessons_left', 'align'=>'center', 'sortable' => 'false'),
  888. array('name'=>'lessons_progress', 'index'=>'lessons_progress', 'align'=>'center', 'sortable' => 'false'),
  889. //Exercises
  890. array('name'=>'exercises_total', 'index'=>'exercises_total', 'align'=>'center', 'sortable' => 'false'),
  891. array('name'=>'exercises_done', 'index'=>'exercises_done', 'align'=>'center', 'sortable' => 'false'),
  892. array('name'=>'exercises_left', 'index'=>'exercises_left', 'align'=>'center', 'sortable' => 'false'),
  893. array('name'=>'exercises_progress', 'index'=>'exercises_progress', 'align'=>'center', 'sortable' => 'false'),
  894. //Assignments
  895. array('name'=>'forums_total', 'index'=>'forums_total', 'align'=>'center', 'sortable' => 'false'),
  896. array('name'=>'forums_done', 'index'=>'forums_done', 'align'=>'center', 'sortable' => 'false'),
  897. array('name'=>'forums_left', 'index'=>'forums_left', 'align'=>'center', 'sortable' => 'false'),
  898. array('name'=>'forums_progress', 'index'=>'forums_progress', 'align'=>'center', 'sortable' => 'false'),
  899. //Assignments
  900. array('name'=>'assigments_total', 'index'=>'assigments_total', 'align'=>'center', 'sortable' => 'false'),
  901. array('name'=>'assigments_done', 'index'=>'assigments_done', 'align'=>'center', 'sortable' => 'false'),
  902. array('name'=>'assigments_left', 'index'=>'assigments_left', 'align'=>'center', 'sortable' => 'false'),
  903. array('name'=>'assigments_progress', 'index'=>'assigments_progress', 'align'=>'center', 'sortable' => 'false'),
  904. //Assignments
  905. array('name'=>'wiki_total', 'index'=>'wiki_total', 'align'=>'center', 'sortable' => 'false'),
  906. array('name'=>'wiki_revisions', 'index'=>'wiki_revisions', 'align'=>'center', 'sortable' => 'false'),
  907. array('name'=>'wiki_read', 'index'=>'wiki_read', 'align'=>'center', 'sortable' => 'false'),
  908. array('name'=>'wiki_unread', 'index'=>'wiki_unread', 'align'=>'center', 'sortable' => 'false'),
  909. array('name'=>'wiki_progress', 'index'=>'wiki_progress', 'align'=>'center', 'sortable' => 'false'),
  910. //Surveys
  911. array('name'=>'surveys_total', 'index'=>'surveys_total', 'align'=>'center', 'sortable' => 'false'),
  912. array('name'=>'surveys_done', 'index'=>'surveys_done', 'align'=>'center', 'sortable' => 'false'),
  913. array('name'=>'surveys_left', 'index'=>'surveys_left', 'align'=>'center', 'sortable' => 'false'),
  914. array('name'=>'surveys_progress', 'index'=>'surveys_progress', 'align'=>'center', 'sortable' => 'false'),
  915. );
  916. $action_links = '';
  917. // jqgrid will use this URL to do the selects
  918. $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_session_progress&session_id=' . $sessionId . '&course_id=' . $courseId . '&date_to=' . $date_to . '&date_from=' . $date_from;
  919. //Table Id
  920. $tableId = 'progressOverview';
  921. //Autowidth
  922. $extra_params['autowidth'] = 'true';
  923. $extra_params['shrinkToFit'] = 'true';
  924. $extra_params['headertitles'] = 'true';
  925. $extra_params['groupHeaders'] = array(
  926. 'courses_detail' => array(
  927. "startColumnName" => 'courses',
  928. "numberOfColumns" => 7,
  929. "titleText" => get_lang('Global'),
  930. ),
  931. 'lessons' => array(
  932. "startColumnName" => 'lessons_total',
  933. "numberOfColumns" => 4,
  934. "titleText" => get_lang('LearningPaths'),
  935. ),
  936. 'exercises' => array(
  937. "startColumnName" => 'exercises_total',
  938. "numberOfColumns" => 4,
  939. "titleText" => get_lang('Exercises'),
  940. ),
  941. 'forums' => array(
  942. "startColumnName" => 'forums_total',
  943. "numberOfColumns" => 4,
  944. "titleText" => get_lang('Forums'),
  945. ),
  946. 'assignments' => array(
  947. "startColumnName" => 'assigments_total',
  948. "numberOfColumns" => 4,
  949. "titleText" => get_lang('Assignments'),
  950. ),
  951. 'wikis' => array(
  952. "startColumnName" => 'wiki_total',
  953. "numberOfColumns" => 5,
  954. "titleText" => get_lang('Wiki'),
  955. ),
  956. 'surveys' => array(
  957. "startColumnName" => 'surveys_total',
  958. "numberOfColumns" => 4,
  959. "titleText" => get_lang('Survey'),
  960. ),
  961. );
  962. //height auto
  963. $extra_params['height'] = 'auto';
  964. $table = Display::grid_js(
  965. $tableId,
  966. $url,
  967. $columns,
  968. $column_model,
  969. $extra_params,
  970. array(),
  971. $action_links,
  972. true
  973. );
  974. $return = '<script>$(function() {'. $table .
  975. 'jQuery("#'.$tableId.'").jqGrid("navGrid","#'.$tableId.'_pager",{view:false, edit:false, add:false, del:false, search:false, excel:true});
  976. jQuery("#'.$tableId.'").jqGrid("navButtonAdd","#'.$tableId.'_pager",{
  977. caption:"",
  978. title:"' . get_lang('ExportExcel') . '",
  979. onClickButton : function () {
  980. jQuery("#'.$tableId.'").jqGrid("excelExport",{"url":"'.$url.'&export_format=xls"});
  981. }
  982. });
  983. });</script>';
  984. $return .= Display::grid_html($tableId);
  985. return $return;
  986. }
  987. /**
  988. * Displays a form with all the additionally defined user fields of the profile
  989. * and give you the opportunity to include these in the CSV export
  990. *
  991. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  992. * @version 1.8.6
  993. * @since November 2008
  994. */
  995. public static function display_user_overview_export_options()
  996. {
  997. $message = '';
  998. // include the user manager and formvalidator library
  999. if (isset($_GET['export']) && $_GET['export'] == 'options') {
  1000. // get all the defined extra fields
  1001. $extrafields = UserManager::get_extra_fields(0, 50, 5, 'ASC', false, 1);
  1002. // creating the form with all the defined extra fields
  1003. $form = new FormValidator(
  1004. 'exportextrafields',
  1005. 'post',
  1006. api_get_self()."?view=".Security::remove_XSS($_GET['view']).'&display='.Security::remove_XSS($_GET['display']).'&export='.Security::remove_XSS($_GET['export'])
  1007. );
  1008. if (is_array($extrafields) && count($extrafields) > 0) {
  1009. foreach ($extrafields as $key => $extra) {
  1010. $form->addElement('checkbox', 'extra_export_field'.$extra[0], '', $extra[3]);
  1011. }
  1012. $form->addButtonSave(get_lang('Ok'), 'submit');
  1013. // setting the default values for the form that contains all the extra fields
  1014. if (is_array($_SESSION['additional_export_fields'])) {
  1015. foreach ($_SESSION['additional_export_fields'] as $key => $value) {
  1016. $defaults['extra_export_field'.$value] = 1;
  1017. }
  1018. }
  1019. $form->setDefaults($defaults);
  1020. } else {
  1021. $form->addElement('html', Display::display_warning_message(get_lang('ThereAreNotExtrafieldsAvailable')));
  1022. }
  1023. if ($form->validate()) {
  1024. // exporting the form values
  1025. $values = $form->exportValues();
  1026. // re-initialising the session that contains the additional fields that need to be exported
  1027. $_SESSION['additional_export_fields'] = array();
  1028. // adding the fields that are checked to the session
  1029. $message = '';
  1030. foreach ($values as $field_ids => $value) {
  1031. if ($value == 1 && strstr($field_ids,'extra_export_field')) {
  1032. $_SESSION['additional_export_fields'][] = str_replace('extra_export_field', '', $field_ids);
  1033. }
  1034. }
  1035. // adding the fields that will be also exported to a message string
  1036. if (is_array($_SESSION['additional_export_fields'])) {
  1037. foreach ($_SESSION['additional_export_fields'] as $key => $extra_field_export) {
  1038. $message .= '<li>'.$extrafields[$extra_field_export][3].'</li>';
  1039. }
  1040. }
  1041. // Displaying a feedback message
  1042. if (!empty($_SESSION['additional_export_fields'])) {
  1043. Display::display_confirmation_message(get_lang('FollowingFieldsWillAlsoBeExported').': <br /><ul>'.$message.'</ul>', false);
  1044. } else {
  1045. Display::display_confirmation_message(get_lang('NoAdditionalFieldsWillBeExported'), false);
  1046. }
  1047. } else {
  1048. $form->display();
  1049. }
  1050. } else {
  1051. if (!empty($_SESSION['additional_export_fields'])) {
  1052. // get all the defined extra fields
  1053. $extrafields = UserManager::get_extra_fields(0, 50, 5, 'ASC');
  1054. foreach ($_SESSION['additional_export_fields'] as $key => $extra_field_export) {
  1055. $message .= '<li>'.$extrafields[$extra_field_export][3].'</li>';
  1056. }
  1057. Display::display_normal_message(get_lang('FollowingFieldsWillAlsoBeExported').': <br /><ul>'.$message.'</ul>', false);
  1058. }
  1059. }
  1060. }
  1061. /**
  1062. * Display a sortable table that contains an overview of all the reporting progress of all courses
  1063. */
  1064. public static function display_tracking_course_overview()
  1065. {
  1066. $t_head = ' <table style="width: 100%;border:0;padding:0;border-collapse:collapse;table-layout: fixed">';
  1067. //$t_head .= ' <caption>'.get_lang('CourseInformation').'</caption>';
  1068. $t_head .= '<tr>';
  1069. $t_head .= ' <th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgTimeSpentInTheCourse'), 6, true).'</span></th>';
  1070. $t_head .= ' <th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgStudentsProgress'), 6, true).'</span></th>';
  1071. $t_head .= ' <th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgCourseScore'), 6, true).'</span></th>';
  1072. //$t_head .= ' <th><div style="width:40px">'.get_lang('AvgExercisesScore').'</div></th>';
  1073. $t_head .= ' <th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalNumberOfMessages'), 6, true).'</span></th>';
  1074. $t_head .= ' <th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalNumberOfAssignments'), 6, true).'</span></th>';
  1075. $t_head .= ' <th width="105px" style="border-bottom:0"><span>'.get_lang('TotalExercisesScoreObtained').'</span></th>';
  1076. //$t_head .= ' <th><div>'.get_lang('TotalExercisesScorePossible').'</div></th>';
  1077. $t_head .= ' <th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalExercisesAnswered'), 6, true).'</span></th>';
  1078. //$t_head .= ' <th><div>'.get_lang('TotalExercisesScorePercentage').'</div></th>';
  1079. //$t_head .= ' <th><div style="width:60px">'.get_lang('FirstLogin').'</div></th>';
  1080. $t_head .= ' <th style="padding:0;border-bottom:0;border-right:0;"><span>'.get_lang('LatestLogin').'</span></th>';
  1081. $t_head .= ' </tr></table>';
  1082. $addparams = array('view' => 'admin', 'display' => 'courseoverview');
  1083. $table = new SortableTable('tracking_session_overview', array('MySpace', 'get_total_number_courses'), array('MySpace','get_course_data_tracking_overview'), 1);
  1084. $table->additional_parameters = $addparams;
  1085. $table->set_header(0, '', false, null, array('style' => 'display: none'));
  1086. $table->set_header(1, get_lang('Course'), true, array('style' => 'font-size:8pt'), array('style' => 'font-size:8pt'));
  1087. $table->set_header(2, $t_head, false, array('style' => 'width:90%;border:0;padding:0;font-size:7.5pt;'), array('style' => 'width:90%;padding:0;font-size:7.5pt;'));
  1088. $table->set_column_filter(2, array('MySpace','course_tracking_filter'));
  1089. $table->display();
  1090. }
  1091. /**
  1092. * Get the total number of courses
  1093. *
  1094. * @return integer Total number of courses
  1095. */
  1096. public static function get_total_number_courses()
  1097. {
  1098. // database table definition
  1099. $main_course_table = Database :: get_main_table(TABLE_MAIN_COURSE);
  1100. return Database::count_rows($main_course_table);
  1101. }
  1102. /**
  1103. * Get data for the courses
  1104. *
  1105. * @param int Inferior limit
  1106. * @param int Number of items to select
  1107. * @param string Column to order on
  1108. * @param string Order direction
  1109. * @return array Results
  1110. */
  1111. public static function get_course_data_tracking_overview($from, $number_of_items, $column, $direction)
  1112. {
  1113. $main_course_table = Database :: get_main_table(TABLE_MAIN_COURSE);
  1114. $from = intval($from);
  1115. $number_of_items = intval($number_of_items);
  1116. $sql = "SELECT code AS col0, title AS col1 FROM $main_course_table";
  1117. $sql .= " ORDER BY col$column $direction ";
  1118. $sql .= " LIMIT $from,$number_of_items";
  1119. $result = Database::query($sql);
  1120. $return = array ();
  1121. while ($course = Database::fetch_row($result)) {
  1122. $return[] = $course;
  1123. }
  1124. return $return;
  1125. }
  1126. /**
  1127. * Fills in course reporting data
  1128. *
  1129. * @param integer course code
  1130. * @param array $url_params additional url parameters
  1131. * @param array $row the row information (the other columns)
  1132. * @return string html code
  1133. */
  1134. public static function course_tracking_filter($course_code, $url_params, $row)
  1135. {
  1136. $course_code = $row[0];
  1137. $courseInfo = api_get_course_info($course_code);
  1138. $courseId = $courseInfo['real_id'];
  1139. // the table header
  1140. $return = '<table class="data_table" style="width: 100%;border:0;padding:0;border-collapse:collapse;table-layout: fixed">';
  1141. // database table definition
  1142. $tbl_course_rel_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  1143. $tbl_user = Database :: get_main_table(TABLE_MAIN_USER);
  1144. // getting all the courses of the user
  1145. $sql = "SELECT *
  1146. FROM $tbl_user AS u
  1147. INNER JOIN $tbl_course_rel_user AS cu
  1148. ON cu.user_id = u.user_id
  1149. WHERE cu.c_id = '".$courseId."'";
  1150. $result = Database::query($sql);
  1151. $time_spent = 0;
  1152. $progress = 0;
  1153. $nb_progress_lp = 0;
  1154. $score = 0;
  1155. $nb_score_lp = 0;
  1156. $nb_messages = 0;
  1157. $nb_assignments = 0;
  1158. $last_login_date = false;
  1159. $total_score_obtained = 0;
  1160. $total_score_possible = 0;
  1161. $total_questions_answered = 0;
  1162. while ($row = Database::fetch_object($result)) {
  1163. // get time spent in the course and session
  1164. $time_spent += Tracking::get_time_spent_on_the_course($row->user_id, $courseInfo['real_id']);
  1165. $progress_tmp = Tracking::get_avg_student_progress($row->user_id, $course_code, array(), null, true);
  1166. $progress += $progress_tmp[0];
  1167. $nb_progress_lp += $progress_tmp[1];
  1168. $score_tmp = Tracking :: get_avg_student_score($row->user_id, $course_code, array(), null, true);
  1169. if(is_array($score_tmp)) {
  1170. $score += $score_tmp[0];
  1171. $nb_score_lp += $score_tmp[1];
  1172. }
  1173. $nb_messages += Tracking::count_student_messages($row->user_id, $course_code);
  1174. $nb_assignments += Tracking::count_student_assignments($row->user_id, $course_code);
  1175. $last_login_date_tmp = Tracking :: get_last_connection_date_on_the_course($row->user_id, $courseInfo, null, false);
  1176. if($last_login_date_tmp != false && $last_login_date == false) { // TODO: To be cleaned
  1177. $last_login_date = $last_login_date_tmp;
  1178. } else if($last_login_date_tmp != false && $last_login_date != false) { // TODO: Repeated previous condition. To be cleaned.
  1179. // Find the max and assign it to first_login_date
  1180. if(strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
  1181. $last_login_date = $last_login_date_tmp;
  1182. }
  1183. }
  1184. $exercise_results_tmp = MySpace::exercises_results($row->user_id, $course_code);
  1185. $total_score_obtained += $exercise_results_tmp['score_obtained'];
  1186. $total_score_possible += $exercise_results_tmp['score_possible'];
  1187. $total_questions_answered += $exercise_results_tmp['questions_answered'];
  1188. }
  1189. if($nb_progress_lp > 0) {
  1190. $avg_progress = round($progress / $nb_progress_lp, 2);
  1191. } else {
  1192. $avg_progress = 0;
  1193. }
  1194. if($nb_score_lp > 0) {
  1195. $avg_score = round($score / $nb_score_lp, 2);
  1196. } else {
  1197. $avg_score = '-';
  1198. }
  1199. if($last_login_date) {
  1200. $last_login_date = api_convert_and_format_date($last_login_date, DATE_FORMAT_SHORT, date_default_timezone_get());
  1201. } else {
  1202. $last_login_date = '-';
  1203. }
  1204. if($total_score_possible > 0) {
  1205. $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
  1206. } else {
  1207. $total_score_percentage = 0;
  1208. }
  1209. if($total_score_percentage > 0) {
  1210. $total_score = $total_score_obtained.'/'.$total_score_possible.' ('.$total_score_percentage.' %)';
  1211. } else {
  1212. $total_score = '-';
  1213. }
  1214. $return .= '<tr>';
  1215. // time spent in the course
  1216. $return .= ' <td style="width:164px;">'.api_time_to_hms($time_spent).'</td>';
  1217. // student progress in course
  1218. $return .= ' <td>'.$avg_progress.'</td>';
  1219. // student score
  1220. $return .= ' <td>'.$avg_score.'</td>';
  1221. // student messages
  1222. $return .= ' <td>'.$nb_messages.'</td>';
  1223. // student assignments
  1224. $return .= ' <td>'.$nb_assignments.'</td>';
  1225. // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
  1226. $return .= '<td width="105px;">'.$total_score.'</td>';
  1227. $return .= '<td>'.$total_questions_answered.'</td>';
  1228. // last connection
  1229. $return .= ' <td>'.$last_login_date.'</td>';
  1230. $return .= '</tr>';
  1231. $return .= '</table>';
  1232. return $return;
  1233. }
  1234. /**
  1235. * This function exports the table that we see in display_tracking_course_overview()
  1236. *
  1237. */
  1238. public static function export_tracking_course_overview()
  1239. {
  1240. // database table definition
  1241. $tbl_course_rel_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  1242. $tbl_user = Database :: get_main_table(TABLE_MAIN_USER);
  1243. // the values of the sortable table
  1244. if ($_GET['tracking_course_overview_page_nr']) {
  1245. $from = $_GET['tracking_course_overview_page_nr'];
  1246. } else {
  1247. $from = 0;
  1248. }
  1249. if ($_GET['tracking_course_overview_column']) {
  1250. $orderby = $_GET['tracking_course_overview_column'];
  1251. } else {
  1252. $orderby = 0;
  1253. }
  1254. if ($_GET['tracking_course_overview_direction']) {
  1255. $direction = $_GET['tracking_course_overview_direction'];
  1256. } else {
  1257. $direction = 'ASC';
  1258. }
  1259. $course_data = MySpace::get_course_data_tracking_overview($from, 1000, $orderby, $direction);
  1260. $csv_content = array();
  1261. // the first line of the csv file with the column headers
  1262. $csv_row = array();
  1263. $csv_row[] = get_lang('Course', '');
  1264. $csv_row[] = get_lang('AvgTimeSpentInTheCourse', '');
  1265. $csv_row[] = get_lang('AvgStudentsProgress', '');
  1266. $csv_row[] = get_lang('AvgCourseScore', '');
  1267. $csv_row[] = get_lang('TotalNumberOfMessages', '');
  1268. $csv_row[] = get_lang('TotalNumberOfAssignments', '');
  1269. $csv_row[] = get_lang('TotalExercisesScoreObtained', '');
  1270. $csv_row[] = get_lang('TotalExercisesScorePossible', '');
  1271. $csv_row[] = get_lang('TotalExercisesAnswered', '');
  1272. $csv_row[] = get_lang('TotalExercisesScorePercentage', '');
  1273. $csv_row[] = get_lang('LatestLogin', '');
  1274. $csv_content[] = $csv_row;
  1275. // the other lines (the data)
  1276. foreach ($course_data as $key => $course) {
  1277. $course_code = $course[0];
  1278. $courseInfo = api_get_course_info($course_code);
  1279. $course_title = $courseInfo['title'];
  1280. $courseId = $courseInfo['real_id'];
  1281. $csv_row = array();
  1282. $csv_row[] = $course_title;
  1283. // getting all the courses of the session
  1284. $sql = "SELECT *
  1285. FROM $tbl_user AS u
  1286. INNER JOIN $tbl_course_rel_user AS cu
  1287. ON cu.user_id = u.user_id
  1288. WHERE cu.c_id = '".$courseId."'";
  1289. $result = Database::query($sql);
  1290. $time_spent = 0;
  1291. $progress = 0;
  1292. $nb_progress_lp = 0;
  1293. $score = 0;
  1294. $nb_score_lp = 0;
  1295. $nb_messages = 0;
  1296. $nb_assignments = 0;
  1297. $last_login_date = false;
  1298. $total_score_obtained = 0;
  1299. $total_score_possible = 0;
  1300. $total_questions_answered = 0;
  1301. while ($row = Database::fetch_object($result)) {
  1302. // get time spent in the course and session
  1303. $time_spent += Tracking::get_time_spent_on_the_course($row->user_id, $courseId);
  1304. $progress_tmp = Tracking::get_avg_student_progress($row->user_id, $course_code, array(), null, true);
  1305. $progress += $progress_tmp[0];
  1306. $nb_progress_lp += $progress_tmp[1];
  1307. $score_tmp = Tracking :: get_avg_student_score($row->user_id, $course_code, array(), null, true);
  1308. if(is_array($score_tmp)) {
  1309. $score += $score_tmp[0];
  1310. $nb_score_lp += $score_tmp[1];
  1311. }
  1312. $nb_messages += Tracking::count_student_messages($row->user_id, $course_code);
  1313. $nb_assignments += Tracking::count_student_assignments($row->user_id, $course_code);
  1314. $last_login_date_tmp = Tracking::get_last_connection_date_on_the_course($row->user_id, $courseInfo, null, false);
  1315. if($last_login_date_tmp != false && $last_login_date == false) { // TODO: To be cleaned.
  1316. $last_login_date = $last_login_date_tmp;
  1317. } else if($last_login_date_tmp != false && $last_login_date == false) { // TODO: Repeated previous condition. To be cleaned.
  1318. // Find the max and assign it to first_login_date
  1319. if(strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
  1320. $last_login_date = $last_login_date_tmp;
  1321. }
  1322. }
  1323. $exercise_results_tmp = MySpace::exercises_results($row->user_id, $course_code);
  1324. $total_score_obtained += $exercise_results_tmp['score_obtained'];
  1325. $total_score_possible += $exercise_results_tmp['score_possible'];
  1326. $total_questions_answered += $exercise_results_tmp['questions_answered'];
  1327. }
  1328. if($nb_progress_lp > 0) {
  1329. $avg_progress = round($progress / $nb_progress_lp, 2);
  1330. } else {
  1331. $avg_progress = 0;
  1332. }
  1333. if($nb_score_lp > 0) {
  1334. $avg_score = round($score / $nb_score_lp, 2);
  1335. } else {
  1336. $avg_score = '-';
  1337. }
  1338. if($last_login_date) {
  1339. $last_login_date = api_convert_and_format_date($last_login_date, DATE_FORMAT_SHORT, date_default_timezone_get());
  1340. } else {
  1341. $last_login_date = '-';
  1342. }
  1343. if($total_score_possible > 0) {
  1344. $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
  1345. } else {
  1346. $total_score_percentage = 0;
  1347. }
  1348. // time spent in the course
  1349. $csv_row[] = api_time_to_hms($time_spent);
  1350. // student progress in course
  1351. $csv_row[] = $avg_progress;
  1352. // student score
  1353. $csv_row[] = $avg_score;
  1354. // student messages
  1355. $csv_row[] = $nb_messages;
  1356. // student assignments
  1357. $csv_row[] = $nb_assignments;
  1358. // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
  1359. $csv_row[] = $total_score_obtained;
  1360. $csv_row[] = $total_score_possible;
  1361. $csv_row[] = $total_questions_answered;
  1362. $csv_row[] = $total_score_percentage;
  1363. // last connection
  1364. $csv_row[] = $last_login_date;
  1365. $csv_content[] = $csv_row;
  1366. }
  1367. Export :: arrayToCsv($csv_content, 'reporting_course_overview');
  1368. exit;
  1369. }
  1370. /**
  1371. * Display a sortable table that contains an overview of all the reporting progress of all sessions and all courses the user is subscribed to
  1372. * @author Guillaume Viguier <guillaume@viguierjust.com>
  1373. */
  1374. public static function display_tracking_session_overview()
  1375. {
  1376. $t_head = ' <table style="width: 100%;border:0;padding:0;border-collapse:collapse;table-layout: fixed">';
  1377. //$t_head .= ' <caption>'.get_lang('CourseInformation').'</caption>';
  1378. $t_head .= '<tr>';
  1379. $t_head .= ' <th width="155px" style="border-left:0;border-bottom:0"><span>'.get_lang('Course').'</span></th>';
  1380. $t_head .= ' <th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgTimeSpentInTheCourse'), 6, true).'</span></th>';
  1381. $t_head .= ' <th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgStudentsProgress'), 6, true).'</span></th>';
  1382. $t_head .= ' <th style="padding:0;border-bottom:0"><span>'.cut(get_lang('AvgCourseScore'), 6, true).'</span></th>';
  1383. //$t_head .= ' <th><div style="width:40px">'.get_lang('AvgExercisesScore').'</div></th>';
  1384. $t_head .= ' <th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalNumberOfMessages'), 6, true).'</span></th>';
  1385. $t_head .= ' <th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalNumberOfAssignments'), 6, true).'</span></th>';
  1386. $t_head .= ' <th width="105px" style="border-bottom:0"><span>'.get_lang('TotalExercisesScoreObtained').'</span></th>';
  1387. //$t_head .= ' <th><div>'.get_lang('TotalExercisesScorePossible').'</div></th>';
  1388. $t_head .= ' <th style="padding:0;border-bottom:0"><span>'.cut(get_lang('TotalExercisesAnswered'), 6, true).'</span></th>';
  1389. //$t_head .= ' <th><div>'.get_lang('TotalExercisesScorePercentage').'</div></th>';
  1390. //$t_head .= ' <th><div style="width:60px">'.get_lang('FirstLogin').'</div></th>';
  1391. $t_head .= ' <th style="padding:0;border-bottom:0;border-right:0;"><span>'.get_lang('LatestLogin').'</span></th>';
  1392. $t_head .= ' </tr></table>';
  1393. $addparams = array('view' => 'admin', 'display' => 'sessionoverview');
  1394. $table = new SortableTable('tracking_session_overview', array('MySpace','get_total_number_sessions'), array('MySpace','get_session_data_tracking_overview'), 1);
  1395. $table->additional_parameters = $addparams;
  1396. $table->set_header(0, '', false, null, array('style' => 'display: none'));
  1397. $table->set_header(1, get_lang('Session'), true, array('style' => 'font-size:8pt'), array('style' => 'font-size:8pt'));
  1398. $table->set_header(2, $t_head, false, array('style' => 'width:90%;border:0;padding:0;font-size:7.5pt;'), array('style' => 'width:90%;padding:0;font-size:7.5pt;'));
  1399. $table->set_column_filter(2, array('MySpace', 'session_tracking_filter'));
  1400. $table->display();
  1401. }
  1402. /**
  1403. * Get the total number of sessions
  1404. *
  1405. * @return integer Total number of sessions
  1406. */
  1407. public static function get_total_number_sessions()
  1408. {
  1409. // database table definition
  1410. $main_session_table = Database :: get_main_table(TABLE_MAIN_SESSION);
  1411. return Database::count_rows($main_session_table);
  1412. }
  1413. /**
  1414. * Get data for the sessions
  1415. *
  1416. * @param int Inferior limit
  1417. * @param int Number of items to select
  1418. * @param string Column to order on
  1419. * @param string Order direction
  1420. * @return array Results
  1421. */
  1422. public static function get_session_data_tracking_overview($from, $number_of_items, $column, $direction)
  1423. {
  1424. $main_session_table = Database :: get_main_table(TABLE_MAIN_SESSION);
  1425. $sql = "SELECT id AS col0, name AS col1 FROM $main_session_table";
  1426. $sql .= " ORDER BY col$column $direction ";
  1427. $sql .= " LIMIT $from,$number_of_items";
  1428. $result = Database::query($sql);
  1429. $return = array ();
  1430. while ($session = Database::fetch_row($result)) {
  1431. $return[] = $session;
  1432. }
  1433. return $return;
  1434. }
  1435. /**
  1436. * Fills in session reporting data
  1437. *
  1438. * @param integer $user_id the id of the user
  1439. * @param array $url_params additonal url parameters
  1440. * @param array $row the row information (the other columns)
  1441. * @return string html code
  1442. */
  1443. public static function session_tracking_filter($session_id, $url_params, $row)
  1444. {
  1445. $session_id = $row[0];
  1446. // the table header
  1447. $return = '<table class="data_table" style="width: 100%;border:0;padding:0;border-collapse:collapse;table-layout: fixed">';
  1448. /*$return .= ' <tr>';
  1449. $return .= ' <th>'.get_lang('Course').'</th>';
  1450. $return .= ' <th>'.get_lang('AvgTimeSpentInTheCourse').'</th>';
  1451. $return .= ' <th>'.get_lang('AvgStudentsProgress').'</th>';
  1452. $return .= ' <th>'.get_lang('AvgCourseScore').'</th>';
  1453. $return .= ' <th>'.get_lang('AvgExercisesScore').'</th>';
  1454. $return .= ' <th>'.get_lang('AvgMessages').'</th>';
  1455. $return .= ' <th>'.get_lang('AvgAssignments').'</th>';
  1456. $return .= ' <th>'.get_lang('TotalExercisesScoreObtained').'</th>';
  1457. $return .= ' <th>'.get_lang('TotalExercisesScorePossible').'</th>';
  1458. $return .= ' <th>'.get_lang('TotalExercisesAnswered').'</th>';
  1459. $return .= ' <th>'.get_lang('TotalExercisesScorePercentage').'</th>';
  1460. $return .= ' <th>'.get_lang('FirstLogin').'</th>';
  1461. $return .= ' <th>'.get_lang('LatestLogin').'</th>';
  1462. $return .= ' </tr>';*/
  1463. // database table definition
  1464. $tbl_session_rel_course = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE);
  1465. $tbl_course = Database :: get_main_table(TABLE_MAIN_COURSE);
  1466. $tbl_session_rel_course_rel_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  1467. $tbl_user = Database :: get_main_table(TABLE_MAIN_USER);
  1468. // getting all the courses of the user
  1469. $sql = "SELECT * FROM $tbl_course AS c
  1470. INNER JOIN $tbl_session_rel_course AS sc
  1471. ON sc.c_id = c.id
  1472. WHERE sc.session_id = '".$session_id."';";
  1473. $result = Database::query($sql);
  1474. while ($row = Database::fetch_object($result)) {
  1475. $courseId = $row->c_id;
  1476. $courseInfo = api_get_course_info_by_id($courseId);
  1477. $return .= '<tr>';
  1478. // course code
  1479. $return .= ' <td width="157px" >'.$row->title.'</td>';
  1480. // get the users in the course
  1481. $sql = "SELECT u.user_id
  1482. FROM $tbl_user AS u
  1483. INNER JOIN $tbl_session_rel_course_rel_user AS scu
  1484. ON u.user_id = scu.user_id
  1485. WHERE scu.session_id = '".$session_id."' AND scu.c_id = '".$courseId."'";
  1486. $result_users = Database::query($sql);
  1487. $time_spent = 0;
  1488. $progress = 0;
  1489. $nb_progress_lp = 0;
  1490. $score = 0;
  1491. $nb_score_lp = 0;
  1492. $nb_messages = 0;
  1493. $nb_assignments = 0;
  1494. $last_login_date = false;
  1495. $total_score_obtained = 0;
  1496. $total_score_possible = 0;
  1497. $total_questions_answered = 0;
  1498. while ($row_user = Database::fetch_object($result_users)) {
  1499. // get time spent in the course and session
  1500. $time_spent += Tracking::get_time_spent_on_the_course($row_user->user_id, $courseId, $session_id);
  1501. $progress_tmp = Tracking::get_avg_student_progress($row_user->user_id, $row->code, array(), $session_id, true);
  1502. $progress += $progress_tmp[0];
  1503. $nb_progress_lp += $progress_tmp[1];
  1504. $score_tmp = Tracking :: get_avg_student_score($row_user->user_id, $row->code, array(), $session_id, true);
  1505. if (is_array($score_tmp)) {
  1506. $score += $score_tmp[0];
  1507. $nb_score_lp += $score_tmp[1];
  1508. }
  1509. $nb_messages += Tracking::count_student_messages($row_user->user_id, $row->code, $session_id);
  1510. $nb_assignments += Tracking::count_student_assignments($row_user->user_id, $row->code, $session_id);
  1511. $last_login_date_tmp = Tracking::get_last_connection_date_on_the_course($row_user->user_id, $courseInfo, $session_id, false);
  1512. if ($last_login_date_tmp != false && $last_login_date == false) {
  1513. // TODO: To be cleaned.
  1514. $last_login_date = $last_login_date_tmp;
  1515. } else if($last_login_date_tmp != false && $last_login_date != false) {
  1516. // TODO: Repeated previous condition! To be cleaned.
  1517. // Find the max and assign it to first_login_date
  1518. if(strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
  1519. $last_login_date = $last_login_date_tmp;
  1520. }
  1521. }
  1522. $exercise_results_tmp = MySpace::exercises_results($row_user->user_id, $row->code, $session_id);
  1523. $total_score_obtained += $exercise_results_tmp['score_obtained'];
  1524. $total_score_possible += $exercise_results_tmp['score_possible'];
  1525. $total_questions_answered += $exercise_results_tmp['questions_answered'];
  1526. }
  1527. if($nb_progress_lp > 0) {
  1528. $avg_progress = round($progress / $nb_progress_lp, 2);
  1529. } else {
  1530. $avg_progress = 0;
  1531. }
  1532. if($nb_score_lp > 0) {
  1533. $avg_score = round($score / $nb_score_lp, 2);
  1534. } else {
  1535. $avg_score = '-';
  1536. }
  1537. if($last_login_date) {
  1538. $last_login_date = api_convert_and_format_date($last_login_date, DATE_FORMAT_SHORT, date_default_timezone_get());
  1539. } else {
  1540. $last_login_date = '-';
  1541. }
  1542. if($total_score_possible > 0) {
  1543. $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
  1544. } else {
  1545. $total_score_percentage = 0;
  1546. }
  1547. if($total_score_percentage > 0) {
  1548. $total_score = $total_score_obtained.'/'.$total_score_possible.' ('.$total_score_percentage.' %)';
  1549. } else {
  1550. $total_score = '-';
  1551. }
  1552. // time spent in the course
  1553. $return .= ' <td><div>'.api_time_to_hms($time_spent).'</div></td>';
  1554. // student progress in course
  1555. $return .= ' <td><div>'.$avg_progress.'</div></td>';
  1556. // student score
  1557. $return .= ' <td><div>'.$avg_score.'</div></td>';
  1558. // student messages
  1559. $return .= ' <td><div>'.$nb_messages.'</div></td>';
  1560. // student assignments
  1561. $return .= ' <td><div>'.$nb_assignments.'</div></td>';
  1562. // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
  1563. $return .= '<td width="105px;">'.$total_score.'</td>';
  1564. $return .= '<td>'.$total_questions_answered.'</td>';
  1565. // last connection
  1566. $return .= ' <td><div>'.$last_login_date.'</div></td>';
  1567. $return .= '<tr>';
  1568. }
  1569. $return .= '</table>';
  1570. return $return;
  1571. }
  1572. /**
  1573. * This function exports the table that we see in display_tracking_session_overview()
  1574. *
  1575. */
  1576. public static function export_tracking_session_overview()
  1577. {
  1578. // database table definition
  1579. $tbl_session_rel_course = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE);
  1580. $tbl_course = Database :: get_main_table(TABLE_MAIN_COURSE);
  1581. $tbl_session_rel_course_rel_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  1582. $tbl_user = Database :: get_main_table(TABLE_MAIN_USER);
  1583. // the values of the sortable table
  1584. if ($_GET['tracking_session_overview_page_nr']) {
  1585. $from = $_GET['tracking_session_overview_page_nr'];
  1586. } else {
  1587. $from = 0;
  1588. }
  1589. if ($_GET['tracking_session_overview_column']) {
  1590. $orderby = $_GET['tracking_session_overview_column'];
  1591. } else {
  1592. $orderby = 0;
  1593. }
  1594. if ($_GET['tracking_session_overview_direction']) {
  1595. $direction = $_GET['tracking_session_overview_direction'];
  1596. } else {
  1597. $direction = 'ASC';
  1598. }
  1599. $session_data = MySpace::get_session_data_tracking_overview($from, 1000, $orderby, $direction);
  1600. $csv_content = array();
  1601. // the first line of the csv file with the column headers
  1602. $csv_row = array();
  1603. $csv_row[] = get_lang('Session');
  1604. $csv_row[] = get_lang('Course', '');
  1605. $csv_row[] = get_lang('AvgTimeSpentInTheCourse', '');
  1606. $csv_row[] = get_lang('AvgStudentsProgress', '');
  1607. $csv_row[] = get_lang('AvgCourseScore', '');
  1608. $csv_row[] = get_lang('TotalNumberOfMessages', '');
  1609. $csv_row[] = get_lang('TotalNumberOfAssignments', '');
  1610. $csv_row[] = get_lang('TotalExercisesScoreObtained', '');
  1611. $csv_row[] = get_lang('TotalExercisesScorePossible', '');
  1612. $csv_row[] = get_lang('TotalExercisesAnswered', '');
  1613. $csv_row[] = get_lang('TotalExercisesScorePercentage', '');
  1614. $csv_row[] = get_lang('LatestLogin', '');
  1615. $csv_content[] = $csv_row;
  1616. // the other lines (the data)
  1617. foreach ($session_data as $key => $session) {
  1618. $session_id = $session[0];
  1619. $session_title = $session[1];
  1620. // getting all the courses of the session
  1621. $sql = "SELECT * FROM $tbl_course AS c
  1622. INNER JOIN $tbl_session_rel_course AS sc
  1623. ON sc.c_id = c.id
  1624. WHERE sc.session_id = '".$session_id."';";
  1625. $result = Database::query($sql);
  1626. while ($row = Database::fetch_object($result)) {
  1627. $courseId = $row->c_id;
  1628. $courseInfo = api_get_course_info_by_id($courseId);
  1629. $csv_row = array();
  1630. $csv_row[] = $session_title;
  1631. $csv_row[] = $row->title;
  1632. // get the users in the course
  1633. $sql = "SELECT scu.user_id
  1634. FROM $tbl_user AS u
  1635. INNER JOIN $tbl_session_rel_course_rel_user AS scu
  1636. ON u.user_id = scu.user_id
  1637. WHERE scu.session_id = '".$session_id."' AND scu.c_id = '".$courseId."'";
  1638. $result_users = Database::query($sql);
  1639. $time_spent = 0;
  1640. $progress = 0;
  1641. $nb_progress_lp = 0;
  1642. $score = 0;
  1643. $nb_score_lp = 0;
  1644. $nb_messages = 0;
  1645. $nb_assignments = 0;
  1646. $last_login_date = false;
  1647. $total_score_obtained = 0;
  1648. $total_score_possible = 0;
  1649. $total_questions_answered = 0;
  1650. while($row_user = Database::fetch_object($result_users)) {
  1651. // get time spent in the course and session
  1652. $time_spent += Tracking::get_time_spent_on_the_course($row_user->user_id, $courseId, $session_id);
  1653. $progress_tmp = Tracking::get_avg_student_progress($row_user->user_id, $row->code, array(), $session_id, true);
  1654. $progress += $progress_tmp[0];
  1655. $nb_progress_lp += $progress_tmp[1];
  1656. $score_tmp = Tracking :: get_avg_student_score($row_user->user_id, $row->code, array(), $session_id, true);
  1657. if (is_array($score_tmp)) {
  1658. $score += $score_tmp[0];
  1659. $nb_score_lp += $score_tmp[1];
  1660. }
  1661. $nb_messages += Tracking::count_student_messages(
  1662. $row_user->user_id,
  1663. $row->code,
  1664. $session_id
  1665. );
  1666. $nb_assignments += Tracking::count_student_assignments(
  1667. $row_user->user_id,
  1668. $row->code,
  1669. $session_id
  1670. );
  1671. $last_login_date_tmp = Tracking:: get_last_connection_date_on_the_course(
  1672. $row_user->user_id,
  1673. $courseInfo,
  1674. $session_id,
  1675. false
  1676. );
  1677. if($last_login_date_tmp != false && $last_login_date == false) { // TODO: To be cleaned.
  1678. $last_login_date = $last_login_date_tmp;
  1679. } else if($last_login_date_tmp != false && $last_login_date == false) { // TODO: Repeated previous condition. To be cleaned.
  1680. // Find the max and assign it to first_login_date
  1681. if(strtotime($last_login_date_tmp) > strtotime($last_login_date)) {
  1682. $last_login_date = $last_login_date_tmp;
  1683. }
  1684. }
  1685. $exercise_results_tmp = MySpace::exercises_results($row_user->user_id, $row->code, $session_id);
  1686. $total_score_obtained += $exercise_results_tmp['score_obtained'];
  1687. $total_score_possible += $exercise_results_tmp['score_possible'];
  1688. $total_questions_answered += $exercise_results_tmp['questions_answered'];
  1689. }
  1690. if($nb_progress_lp > 0) {
  1691. $avg_progress = round($progress / $nb_progress_lp, 2);
  1692. } else {
  1693. $avg_progress = 0;
  1694. }
  1695. if($nb_score_lp > 0) {
  1696. $avg_score = round($score / $nb_score_lp, 2);
  1697. } else {
  1698. $avg_score = '-';
  1699. }
  1700. if($last_login_date) {
  1701. $last_login_date = api_convert_and_format_date($last_login_date, DATE_FORMAT_SHORT, date_default_timezone_get());
  1702. } else {
  1703. $last_login_date = '-';
  1704. }
  1705. if($total_score_possible > 0) {
  1706. $total_score_percentage = round($total_score_obtained / $total_score_possible * 100, 2);
  1707. } else {
  1708. $total_score_percentage = 0;
  1709. }
  1710. if($total_score_percentage > 0) {
  1711. $total_score = $total_score_obtained.'/'.$total_score_possible.' ('.$total_score_percentage.' %)';
  1712. } else {
  1713. $total_score = '-';
  1714. }
  1715. // time spent in the course
  1716. $csv_row[] = api_time_to_hms($time_spent);
  1717. // student progress in course
  1718. $csv_row[] = $avg_progress;
  1719. // student score
  1720. $csv_row[] = $avg_score;
  1721. // student messages
  1722. $csv_row[] = $nb_messages;
  1723. // student assignments
  1724. $csv_row[] = $nb_assignments;
  1725. // student exercises results (obtained score, maximum score, number of exercises answered, score percentage)
  1726. $csv_row[] = $total_score_obtained;
  1727. $csv_row[] = $total_score_possible;
  1728. $csv_row[] = $total_questions_answered;
  1729. $csv_row[] = $total_score_percentage;
  1730. // last connection
  1731. $csv_row[] = $last_login_date;
  1732. $csv_content[] = $csv_row;
  1733. }
  1734. }
  1735. Export :: arrayToCsv($csv_content, 'reporting_session_overview');
  1736. exit;
  1737. }
  1738. /**
  1739. * Get general information about the exercise performance of the user
  1740. * the total obtained score (all the score on all the questions)
  1741. * the maximum score that could be obtained
  1742. * the number of questions answered
  1743. * the success percentage
  1744. * @param integer $user_id the id of the user
  1745. * @param string $course_code the course code
  1746. * @return array
  1747. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  1748. * @version Dokeos 1.8.6
  1749. * @since November 2008
  1750. */
  1751. public static function exercises_results($user_id, $course_code, $session_id = false)
  1752. {
  1753. $questions_answered = 0;
  1754. $courseId = api_get_course_int_id($course_code);
  1755. $sql = 'SELECT exe_result , exe_weighting
  1756. FROM '.Database :: get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES)."
  1757. WHERE c_id = ' . $courseId . '
  1758. AND exe_user_id = '".intval($user_id)."'";
  1759. if($session_id !== false) {
  1760. $sql .= " AND session_id = '".$session_id."' ";
  1761. }
  1762. $result = Database::query($sql);
  1763. $score_obtained = 0;
  1764. $score_possible = 0;
  1765. $questions_answered = 0;
  1766. while ($row = Database::fetch_array($result)) {
  1767. $score_obtained += $row['exe_result'];
  1768. $score_possible += $row['exe_weighting'];
  1769. $questions_answered ++;
  1770. }
  1771. if ($score_possible != 0) {
  1772. $percentage = round(($score_obtained / $score_possible * 100), 2);
  1773. } else {
  1774. $percentage = null;
  1775. }
  1776. return array(
  1777. 'score_obtained' => $score_obtained,
  1778. 'score_possible' => $score_possible,
  1779. 'questions_answered' => $questions_answered,
  1780. 'percentage' => $percentage
  1781. );
  1782. }
  1783. /**
  1784. * This function exports the table that we see in display_tracking_user_overview()
  1785. *
  1786. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  1787. * @version Dokeos 1.8.6
  1788. * @since October 2008
  1789. */
  1790. public static function export_tracking_user_overview()
  1791. {
  1792. // database table definitions
  1793. $tbl_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  1794. $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
  1795. $sort_by_first_name = api_sort_by_first_name();
  1796. // the values of the sortable table
  1797. if ($_GET['tracking_user_overview_page_nr']) {
  1798. $from = $_GET['tracking_user_overview_page_nr'];
  1799. } else {
  1800. $from = 0;
  1801. }
  1802. if ($_GET['tracking_user_overview_column']) {
  1803. $orderby = $_GET['tracking_user_overview_column'];
  1804. } else {
  1805. $orderby = 0;
  1806. }
  1807. if ($is_western_name_order != api_is_western_name_order() && ($orderby == 1 || $orderby == 2)) {
  1808. // Swapping the sorting column if name order for export is different than the common name order.
  1809. $orderby = 3 - $orderby;
  1810. }
  1811. if ($_GET['tracking_user_overview_direction']) {
  1812. $direction = $_GET['tracking_user_overview_direction'];
  1813. } else {
  1814. $direction = 'ASC';
  1815. }
  1816. $user_data = MySpace::get_user_data_tracking_overview($from, 1000, $orderby, $direction);
  1817. // the first line of the csv file with the column headers
  1818. $csv_row = array();
  1819. $csv_row[] = get_lang('OfficialCode');
  1820. if ($is_western_name_order) {
  1821. $csv_row[] = get_lang('FirstName', '');
  1822. $csv_row[] = get_lang('LastName', '');
  1823. } else {
  1824. $csv_row[] = get_lang('LastName', '');
  1825. $csv_row[] = get_lang('FirstName', '');
  1826. }
  1827. $csv_row[] = get_lang('LoginName');
  1828. $csv_row[] = get_lang('CourseCode');
  1829. // the additional user defined fields (only those that were selected to be exported)
  1830. $fields = UserManager::get_extra_fields(0, 50, 5, 'ASC');
  1831. if (is_array($_SESSION['additional_export_fields'])) {
  1832. foreach ($_SESSION['additional_export_fields'] as $key => $extra_field_export) {
  1833. $csv_row[] = $fields[$extra_field_export][3];
  1834. $field_names_to_be_exported[] = 'extra_'.$fields[$extra_field_export][1];
  1835. }
  1836. }
  1837. $csv_row[] = get_lang('AvgTimeSpentInTheCourse', '');
  1838. $csv_row[] = get_lang('AvgStudentsProgress', '');
  1839. $csv_row[] = get_lang('AvgCourseScore', '');
  1840. $csv_row[] = get_lang('AvgExercisesScore', '');
  1841. $csv_row[] = get_lang('AvgMessages', '');
  1842. $csv_row[] = get_lang('AvgAssignments', '');
  1843. $csv_row[] = get_lang('TotalExercisesScoreObtained', '');
  1844. $csv_row[] = get_lang('TotalExercisesScorePossible', '');
  1845. $csv_row[] = get_lang('TotalExercisesAnswered', '');
  1846. $csv_row[] = get_lang('TotalExercisesScorePercentage', '');
  1847. $csv_row[] = get_lang('FirstLogin', '');
  1848. $csv_row[] = get_lang('LatestLogin', '');
  1849. $csv_content[] = $csv_row;
  1850. // the other lines (the data)
  1851. foreach ($user_data as $key => $user) {
  1852. // getting all the courses of the user
  1853. $sql = "SELECT * FROM $tbl_course_user
  1854. WHERE user_id = '".intval($user[4])."' AND relation_type<>".COURSE_RELATION_TYPE_RRHH." ";
  1855. $result = Database::query($sql);
  1856. while ($row = Database::fetch_row($result)) {
  1857. $courseInfo = api_get_course_info($row['course_code']);
  1858. $courseId = $courseInfo['real_id'];
  1859. $csv_row = array();
  1860. // user official code
  1861. $csv_row[] = $user[0];
  1862. // user first|last name
  1863. $csv_row[] = $user[1];
  1864. // user last|first name
  1865. $csv_row[] = $user[2];
  1866. // user login name
  1867. $csv_row[] = $user[3];
  1868. // course code
  1869. $csv_row[] = $row[0];
  1870. // the additional defined user fields
  1871. $extra_fields = MySpace::get_user_overview_export_extra_fields($user[4]);
  1872. if (is_array($field_names_to_be_exported)) {
  1873. foreach ($field_names_to_be_exported as $key => $extra_field_export) {
  1874. $csv_row[] = $extra_fields[$extra_field_export];
  1875. }
  1876. }
  1877. // time spent in the course
  1878. $csv_row[] = api_time_to_hms(Tracking::get_time_spent_on_the_course ($user[4], $courseId));
  1879. // student progress in course
  1880. $csv_row[] = round(Tracking::get_avg_student_progress ($user[4], $row[0]), 2);
  1881. // student score
  1882. $csv_row[] = round(Tracking::get_avg_student_score($user[4], $row[0]), 2);
  1883. // student tes score
  1884. $csv_row[] = round(Tracking::get_avg_student_exercise_score($user[4], $row[0]), 2);
  1885. // student messages
  1886. $csv_row[] = Tracking::count_student_messages($user[4], $row[0]);
  1887. // student assignments
  1888. $csv_row[] = Tracking::count_student_assignments ($user[4], $row[0]);
  1889. // student exercises results
  1890. $exercises_results = MySpace::exercises_results($user[4], $row[0]);
  1891. $csv_row[] = $exercises_results['score_obtained'];
  1892. $csv_row[] = $exercises_results['score_possible'];
  1893. $csv_row[] = $exercises_results['questions_answered'];
  1894. $csv_row[] = $exercises_results['percentage'];
  1895. // first connection
  1896. $csv_row[] = Tracking::get_first_connection_date_on_the_course ($user[4], $courseId);
  1897. // last connection
  1898. $csv_row[] = strip_tags(Tracking::get_last_connection_date_on_the_course($user[4], $courseInfo));
  1899. $csv_content[] = $csv_row;
  1900. }
  1901. }
  1902. Export :: arrayToCsv($csv_content, 'reporting_user_overview');
  1903. exit;
  1904. }
  1905. /**
  1906. * Get data for courses list in sortable with pagination
  1907. * @return array
  1908. */
  1909. public static function get_course_data($from, $number_of_items, $column, $direction)
  1910. {
  1911. global $courses, $csv_content, $charset, $session_id;
  1912. // definition database tables
  1913. $tbl_course = Database :: get_main_table(TABLE_MAIN_COURSE);
  1914. $tbl_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  1915. $tbl_session_course_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  1916. $course_data = array();
  1917. $courses_code = array_keys($courses);
  1918. foreach ($courses_code as &$code) {
  1919. $code = "'$code'";
  1920. }
  1921. // get all courses with limit
  1922. $sql = "SELECT course.code as col1, course.title as col2
  1923. FROM $tbl_course course
  1924. WHERE course.code IN (".implode(',',$courses_code).")";
  1925. if (!in_array($direction, array('ASC','DESC'))) $direction = 'ASC';
  1926. $column = intval($column);
  1927. $from = intval($from);
  1928. $number_of_items = intval($number_of_items);
  1929. $sql .= " ORDER BY col$column $direction ";
  1930. $sql .= " LIMIT $from,$number_of_items";
  1931. $res = Database::query($sql);
  1932. while ($row_course = Database::fetch_row($res)) {
  1933. $course_code = $row_course[0];
  1934. $courseInfo = api_get_course_info($course_code);
  1935. $courseId = $courseInfo['real_id'];
  1936. $avg_assignments_in_course = $avg_messages_in_course = $nb_students_in_course = $avg_progress_in_course = $avg_score_in_course = $avg_time_spent_in_course = $avg_score_in_exercise = 0;
  1937. // students directly subscribed to the course
  1938. if (empty($session_id)) {
  1939. $sql = "SELECT user_id
  1940. FROM $tbl_course_user as course_rel_user
  1941. WHERE
  1942. course_rel_user.status='5' AND
  1943. course_rel_user.c_id = '$courseId'";
  1944. } else {
  1945. $sql = "SELECT user_id FROM $tbl_session_course_user srcu
  1946. WHERE
  1947. c_id = '$courseId' AND
  1948. session_id = '$session_id' AND
  1949. status<>2";
  1950. }
  1951. $rs = Database::query($sql);
  1952. $users = array();
  1953. while ($row = Database::fetch_array($rs)) {
  1954. $users[] = $row['user_id'];
  1955. }
  1956. if (count($users) > 0) {
  1957. $nb_students_in_course = count($users);
  1958. $avg_assignments_in_course = Tracking::count_student_assignments($users, $course_code, $session_id);
  1959. $avg_messages_in_course = Tracking::count_student_messages($users, $course_code, $session_id);
  1960. $avg_progress_in_course = Tracking::get_avg_student_progress($users, $course_code, array(), $session_id);
  1961. $avg_score_in_course = Tracking::get_avg_student_score($users, $course_code, array(), $session_id);
  1962. $avg_score_in_exercise = Tracking::get_avg_student_exercise_score($users, $course_code, 0, $session_id);
  1963. $avg_time_spent_in_course = Tracking::get_time_spent_on_the_course($users, $courseInfo['real_id'], $session_id);
  1964. $avg_progress_in_course = round($avg_progress_in_course / $nb_students_in_course, 2);
  1965. if (is_numeric($avg_score_in_course)) {
  1966. $avg_score_in_course = round($avg_score_in_course / $nb_students_in_course, 2);
  1967. }
  1968. $avg_time_spent_in_course = api_time_to_hms($avg_time_spent_in_course / $nb_students_in_course);
  1969. } else {
  1970. $avg_time_spent_in_course = null;
  1971. $avg_progress_in_course = null;
  1972. $avg_score_in_course = null;
  1973. $avg_score_in_exercise = null;
  1974. $avg_messages_in_course = null;
  1975. $avg_assignments_in_course = null;
  1976. }
  1977. $table_row = array();
  1978. $table_row[] = $row_course[1];
  1979. $table_row[] = $nb_students_in_course;
  1980. $table_row[] = $avg_time_spent_in_course;
  1981. $table_row[] = is_null($avg_progress_in_course) ? '' : $avg_progress_in_course.'%';
  1982. $table_row[] = is_null($avg_score_in_course) ? '' : $avg_score_in_course.'%';
  1983. $table_row[] = is_null($avg_score_in_exercise) ? '' : $avg_score_in_exercise.'%';
  1984. $table_row[] = $avg_messages_in_course;
  1985. $table_row[] = $avg_assignments_in_course;
  1986. //set the "from" value to know if I access the Reporting by the chamilo tab or the course link
  1987. $table_row[] = '<center><a href="../../tracking/courseLog.php?cidReq=' .$course_code.'&from=myspace&id_session='.$session_id.'">
  1988. '.Display::return_icon('2rightarrow.png').'
  1989. </a>
  1990. </center>';
  1991. $csv_content[] = array(
  1992. api_html_entity_decode($row_course[1], ENT_QUOTES, $charset),
  1993. $nb_students_in_course,
  1994. $avg_time_spent_in_course,
  1995. is_null($avg_progress_in_course) ? null : $avg_progress_in_course.'%',
  1996. is_null($avg_score_in_course) ? null : is_numeric($avg_score_in_course) ? $avg_score_in_course.'%' : $avg_score_in_course ,
  1997. is_null($avg_score_in_exercise) ? null : $avg_score_in_exercise.'%',
  1998. $avg_messages_in_course,
  1999. $avg_assignments_in_course,
  2000. );
  2001. $course_data[] = $table_row;
  2002. }
  2003. return $course_data;
  2004. }
  2005. /**
  2006. * get the numer of users of the platform
  2007. *
  2008. * @return integer
  2009. *
  2010. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  2011. * @version Dokeos 1.8.6
  2012. * @since October 2008
  2013. */
  2014. public static function get_number_of_users_tracking_overview()
  2015. {
  2016. // database table definition
  2017. $main_user_table = Database :: get_main_table(TABLE_MAIN_USER);
  2018. return Database::count_rows($main_user_table);
  2019. }
  2020. /**
  2021. * get all the data for the sortable table of the reporting progress of all users and all the courses the user is subscribed to.
  2022. *
  2023. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  2024. * @version Dokeos 1.8.6
  2025. * @since October 2008
  2026. */
  2027. public static function get_user_data_tracking_overview($from, $number_of_items, $column, $direction)
  2028. {
  2029. // database table definition
  2030. $access_url_id = api_get_current_access_url_id();
  2031. $tbl_url_rel_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
  2032. $main_user_table = Database::get_main_table(TABLE_MAIN_USER);
  2033. $condition_multi_url = null;
  2034. if (api_is_multiple_url_enabled()) {
  2035. $condition_multi_url = ", $tbl_url_rel_user as url_user
  2036. WHERE user.user_id=url_user.user_id AND access_url_id='$access_url_id'";
  2037. }
  2038. global $export_csv;
  2039. if ($export_csv) {
  2040. $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
  2041. } else {
  2042. $is_western_name_order = api_is_western_name_order();
  2043. }
  2044. $sql = "SELECT
  2045. official_code AS col0,
  2046. ".($is_western_name_order ? "
  2047. firstname AS col1,
  2048. lastname AS col2,
  2049. " : "
  2050. lastname AS col1,
  2051. firstname AS col2,
  2052. ").
  2053. "username AS col3,
  2054. user.user_id AS col4
  2055. FROM
  2056. $main_user_table as user $condition_multi_url
  2057. ";
  2058. $sql .= " ORDER BY col$column $direction ";
  2059. $sql .= " LIMIT $from,$number_of_items";
  2060. $result = Database::query($sql);
  2061. $return = array ();
  2062. while ($user = Database::fetch_row($result)) {
  2063. $return[] = $user;
  2064. }
  2065. return $return;
  2066. }
  2067. /**
  2068. * Get all information that the user with user_id = $user_data has
  2069. * entered in the additionally defined profile fields
  2070. * @param integer $user_id the id of the user
  2071. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  2072. * @version Dokeos 1.8.6
  2073. * @since November 2008
  2074. */
  2075. public static function get_user_overview_export_extra_fields($user_id)
  2076. {
  2077. // include the user manager
  2078. $extra_data = UserManager::get_extra_user_data($user_id, true);
  2079. return $extra_data;
  2080. }
  2081. /**
  2082. * Checks if a username exist in the DB otherwise it create a "double"
  2083. * i.e. if we look into for jmontoya but the user's name already exist we create the user jmontoya2
  2084. * the return array will be array(username=>'jmontoya', sufix='2')
  2085. * @param string firstname
  2086. * @param string lastname
  2087. * @param string username
  2088. * @return array with the username, the sufix
  2089. * @author Julio Montoya Armas
  2090. */
  2091. public static function make_username($firstname, $lastname, $username, $language = null, $encoding = null)
  2092. {
  2093. // if username exist
  2094. if (!UserManager::is_username_available($username) || empty($username)) {
  2095. $i = 0;
  2096. while (1) {
  2097. if ($i == 0) {
  2098. $sufix = '';
  2099. } else {
  2100. $sufix = $i;
  2101. }
  2102. $desired_username = UserManager::create_username(
  2103. $firstname,
  2104. $lastname,
  2105. $language,
  2106. $encoding
  2107. );
  2108. if (UserManager::is_username_available($desired_username.$sufix)) {
  2109. break;
  2110. } else {
  2111. $i++;
  2112. }
  2113. }
  2114. $username_array = array('username' => $desired_username , 'sufix' => $sufix);
  2115. return $username_array;
  2116. } else {
  2117. $username_array = array('username' => $username, 'sufix' => '');
  2118. return $username_array;
  2119. }
  2120. }
  2121. /**
  2122. * Checks if there are repeted users in a given array
  2123. * @param array $usernames list of the usernames in the uploaded file
  2124. * @param array $user_array['username'] and $user_array['sufix'] where sufix is the number part in a login i.e -> jmontoya2
  2125. * @return array with the $usernames array and the $user_array array
  2126. * @author Julio Montoya Armas
  2127. */
  2128. public static function check_user_in_array($usernames, $user_array)
  2129. {
  2130. $user_list = array_keys($usernames);
  2131. $username = $user_array['username'].$user_array['sufix'];
  2132. if (in_array($username, $user_list)) {
  2133. $user_array['sufix'] += $usernames[$username];
  2134. $usernames[$username]++;
  2135. } else {
  2136. $usernames[$username] = 1;
  2137. }
  2138. $result_array = array($usernames, $user_array);
  2139. return $result_array;
  2140. }
  2141. /**
  2142. * Checks whether a username has been already subscribed in a session.
  2143. * @param string a given username
  2144. * @param array the array with the course list id
  2145. * @param the session id
  2146. * @return 0 if the user is not subscribed otherwise it returns the user_id of the given username
  2147. * @author Julio Montoya
  2148. */
  2149. public static function user_available_in_session($username, $course_list, $id_session)
  2150. {
  2151. $table_user = Database::get_main_table(TABLE_MAIN_USER);
  2152. $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  2153. $id_session = intval($id_session);
  2154. $username = Database::escape_string($username);
  2155. foreach ($course_list as $courseId) {
  2156. $courseId = intval($courseId);
  2157. $sql = " SELECT u.user_id FROM $tbl_session_rel_course_rel_user rel
  2158. INNER JOIN $table_user u
  2159. ON (rel.user_id = u.user_id)
  2160. WHERE
  2161. rel.session_id='$id_session' AND
  2162. u.status='5' AND
  2163. u.username ='$username' AND
  2164. rel.c_id='$courseId'";
  2165. $rs = Database::query($sql);
  2166. if (Database::num_rows($rs) > 0) {
  2167. return Database::result($rs, 0, 0);
  2168. } else {
  2169. return 0;
  2170. }
  2171. }
  2172. }
  2173. /**
  2174. * This function checks whether some users in the uploaded file
  2175. * repeated and creates unique usernames if necesary.
  2176. * A case: Within the file there is an user repeted twice (Julio Montoya / Julio Montoya)
  2177. * and the username fields are empty.
  2178. * Then, this function would create unique usernames based on the first and the last name.
  2179. * Two users wiould be created - jmontoya and jmontoya2.
  2180. * Of course, if in the database there is a user with the name jmontoya,
  2181. * the newly created two users registered would be jmontoya2 and jmontoya3.
  2182. * @param $users list of users
  2183. * @author Julio Montoya Armas
  2184. */
  2185. function check_all_usernames($users, $course_list, $id_session)
  2186. {
  2187. $table_user = Database::get_main_table(TABLE_MAIN_USER);
  2188. $usernames = array();
  2189. $new_users = array();
  2190. foreach ($users as $index => $user) {
  2191. $desired_username = array();
  2192. if (empty($user['UserName'])) {
  2193. $desired_username = MySpace::make_username($user['FirstName'], $user['LastName'], '');
  2194. $pre_username = $desired_username['username'].$desired_username['sufix'];
  2195. $user['UserName'] = $pre_username;
  2196. $user['create'] = '1';
  2197. } else {
  2198. if (UserManager::is_username_available($user['UserName'])) {
  2199. $desired_username = MySpace::make_username($user['FirstName'], $user['LastName'], $user['UserName']);
  2200. $user['UserName'] = $desired_username['username'].$desired_username['sufix'];
  2201. $user['create'] = '1';
  2202. } else {
  2203. $is_session_avail = MySpace::user_available_in_session($user['UserName'], $course_list, $id_session);
  2204. if ($is_session_avail == 0) {
  2205. $user_name = $user['UserName'];
  2206. $sql_select = "SELECT user_id FROM $table_user WHERE username ='$user_name' ";
  2207. $rs = Database::query($sql_select);
  2208. $user['create'] = Database::result($rs, 0, 0); // This should be the ID because the user exists.
  2209. } else {
  2210. $user['create'] = $is_session_avail;
  2211. }
  2212. }
  2213. }
  2214. // Usernames is the current list of users in the file.
  2215. $result_array = MySpace::check_user_in_array($usernames, $desired_username);
  2216. $usernames = $result_array[0];
  2217. $desired_username = $result_array[1];
  2218. $user['UserName'] = $desired_username['username'].$desired_username['sufix'];
  2219. $new_users[] = $user;
  2220. }
  2221. return $new_users;
  2222. }
  2223. /**
  2224. * This functions checks whether there are users that are already
  2225. * registered in the DB by different creator than the current coach.
  2226. * @param string a given username
  2227. * @param array the array with the course list ids
  2228. * @param the session id
  2229. * @author Julio Montoya Armas
  2230. */
  2231. public function get_user_creator($users)
  2232. {
  2233. $errors = array();
  2234. foreach ($users as $index => $user) {
  2235. // database table definition
  2236. $table_user = Database::get_main_table(TABLE_MAIN_USER);
  2237. $username = Database::escape_string($user['UserName']);
  2238. $sql = "SELECT creator_id FROM $table_user WHERE username='$username' ";
  2239. $rs = Database::query($sql);
  2240. $creator_id = Database::result($rs, 0, 0);
  2241. // check if we are the creators or not
  2242. if ($creator_id != '') {
  2243. if ($creator_id != api_get_user_id()) {
  2244. $user['error'] = get_lang('UserAlreadyRegisteredByOtherCreator');
  2245. $errors[] = $user;
  2246. }
  2247. }
  2248. }
  2249. return $errors;
  2250. }
  2251. /**
  2252. * Validates imported data.
  2253. * @param list of users
  2254. */
  2255. function validate_data($users, $id_session = null)
  2256. {
  2257. $errors = array();
  2258. $new_users = array();
  2259. foreach ($users as $index => $user) {
  2260. // 1. Check whether mandatory fields are set.
  2261. $mandatory_fields = array('LastName', 'FirstName');
  2262. if (api_get_setting('registration', 'email') == 'true') {
  2263. $mandatory_fields[] = 'Email';
  2264. }
  2265. foreach ($mandatory_fields as $key => $field) {
  2266. if (!isset ($user[$field]) || strlen($user[$field]) == 0) {
  2267. $user['error'] = get_lang($field.'Mandatory');
  2268. $errors[] = $user;
  2269. }
  2270. }
  2271. // 2. Check whether the username is too long.
  2272. if (UserManager::is_username_too_long($user['UserName'])) {
  2273. $user['error'] = get_lang('UserNameTooLong');
  2274. $errors[] = $user;
  2275. }
  2276. $user['UserName'] = trim($user['UserName']);
  2277. if (empty($user['UserName'])) {
  2278. $user['UserName'] = UserManager::create_username($user['FirstName'], $user['LastName']);
  2279. }
  2280. $new_users[] = $user;
  2281. }
  2282. $results = array('errors' => $errors, 'users' => $new_users);
  2283. return $results;
  2284. }
  2285. /**
  2286. * Adds missing user-information (which isn't required, like password, etc).
  2287. */
  2288. function complete_missing_data($user) {
  2289. // 1. Generate a password if it is necessary.
  2290. if (!isset ($user['Password']) || strlen($user['Password']) == 0) {
  2291. $user['Password'] = api_generate_password();
  2292. }
  2293. return $user;
  2294. }
  2295. /**
  2296. * Saves imported data.
  2297. */
  2298. public function save_data($users, $course_list, $id_session)
  2299. {
  2300. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  2301. $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  2302. $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  2303. $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  2304. $id_session = intval($id_session);
  2305. $sendMail = $_POST['sendMail'] ? 1 : 0;
  2306. // Adding users to the platform.
  2307. $new_users = array();
  2308. foreach ($users as $index => $user) {
  2309. $user = MySpace::complete_missing_data($user);
  2310. // coach only will registered users
  2311. $default_status = STUDENT;
  2312. if ($user['create'] == COURSEMANAGER) {
  2313. $user['id'] = UserManager:: create_user(
  2314. $user['FirstName'],
  2315. $user['LastName'],
  2316. $default_status,
  2317. $user['Email'],
  2318. $user['UserName'],
  2319. $user['Password'],
  2320. $user['OfficialCode'],
  2321. api_get_setting('language.platform_language'),
  2322. $user['PhoneNumber'],
  2323. ''
  2324. );
  2325. $user['added_at_platform'] = 1;
  2326. } else {
  2327. $user['id'] = $user['create'];
  2328. $user['added_at_platform'] = 0;
  2329. }
  2330. $new_users[] = $user;
  2331. }
  2332. // Update user list.
  2333. $users = $new_users;
  2334. // Inserting users.
  2335. $super_list = array();
  2336. foreach ($course_list as $enreg_course) {
  2337. $nbr_users = 0;
  2338. $new_users = array();
  2339. $enreg_course = Database::escape_string($enreg_course);
  2340. foreach ($users as $index => $user) {
  2341. $userid = intval($user['id']);
  2342. $sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user(session_id, c_id, user_id)
  2343. VALUES('$id_session','$enreg_course','$userid')";
  2344. $course_session = array('course' => $enreg_course, 'added' => 1);
  2345. $result = Database::query($sql);
  2346. if (Database::affected_rows($result)) {
  2347. $nbr_users++;
  2348. }
  2349. $new_users[] = $user;
  2350. }
  2351. $super_list[] = $new_users;
  2352. //update the nbr_users field
  2353. $sql_select = "SELECT COUNT(user_id) as nbUsers FROM $tbl_session_rel_course_rel_user
  2354. WHERE session_id='$id_session' AND c_id='$enreg_course'";
  2355. $rs = Database::query($sql_select);
  2356. list($nbr_users) = Database::fetch_array($rs);
  2357. $sql_update = "UPDATE $tbl_session_rel_course SET nbr_users=$nbr_users
  2358. WHERE session_id='$id_session' AND c_id='$enreg_course'";
  2359. Database::query($sql_update);
  2360. $sql_update = "UPDATE $tbl_session SET nbr_users= '$nbr_users' WHERE id='$id_session'";
  2361. Database::query($sql_update);
  2362. }
  2363. $new_users = array();
  2364. foreach ($users as $index => $user) {
  2365. $userid = $user['id'];
  2366. $sql_insert = "INSERT IGNORE INTO $tbl_session_rel_user(session_id, user_id, registered_at)
  2367. VALUES ('$id_session','$userid', '" . api_get_utc_datetime() . "')";
  2368. Database::query($sql_insert);
  2369. $user['added_at_session'] = 1;
  2370. $new_users[] = $user;
  2371. }
  2372. $users = $new_users;
  2373. $registered_users = get_lang('FileImported').'<br /> Import file results : <br />';
  2374. // Sending emails.
  2375. $addedto = '';
  2376. if ($sendMail) {
  2377. $i = 0;
  2378. foreach ($users as $index => $user) {
  2379. $emailsubject = '['.api_get_setting(
  2380. 'platform.site_name'
  2381. ).'] '.get_lang('YourReg').' '.api_get_setting(
  2382. 'platform.site_name'
  2383. );
  2384. $emailbody = get_lang('Dear').' '.
  2385. api_get_person_name($user['FirstName'], $user['LastName']).",\n\n".
  2386. get_lang('YouAreReg')." ".api_get_setting(
  2387. 'platform.site_name'
  2388. )." ".get_lang('WithTheFollowingSettings')."\n\n".
  2389. get_lang('Username')." : $user[UserName]\n".
  2390. get_lang('Pass')." : $user[Password]\n\n".
  2391. get_lang('Address')." ".api_get_setting(
  2392. 'platform.site_name'
  2393. )." ".get_lang('Is')." : ".api_get_path(WEB_PATH)." \n\n".
  2394. get_lang('Problem')."\n\n".
  2395. get_lang('SignatureFormula').",\n\n".
  2396. api_get_person_name(
  2397. api_get_setting('admin.administrator_name'),
  2398. api_get_setting('admin.administrator_surname')
  2399. )."\n".
  2400. get_lang('Manager')." ".api_get_setting(
  2401. 'platform.site_name'
  2402. )."\nT. ".
  2403. api_get_setting(
  2404. 'admin.administrator_phone'
  2405. )."\n".get_lang('Email')." : ".api_get_setting(
  2406. 'admin.administrator_email'
  2407. );
  2408. api_mail_html(
  2409. api_get_person_name($user['FirstName'], $user['LastName'], null, PERSON_NAME_EMAIL_ADDRESS),
  2410. $user['Email'],
  2411. $emailsubject,
  2412. $emailbody
  2413. );
  2414. $userInfo = api_get_user_info($user['id']);
  2415. if (($user['added_at_platform'] == 1 && $user['added_at_session'] == 1) || $user['added_at_session'] == 1) {
  2416. if ($user['added_at_platform'] == 1) {
  2417. $addedto = get_lang('UserCreatedPlatform');
  2418. } else {
  2419. $addedto = ' ';
  2420. }
  2421. if ($user['added_at_session'] == 1) {
  2422. $addedto .= get_lang('UserInSession');
  2423. }
  2424. } else {
  2425. $addedto = get_lang('UserNotAdded');
  2426. }
  2427. $registered_users .= UserManager::getUserProfileLink($userInfo)." - ".$addedto.'<br />';
  2428. }
  2429. } else {
  2430. $i = 0;
  2431. foreach ($users as $index => $user) {
  2432. $userInfo = api_get_user_info($user['id']);
  2433. if (($user['added_at_platform'] == 1 && $user['added_at_session'] == 1) || $user['added_at_session'] == 1) {
  2434. if ($user['added_at_platform'] == 1) {
  2435. $addedto = get_lang('UserCreatedPlatform');
  2436. } else {
  2437. $addedto = ' ';
  2438. }
  2439. if ($user['added_at_session'] == 1) {
  2440. $addedto .= ' '.get_lang('UserInSession');
  2441. }
  2442. } else {
  2443. $addedto = get_lang('UserNotAdded');
  2444. }
  2445. $registered_users .= "<a href=\"../user/userInfo.php?uInfo=".$user['id']."\">".api_get_person_name($user['FirstName'], $user['LastName'])."</a> - ".$addedto.'<br />';
  2446. }
  2447. }
  2448. header('Location: course.php?id_session='.$id_session.'&action=show_message&message='.urlencode($registered_users));
  2449. exit;
  2450. }
  2451. /**
  2452. * Reads CSV-file.
  2453. * @param string $file Path to the CSV-file
  2454. * @return array All userinformation read from the file
  2455. */
  2456. function parse_csv_data($file) {
  2457. $users = Import :: csvToArray($file);
  2458. foreach ($users as $index => $user) {
  2459. if (isset ($user['Courses'])) {
  2460. $user['Courses'] = explode('|', trim($user['Courses']));
  2461. }
  2462. $users[$index] = $user;
  2463. }
  2464. return $users;
  2465. }
  2466. /**
  2467. * XML-parser: the handler at the beginning of element.
  2468. */
  2469. function element_start($parser, $data) {
  2470. $data = api_utf8_decode($data);
  2471. global $user;
  2472. global $current_tag;
  2473. switch ($data) {
  2474. case 'Contact' :
  2475. $user = array ();
  2476. break;
  2477. default :
  2478. $current_tag = $data;
  2479. }
  2480. }
  2481. /**
  2482. * XML-parser: the handler at the end of element.
  2483. */
  2484. function element_end($parser, $data) {
  2485. $data = api_utf8_decode($data);
  2486. global $user;
  2487. global $users;
  2488. global $current_value;
  2489. global $purification_option_for_usernames;
  2490. $user[$data] = $current_value;
  2491. switch ($data) {
  2492. case 'Contact' :
  2493. $user['UserName'] = UserManager::purify_username($user['UserName'], $purification_option_for_usernames);
  2494. $users[] = $user;
  2495. break;
  2496. default :
  2497. $user[$data] = $current_value;
  2498. break;
  2499. }
  2500. }
  2501. /**
  2502. * XML-parser: the handler for character data.
  2503. */
  2504. function character_data($parser, $data) {
  2505. $data = trim(api_utf8_decode($data));
  2506. global $current_value;
  2507. $current_value = $data;
  2508. }
  2509. /**
  2510. * Reads XML-file.
  2511. * @param string $file Path to the XML-file
  2512. * @return array All userinformation read from the file
  2513. */
  2514. function parse_xml_data($file) {
  2515. global $current_tag;
  2516. global $current_value;
  2517. global $user;
  2518. global $users;
  2519. $users = array ();
  2520. $parser = xml_parser_create('UTF-8');
  2521. xml_set_element_handler($parser, array('MySpace','element_start'), array('MySpace','element_end'));
  2522. xml_set_character_data_handler($parser, "character_data");
  2523. xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
  2524. xml_parse($parser, api_utf8_encode_xml(file_get_contents($file)));
  2525. xml_parser_free($parser);
  2526. return $users;
  2527. }
  2528. public static function displayTrackingAccessOverView($courseId, $sessionId, $studentId)
  2529. {
  2530. $courseId = intval($courseId);
  2531. $sessionId = intval($sessionId);
  2532. $studentId = intval($studentId);
  2533. $em = Database::getManager();
  2534. $sessionRepo = $em->getRepository('ChamiloCoreBundle:Session');
  2535. $courseList = [];
  2536. $sessionList = [];
  2537. $studentList = [];
  2538. if (!empty($courseId)) {
  2539. $course = $em->find('ChamiloCoreBundle:Course', $courseId);
  2540. $courseList[$course->getId()] = $course->getTitle();
  2541. }
  2542. if (!empty($sessionId)) {
  2543. $session = $em->find('ChamiloCoreBundle:Session', $sessionId);
  2544. $sessionList[$session->getId()] = $session->getName();
  2545. }
  2546. if (!empty($studentId)) {
  2547. $student = $em->find('ChamiloUserBundle:User', $studentId);
  2548. $studentList[$student->getId()] = $student->getCompleteName();
  2549. }
  2550. $form = new FormValidator('access_overview', 'GET');
  2551. $form->addElement(
  2552. 'select_ajax',
  2553. 'course_id',
  2554. get_lang('SearchCourse'),
  2555. $courseList,
  2556. [
  2557. 'url' => api_get_path(WEB_AJAX_PATH) . 'course.ajax.php?' . http_build_query([
  2558. 'a' => 'search_course_by_session_all',
  2559. 'session_id' => $sessionId
  2560. ])
  2561. ]
  2562. );
  2563. $form->addElement(
  2564. 'select_ajax',
  2565. 'session_id',
  2566. get_lang('SearchSession'),
  2567. $sessionList,
  2568. [
  2569. 'url_function' => "
  2570. function () {
  2571. var params = $.param({
  2572. a: 'search_session_by_course',
  2573. course_id: $('#course_id').val() || 0
  2574. });
  2575. return '" . api_get_path(WEB_AJAX_PATH) . "session.ajax.php?' + params;
  2576. }
  2577. "
  2578. ]
  2579. );
  2580. $form->addSelect(
  2581. 'profile',
  2582. get_lang('Profile'),
  2583. [
  2584. '' => get_lang('Select'),
  2585. STUDENT => get_lang('Student'),
  2586. COURSEMANAGER => get_lang('CourseManager'),
  2587. DRH => get_lang('Drh')
  2588. ],
  2589. ['id' => 'profile']
  2590. );
  2591. $form->addElement(
  2592. 'select_ajax',
  2593. 'student_id',
  2594. get_lang('SearchUsers'),
  2595. $studentList,
  2596. [
  2597. 'placeholder' => get_lang('All'),
  2598. 'url_function' => "
  2599. function () {
  2600. var params = $.param({
  2601. a: 'search_user_by_course',
  2602. session_id: $('#session_id').val(),
  2603. course_id: $('#course_id').val()
  2604. });
  2605. return '" . api_get_path(WEB_AJAX_PATH) . "course.ajax.php?' + params;
  2606. }
  2607. "
  2608. ]
  2609. );
  2610. $form->addDateRangePicker(
  2611. 'date',
  2612. get_lang('DateRange'),
  2613. true,
  2614. [
  2615. 'id' => 'date_range',
  2616. 'format' => 'YYYY-MM-DD',
  2617. 'timePicker' => 'false',
  2618. 'validate_format' => 'Y-m-d'
  2619. ]
  2620. );
  2621. $form->addHidden('display', 'accessoverview');
  2622. $form->addRule('course_id', get_lang('Required'), 'required');
  2623. $form->addRule('profile', get_lang('Required'), 'required');
  2624. $form->addButton('submit', get_lang('Generate'), 'gear', 'primary');
  2625. $table = null;
  2626. if ($form->validate()) {
  2627. $table = new SortableTable(
  2628. 'tracking_access_overview',
  2629. ['MySpace','getNumberOfRrackingAccessOverview'],
  2630. ['MySpace','getUserDataAccessTrackingOverview'],
  2631. 0
  2632. );
  2633. $table->additional_parameters = $form->exportValues();
  2634. $table->set_header(0, get_lang('LoginDate'), true);
  2635. $table->set_header(1, get_lang('Username'), true);
  2636. if (api_is_western_name_order()) {
  2637. $table->set_header(2, get_lang('FirstName'), true);
  2638. $table->set_header(3, get_lang('LastName'), true);
  2639. } else {
  2640. $table->set_header(2, get_lang('LastName'), true);
  2641. $table->set_header(3, get_lang('FirstName'), true);
  2642. }
  2643. $table->set_header(4, get_lang('Clicks'), false);
  2644. $table->set_header(5, get_lang('IP'), false);
  2645. $table->set_header(6, get_lang('TimeLoggedIn'), false);
  2646. }
  2647. $template = new Template(null, false, false, false, false, false, false);
  2648. $template->assign('form', $form->returnForm());
  2649. $template->assign('table', $table ? $table->return_table() : null);
  2650. echo $template->fetch(
  2651. $template->get_template('my_space/accessoverview.tpl')
  2652. );
  2653. }
  2654. public static function getNumberOfRrackingAccessOverview()
  2655. {
  2656. $track_e_course_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
  2657. return Database::count_rows($track_e_course_access);
  2658. }
  2659. public static function getUserDataAccessTrackingOverview($from, $numberItems, $column, $orderDirection)
  2660. {
  2661. $user = Database::get_main_table(TABLE_MAIN_USER);
  2662. $course = Database::get_main_table(TABLE_MAIN_COURSE);
  2663. $track_e_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
  2664. $track_e_course_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
  2665. global $export_csv;
  2666. if ($export_csv) {
  2667. $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
  2668. } else {
  2669. $is_western_name_order = api_is_western_name_order();
  2670. }
  2671. //TODO add course name
  2672. $sql = "SELECT
  2673. a.login_course_date as col0,
  2674. u.username as col1,
  2675. " . (
  2676. $is_western_name_order ? "
  2677. u.firstname AS col2,
  2678. u.lastname AS col3,
  2679. " : "
  2680. u.lastname AS col2,
  2681. u.firstname AS col3,
  2682. " ) . "
  2683. a.logout_course_date,
  2684. c.title,
  2685. c.code,
  2686. u.user_id
  2687. FROM $track_e_course_access a
  2688. INNER JOIN $user u ON a.user_id = u.user_id
  2689. INNER JOIN $course c ON a.c_id = c.id";
  2690. if (isset($_GET['session_id']) && !empty($_GET['session_id'])) {
  2691. $sessionId = intval($_GET['session_id']);
  2692. $sql .= " WHERE a.session_id = " . $sessionId;
  2693. }
  2694. $sql .= " ORDER BY col$column $orderDirection ";
  2695. $sql .= " LIMIT $from,$numberItems";
  2696. $result = Database::query($sql);
  2697. //$clicks = Tracking::get_total_clicks_by_session();
  2698. $data = array();
  2699. while ($user = Database::fetch_assoc($result)) {
  2700. $data[] = $user;
  2701. }
  2702. $return = [];
  2703. //TODO: Dont use numeric index
  2704. foreach ($data as $key => $info) {
  2705. $start_date = $info['col0'];
  2706. $end_date = $info['logout_course_date'];
  2707. $return[$info['user_id']] = array(
  2708. $start_date,
  2709. $info['col1'],
  2710. $info['col2'],
  2711. $info['col3'],
  2712. $info['user_id'],
  2713. 'ip',
  2714. //TODO is not correct/precise, it counts the time not logged between two loggins
  2715. gmdate("H:i:s", strtotime($end_date) - strtotime($start_date))
  2716. );
  2717. }
  2718. foreach ($return as $key => $info) {
  2719. $ipResult = Database::select(
  2720. 'user_ip',
  2721. $track_e_login,
  2722. ['where' => [
  2723. '? BETWEEN login_date AND logout_date' => $info[0]
  2724. ]],
  2725. 'first'
  2726. );
  2727. $return[$key][5] = $ipResult['user_ip'];
  2728. }
  2729. return $return;
  2730. }
  2731. }
  2732. /**
  2733. * @param $user_id
  2734. * @param int $courseId
  2735. * @param null $start_date
  2736. * @param null $end_date
  2737. * @return array
  2738. */
  2739. function get_stats($user_id, $courseId, $start_date = null, $end_date = null)
  2740. {
  2741. // Database table definitions
  2742. $tbl_track_course = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
  2743. $course_info = api_get_course_info_by_id($courseId);
  2744. if (!empty($course_info)) {
  2745. $strg_sd = "";
  2746. $strg_ed = "";
  2747. if ($start_date != null && $end_date != null){
  2748. $end_date = add_day_to( $end_date );
  2749. $strg_sd = "AND login_course_date BETWEEN '$start_date' AND '$end_date'";
  2750. $strg_ed = "AND logout_course_date BETWEEN '$start_date' AND '$end_date'";
  2751. }
  2752. $sql = 'SELECT
  2753. SEC_TO_TIME(avg(time_to_sec(timediff(logout_course_date,login_course_date)))) as avrg,
  2754. SEC_TO_TIME(sum(time_to_sec(timediff(logout_course_date,login_course_date)))) as total,
  2755. count(user_id) as times
  2756. FROM ' . $tbl_track_course . '
  2757. WHERE
  2758. user_id = ' . intval($user_id) . ' AND
  2759. c_id = ' . intval($courseId) . ' '.$strg_sd.' '.$strg_ed.' '.'
  2760. ORDER BY login_course_date ASC';
  2761. $rs = Database::query($sql);
  2762. $result = array();
  2763. if ($row = Database::fetch_array($rs)) {
  2764. $foo_avg = $row['avrg'];
  2765. $foo_total = $row['total'];
  2766. $foo_times = $row['times'];
  2767. $result = array('avg' => $foo_avg, 'total' => $foo_total, 'times' => $foo_times);
  2768. }
  2769. }
  2770. return $result;
  2771. }
  2772. function add_day_to($end_date) {
  2773. $foo_date = strtotime( $end_date );
  2774. $foo_date = strtotime(" +1 day", $foo_date);
  2775. $foo_date = date("Y-m-d", $foo_date);
  2776. return $foo_date;
  2777. }
  2778. /**
  2779. * Gets the connections to a course as an array of login and logout time
  2780. *
  2781. * @param int $user_id
  2782. * @param int $courseId
  2783. * @author Jorge Frisancho Jibaja
  2784. * @author Julio Montoya <gugli100@gmail.com> fixing the function
  2785. * @version OCT-22- 2010
  2786. * @return array
  2787. */
  2788. function get_connections_to_course_by_date($user_id, $courseId, $start_date, $end_date)
  2789. {
  2790. // Database table definitions
  2791. $tbl_track_course = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
  2792. $course_info = api_get_course_info_by_id($courseId);
  2793. $user_id = intval($user_id);
  2794. $courseId = intval($courseId);
  2795. $connections = array();
  2796. if (!empty($course_info)) {
  2797. $end_date = add_day_to($end_date);
  2798. $sql = "SELECT login_course_date, logout_course_date
  2799. FROM $tbl_track_course
  2800. WHERE
  2801. user_id = $user_id AND
  2802. c_id = $courseId AND
  2803. login_course_date BETWEEN '$start_date' AND '$end_date' AND
  2804. logout_course_date BETWEEN '$start_date' AND '$end_date'
  2805. ORDER BY login_course_date ASC";
  2806. $rs = Database::query($sql);
  2807. while ($row = Database::fetch_array($rs)) {
  2808. $login_date = $row['login_course_date'];
  2809. $logout_date = $row['logout_course_date'];
  2810. $timestamp_login_date = strtotime($login_date);
  2811. $timestamp_logout_date = strtotime($logout_date);
  2812. $connections[] = array(
  2813. 'login' => $timestamp_login_date,
  2814. 'logout' => $timestamp_logout_date
  2815. );
  2816. }
  2817. }
  2818. return $connections;
  2819. }
  2820. /**
  2821. *
  2822. *
  2823. * @param array
  2824. * @author Jorge Frisancho Jibaja
  2825. * @version OCT-22- 2010
  2826. * @return array
  2827. */
  2828. function convert_to_array($sql_result){
  2829. $result_to_print = '<table>';
  2830. foreach ($sql_result as $key => $data) {
  2831. $result_to_print .= '<tr><td>'.date('d-m-Y (H:i:s)', $data['login']).'</td><td>'.api_time_to_hms($data['logout'] - $data['login']).'</tr></td>'."\n";
  2832. }
  2833. $result_to_print .= '</table>';
  2834. $result_to_print = array("result"=>$result_to_print);
  2835. return $result_to_print;
  2836. }
  2837. /**
  2838. * Converte an array to a table in html
  2839. *
  2840. * @param array $sql_result
  2841. * @author Jorge Frisancho Jibaja
  2842. * @version OCT-22- 2010
  2843. * @return string
  2844. */
  2845. function convert_to_string($sql_result){
  2846. $result_to_print = '<table>';
  2847. if (!empty($sql_result)) {
  2848. foreach ($sql_result as $key => $data) {
  2849. $result_to_print .= '<tr><td>'.date('d-m-Y (H:i:s)', $data['login']).'</td><td>'.api_time_to_hms($data['logout'] - $data['login']).'</tr></td>'."\n";
  2850. }
  2851. }
  2852. $result_to_print .= '</table>';
  2853. return $result_to_print;
  2854. }
  2855. /**
  2856. * This function draw the graphic to be displayed on the user view as an image
  2857. *
  2858. * @param array $sql_result
  2859. * @param string $start_date
  2860. * @param string $end_date
  2861. * @param string $type
  2862. * @author Jorge Frisancho Jibaja
  2863. * @version OCT-22- 2010
  2864. * @return string
  2865. */
  2866. function grapher($sql_result, $start_date, $end_date, $type = "")
  2867. {
  2868. if (empty($start_date)) { $start_date =""; }
  2869. if (empty($end_date)) { $end_date =""; }
  2870. if ($type == ""){ $type = 'day'; }
  2871. $main_year = $main_month_year = $main_day = array();
  2872. // get last 8 days/months
  2873. $last_days = 5;
  2874. $last_months = 3;
  2875. for ($i = $last_days; $i >= 0; $i--) {
  2876. $main_day[date ('d-m-Y', mktime () - $i * 3600 * 24)] = 0;
  2877. }
  2878. for ($i = $last_months; $i >= 0; $i--) {
  2879. $main_month_year[date ('m-Y', mktime () - $i * 30 * 3600 * 24)] = 0;
  2880. }
  2881. $i = 0;
  2882. if (is_array($sql_result) && count($sql_result) > 0) {
  2883. foreach ($sql_result as $key => $data) {
  2884. //creating the main array
  2885. $main_month_year[date('m-Y', $data['login'])] += float_format(($data['logout'] - $data['login']) / 60, 0);
  2886. $main_day[date('d-m-Y', $data['login'])] += float_format(($data['logout'] - $data['login']) / 60, 0);
  2887. if ($i > 500) {
  2888. break;
  2889. }
  2890. $i++;
  2891. }
  2892. switch ($type) {
  2893. case 'day':
  2894. $main_date = $main_day;
  2895. break;
  2896. case 'month':
  2897. $main_date = $main_month_year;
  2898. break;
  2899. case 'year':
  2900. $main_date = $main_year;
  2901. break;
  2902. }
  2903. // the nice graphics :D
  2904. $labels = array_keys($main_date);
  2905. if (count($main_date) == 1) {
  2906. $labels = $labels[0];
  2907. $main_date = $main_date[$labels];
  2908. }
  2909. /* Create and populate the pData object */
  2910. $myData = new pData();
  2911. $myData->addPoints($main_date, 'Serie1');
  2912. if (count($main_date)!= 1) {
  2913. $myData->addPoints($labels, 'Labels');
  2914. $myData->setSerieDescription('Labels', 'Months');
  2915. $myData->setAbscissa('Labels');
  2916. }
  2917. $myData->setSerieWeight('Serie1', 1);
  2918. $myData->setSerieDescription('Serie1', get_lang('MyResults'));
  2919. $myData->setAxisName(0, get_lang('Minutes'));
  2920. $myData->loadPalette(api_get_path(SYS_CODE_PATH) . 'palettes/pchart/default.color', true);
  2921. // Cache definition
  2922. $cachePath = api_get_path(SYS_ARCHIVE_PATH);
  2923. $myCache = new pCache(array('CacheFolder' => substr($cachePath, 0, strlen($cachePath) - 1)));
  2924. $chartHash = $myCache->getHash($myData);
  2925. if ($myCache->isInCache($chartHash)) {
  2926. //if we already created the img
  2927. $imgPath = api_get_path(SYS_ARCHIVE_PATH) . $chartHash;
  2928. $myCache->saveFromCache($chartHash, $imgPath);
  2929. $imgPath = api_get_path(WEB_ARCHIVE_PATH) . $chartHash;
  2930. } else {
  2931. /* Define width, height and angle */
  2932. $mainWidth = 760;
  2933. $mainHeight = 230;
  2934. $angle = 50;
  2935. /* Create the pChart object */
  2936. $myPicture = new pImage($mainWidth, $mainHeight, $myData);
  2937. /* Turn of Antialiasing */
  2938. $myPicture->Antialias = false;
  2939. /* Draw the background */
  2940. $settings = array("R" => 255, "G" => 255, "B" => 255);
  2941. $myPicture->drawFilledRectangle(0, 0, $mainWidth, $mainHeight, $settings);
  2942. /* Add a border to the picture */
  2943. $myPicture->drawRectangle(
  2944. 0,
  2945. 0,
  2946. $mainWidth - 1,
  2947. $mainHeight - 1,
  2948. array("R" => 0, "G" => 0, "B" => 0)
  2949. );
  2950. /* Set the default font */
  2951. $myPicture->setFontProperties(
  2952. array(
  2953. "FontName" => api_get_path(SYS_FONTS_PATH) . 'opensans/OpenSans-Regular.ttf',
  2954. "FontSize" => 10)
  2955. );
  2956. /* Write the chart title */
  2957. $myPicture->drawText(
  2958. $mainWidth / 2,
  2959. 30,
  2960. get_lang('ExercisesInTimeProgressChart'),
  2961. array(
  2962. "FontSize" => 12,
  2963. "Align" => TEXT_ALIGN_BOTTOMMIDDLE
  2964. )
  2965. );
  2966. /* Set the default font */
  2967. $myPicture->setFontProperties(
  2968. array(
  2969. "FontName" => api_get_path(SYS_FONTS_PATH) . 'opensans/OpenSans-Regular.ttf',
  2970. "FontSize" => 8
  2971. )
  2972. );
  2973. /* Define the chart area */
  2974. $myPicture->setGraphArea(50, 40, $mainWidth - 40, $mainHeight - 80);
  2975. /* Draw the scale */
  2976. $scaleSettings = array(
  2977. 'XMargin' => 10,
  2978. 'YMargin' => 10,
  2979. 'Floating' => true,
  2980. 'GridR' => 200,
  2981. 'GridG' => 200,
  2982. 'GridB' => 200,
  2983. 'DrawSubTicks' => true,
  2984. 'CycleBackground' => true,
  2985. 'LabelRotation' => $angle,
  2986. 'Mode' => SCALE_MODE_ADDALL_START0,
  2987. );
  2988. $myPicture->drawScale($scaleSettings);
  2989. /* Turn on Antialiasing */
  2990. $myPicture->Antialias = true;
  2991. /* Enable shadow computing */
  2992. $myPicture->setShadow(
  2993. true,
  2994. array(
  2995. "X" => 1,
  2996. "Y" => 1,
  2997. "R" => 0,
  2998. "G" => 0,
  2999. "B" => 0,
  3000. "Alpha" => 10
  3001. )
  3002. );
  3003. /* Draw the line chart */
  3004. $myPicture->setFontProperties(
  3005. array(
  3006. "FontName" => api_get_path(SYS_FONTS_PATH) . 'opensans/OpenSans-Regular.ttf',
  3007. "FontSize" => 10
  3008. )
  3009. );
  3010. $myPicture->drawSplineChart();
  3011. $myPicture->drawPlotChart(
  3012. array(
  3013. "DisplayValues" => true,
  3014. "PlotBorder" => true,
  3015. "BorderSize" => 1,
  3016. "Surrounding" => -60,
  3017. "BorderAlpha" => 80
  3018. )
  3019. );
  3020. /* Do NOT Write the chart legend */
  3021. /* Write and save into cache */
  3022. $myCache->writeToCache($chartHash, $myPicture);
  3023. $imgPath = api_get_path(SYS_ARCHIVE_PATH) . $chartHash;
  3024. $myCache->saveFromCache($chartHash, $imgPath);
  3025. $imgPath = api_get_path(WEB_ARCHIVE_PATH) . $chartHash;
  3026. }
  3027. $html = '<img src="' . $imgPath . '">';
  3028. return $html;
  3029. } else {
  3030. $foo_img = api_convert_encoding('<div id="messages" class="warning-message">'.get_lang('GraphicNotAvailable').'</div>','UTF-8');
  3031. return $foo_img;
  3032. }
  3033. }