exercice.php 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Exercise list: This script shows the list of exercises for administrators and students.
  5. * @package chamilo.exercise
  6. * @author Olivier Brouckaert, original author
  7. * @author Denes Nagy, HotPotatoes integration
  8. * @author Wolfgang Schneider, code/html cleanup
  9. * @author Julio Montoya <gugli100@gmail.com>, lots of cleanup + several improvements
  10. */
  11. /**
  12. * Code
  13. */
  14. // name of the language file that needs to be included
  15. $language_file = array('exercice','tracking');
  16. // including the global library
  17. require_once '../inc/global.inc.php';
  18. require_once '../gradebook/lib/be.inc.php';
  19. // Setting the tabs
  20. $this_section = SECTION_COURSES;
  21. $htmlHeadXtra[] = api_get_jquery_ui_js();
  22. // Access control
  23. api_protect_course_script(true);
  24. $show = (isset ($_GET['show']) && $_GET['show'] == 'result') ? 'result' : 'test'; // moved down to fix bug: http://www.dokeos.com/forum/viewtopic.php?p=18609#18609
  25. // including additional libraries
  26. require_once 'exercise.class.php';
  27. require_once 'exercise.lib.php';
  28. require_once 'question.class.php';
  29. require_once 'answer.class.php';
  30. require_once api_get_path(LIBRARY_PATH) . 'fileManage.lib.php';
  31. require_once api_get_path(LIBRARY_PATH) . 'fileUpload.lib.php';
  32. require_once 'hotpotatoes.lib.php';
  33. require_once api_get_path(LIBRARY_PATH) . 'document.lib.php';
  34. require_once api_get_path(LIBRARY_PATH) . 'mail.lib.inc.php';
  35. require_once api_get_path(LIBRARY_PATH) . 'usermanager.lib.php';
  36. /* Constants and variables */
  37. $is_allowedToEdit = api_is_allowed_to_edit(null,true);
  38. $is_tutor = api_is_allowed_to_edit(true);
  39. $is_tutor_course = api_is_course_tutor();
  40. $tbl_course_rel_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  41. $TBL_USER = Database :: get_main_table(TABLE_MAIN_USER);
  42. $TBL_DOCUMENT = Database :: get_course_table(TABLE_DOCUMENT);
  43. $TBL_ITEM_PROPERTY = Database :: get_course_table(TABLE_ITEM_PROPERTY);
  44. $TBL_EXERCICE_ANSWER = Database :: get_course_table(TABLE_QUIZ_ANSWER);
  45. $TBL_EXERCICE_QUESTION = Database :: get_course_table(TABLE_QUIZ_TEST_QUESTION);
  46. $TBL_EXERCICES = Database :: get_course_table(TABLE_QUIZ_TEST);
  47. $TBL_QUESTIONS = Database :: get_course_table(TABLE_QUIZ_QUESTION);
  48. $TBL_TRACK_EXERCICES = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
  49. $TBL_TRACK_HOTPOTATOES = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_HOTPOTATOES);
  50. $TBL_TRACK_ATTEMPT = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
  51. $TBL_TRACK_ATTEMPT_RECORDING= Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING);
  52. $TBL_LP_ITEM_VIEW = Database :: get_course_table(TABLE_LP_ITEM_VIEW);
  53. $TBL_LP_ITEM = Database :: get_course_table(TABLE_LP_ITEM);
  54. $TBL_LP_VIEW = Database :: get_course_table(TABLE_LP_VIEW);
  55. // document path
  56. $documentPath = api_get_path(SYS_COURSE_PATH) . $_course['path'] . "/document";
  57. // picture path
  58. $picturePath = $documentPath . '/images';
  59. // audio path
  60. $audioPath = $documentPath . '/audio';
  61. // hotpotatoes
  62. $uploadPath = DIR_HOTPOTATOES; //defined in main_api
  63. $exercicePath = api_get_self();
  64. $exfile = explode('/', $exercicePath);
  65. $exfile = strtolower($exfile[sizeof($exfile) - 1]);
  66. $exercicePath = substr($exercicePath, 0, strpos($exercicePath, $exfile));
  67. $exercicePath = $exercicePath . "exercice.php";
  68. if ($show == 'result') {
  69. if (empty($_GET['exerciseId']) && empty($_GET['path']) ) {
  70. //header('Location: exercice.php?' . api_get_cidreq());
  71. }
  72. }
  73. // Clear the exercise session
  74. if (isset ($_SESSION['objExercise'])) {
  75. api_session_unregister('objExercise');
  76. }
  77. if (isset ($_SESSION['objQuestion'])) {
  78. api_session_unregister('objQuestion');
  79. }
  80. if (isset ($_SESSION['objAnswer'])) {
  81. api_session_unregister('objAnswer');
  82. }
  83. if (isset ($_SESSION['questionList'])) {
  84. api_session_unregister('questionList');
  85. }
  86. if (isset ($_SESSION['exerciseResult'])) {
  87. api_session_unregister('exerciseResult');
  88. }
  89. //General POST/GET/SESSION/COOKIES parameters recovery
  90. if (empty ($origin)) {
  91. $origin = Security::remove_XSS($_REQUEST['origin']);
  92. }
  93. if (empty ($choice)) {
  94. $choice = $_REQUEST['choice'];
  95. }
  96. if (empty ($hpchoice)) {
  97. $hpchoice = $_REQUEST['hpchoice'];
  98. }
  99. if (empty ($exerciseId)) {
  100. $exerciseId = intval($_REQUEST['exerciseId']);
  101. }
  102. if (empty ($file)) {
  103. $file = Database :: escape_string($_REQUEST['file']);
  104. }
  105. $learnpath_id = intval($_REQUEST['learnpath_id']);
  106. $learnpath_item_id = intval($_REQUEST['learnpath_item_id']);
  107. $page = intval($_REQUEST['page']);
  108. if ($page < 0) {
  109. $page = 1;
  110. }
  111. if ($origin == 'learnpath') {
  112. $show = 'result';
  113. }
  114. //Deleting an attempt
  115. if ($_GET['delete'] == 'delete' && ($is_allowedToEdit || api_is_coach()) && !empty ($_GET['did']) && $_GET['did'] == strval(intval($_GET['did']))) {
  116. $sql = 'DELETE FROM ' . Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES) . ' WHERE exe_id = ' . $_GET['did']; //_GET[did] filtered by entry condition
  117. Database::query($sql);
  118. $filter=Security::remove_XSS($_GET['filter']);
  119. header('Location: exercice.php?cidReq=' . Security::remove_XSS($_GET['cidReq']) . '&show=result&filter=' . $filter . '&exerciseId='.$exerciseId);
  120. exit;
  121. }
  122. //Send student email @todo move this code in a class, library
  123. if ($show == 'result' && $_REQUEST['comments'] == 'update' && ($is_allowedToEdit || $is_tutor) && $_GET['exeid']== strval(intval($_GET['exeid']))) {
  124. $id = intval($_GET['exeid']); //filtered by post-condition
  125. $track_exercise_info = get_exercise_track_exercise_info($id);
  126. if (empty($track_exercise_info)) {
  127. api_not_allowed();
  128. }
  129. $test = $track_exercise_info['title'];
  130. $student_id = $track_exercise_info['exe_user_id'];
  131. $course_id = $track_exercise_info['exe_cours_id'];
  132. $session_id = $track_exercise_info['session_id'];
  133. $lp_id = $track_exercise_info['orig_lp_id'];
  134. $lp_item_id = $track_exercise_info['orig_lp_item_id'];
  135. $lp_item_view_id = $track_exercise_info['orig_lp_item_view_id'];
  136. // Teacher data
  137. $teacher_info = api_get_user_info(api_get_user_id());
  138. $user_info = api_get_user_info($student_id);
  139. $student_email = $user_info['mail'];
  140. $from = $teacher_info['mail'];
  141. $from_name = api_get_person_name($teacher_info['firstname'], $teacher_info['lastname'], null, PERSON_NAME_EMAIL_ADDRESS);
  142. $url = api_get_path(WEB_CODE_PATH) . 'exercice/exercice.php?' . api_get_cidreq() . '&id_session='.$session_id.'&show=result&exerciseId='.$exerciseId;
  143. $my_post_info = array();
  144. $post_content_id = array();
  145. $comments_exist = false;
  146. foreach ($_POST as $key_index=>$key_value) {
  147. $my_post_info = explode('_',$key_index);
  148. $post_content_id[]=$my_post_info[1];
  149. if ($my_post_info[0]=='comments') {
  150. $comments_exist=true;
  151. }
  152. }
  153. $loop_in_track=($comments_exist===true) ? (count($_POST)/2) : count($_POST);
  154. $array_content_id_exe=array();
  155. if ($comments_exist===true) {
  156. $array_content_id_exe = array_slice($post_content_id,$loop_in_track);
  157. } else {
  158. $array_content_id_exe = $post_content_id;
  159. }
  160. for ($i=0;$i<$loop_in_track;$i++) {
  161. $my_marks = Database::escape_string($_POST['marks_'.$array_content_id_exe[$i]]);
  162. $contain_comments = Database::escape_string($_POST['comments_'.$array_content_id_exe[$i]]);
  163. if (isset($contain_comments)) {
  164. $my_comments = Database::escape_string($_POST['comments_'.$array_content_id_exe[$i]]);
  165. } else {
  166. $my_comments = '';
  167. }
  168. $my_questionid=$array_content_id_exe[$i];
  169. $sql = "SELECT question from $TBL_QUESTIONS WHERE id = '$my_questionid'";
  170. $result =Database::query($sql);
  171. $ques_name = Database::result($result,0,"question");
  172. $query = "UPDATE $TBL_TRACK_ATTEMPT SET marks = '$my_marks',teacher_comment = '$my_comments' WHERE question_id = ".$my_questionid." AND exe_id=".$id;
  173. Database::query($query);
  174. //Saving results in the track recording table
  175. $recording_changes = 'INSERT INTO '.$TBL_TRACK_ATTEMPT_RECORDING.' (exe_id, question_id, marks, insert_date, author, teacher_comment) VALUES
  176. ('."'$id','".$my_questionid."','$my_marks','".api_get_utc_datetime()."','".api_get_user_id()."'".',"'.$my_comments.'")';
  177. Database::query($recording_changes);
  178. }
  179. $qry = 'SELECT DISTINCT question_id, marks FROM ' . $TBL_TRACK_ATTEMPT . ' where exe_id = '.$id .' GROUP BY question_id';
  180. $res = Database::query($qry);
  181. $tot = 0;
  182. while ($row = Database :: fetch_array($res, 'ASSOC')) {
  183. $tot += $row['marks'];
  184. }
  185. $totquery = "UPDATE $TBL_TRACK_EXERCICES SET exe_result = '".floatval($tot)."' WHERE exe_id = ".$id;
  186. Database::query($totquery);
  187. //@todo move this somewhere else
  188. $subject = get_lang('ExamSheetVCC');
  189. $course_info = api_get_course_info();
  190. $message = '<p>'.get_lang('DearStudentEmailIntroduction') . '</p><p>'.get_lang('AttemptVCC');
  191. $message .= '<h3>'.get_lang('CourseName'). '</h3><p>'.Security::remove_XSS($course_info['name']).'';
  192. $message .= '<h3>'.get_lang('Exercise') . '</h3><p>'.Security::remove_XSS($test);
  193. //Only for exercises not in a LP
  194. if ($lp_id == 0) {
  195. $message .= '<p>'.get_lang('ClickLinkToViewComment') . ' <a href="#url#">#url#</a><br />';
  196. }
  197. $message .= '<p>'.get_lang('Regards') . ' </p>';
  198. $message .= $from_name;
  199. $message = str_replace("#test#", Security::remove_XSS($test), $message);
  200. $message = str_replace("#url#", $url, $message);
  201. @api_mail_html($student_email, $student_email, $subject, $message, $from_name, $from, array('charset'=>api_get_system_encoding()));
  202. //Updating LP score here
  203. if (in_array($origin, array ('tracking_course','user_course','correct_exercise_in_lp'))) {
  204. $sql_update_score = "UPDATE $TBL_LP_ITEM_VIEW SET score = '" . floatval($tot) . "' WHERE id = " .$lp_item_view_id;
  205. Database::query($sql_update_score);
  206. if ($origin == 'tracking_course') {
  207. //Redirect to the course detail in lp
  208. header('location: exercice.php?course=' . Security :: remove_XSS($_GET['course']));
  209. exit;
  210. } else {
  211. //Redirect to the reporting
  212. header('location: ../mySpace/myStudents.php?origin=' . $origin . '&student=' . $student_id . '&details=true&course=' . $course_id.'&session_id='.$session_id);
  213. exit;
  214. }
  215. }
  216. }
  217. if (!empty($_GET['gradebook']) && $_GET['gradebook']=='view' ) {
  218. $_SESSION['gradebook']=Security::remove_XSS($_GET['gradebook']);
  219. $gradebook= $_SESSION['gradebook'];
  220. } elseif (empty($_GET['gradebook'])) {
  221. unset($_SESSION['gradebook']);
  222. $gradebook= '';
  223. }
  224. if (!empty($gradebook) && $gradebook=='view') {
  225. $interbreadcrumb[] = array ('url' => '../gradebook/' . $_SESSION['gradebook_dest'],'name' => get_lang('ToolGradebook'));
  226. }
  227. if ($show != 'result') {
  228. $nameTools = get_lang('Exercices');
  229. } else {
  230. if ($is_allowedToEdit || $is_tutor) {
  231. $nameTools = get_lang('StudentScore');
  232. $interbreadcrumb[] = array("url" => "exercice.php?gradebook=$gradebook","name" => get_lang('Exercices'));
  233. $objExerciseTmp = new Exercise();
  234. if ($objExerciseTmp->read($exerciseId)) {
  235. $interbreadcrumb[] = array("url" => "admin.php?exerciseId=".$exerciseId, "name" => $objExerciseTmp->name);
  236. }
  237. } else {
  238. $nameTools = get_lang('YourScore');
  239. $interbreadcrumb[] = array ("url" => "exercice.php?gradebook=$gradebook","name" => get_lang('Exercices'));
  240. }
  241. }
  242. // need functions of statsutils lib to display previous exercices scores
  243. require_once api_get_path(LIBRARY_PATH) . 'statsUtils.lib.inc.php';
  244. if ($is_allowedToEdit && !empty ($choice) && $choice == 'exportqti2') {
  245. require_once 'export/qti2/qti2_export.php';
  246. $export = export_exercise($exerciseId, true);
  247. require_once api_get_path(LIBRARY_PATH) . 'pclzip/pclzip.lib.php';
  248. $archive_path = api_get_path(SYS_ARCHIVE_PATH);
  249. $temp_dir_short = api_get_unique_id();
  250. $temp_zip_dir = $archive_path . "/" . $temp_dir_short;
  251. if (!is_dir($temp_zip_dir))
  252. mkdir($temp_zip_dir, api_get_permissions_for_new_directories());
  253. $temp_zip_file = $temp_zip_dir . "/" . api_get_unique_id() . ".zip";
  254. $temp_xml_file = $temp_zip_dir . "/qti2export_" . $exerciseId . '.xml';
  255. file_put_contents($temp_xml_file, $export);
  256. $zip_folder = new PclZip($temp_zip_file);
  257. $zip_folder->add($temp_xml_file, PCLZIP_OPT_REMOVE_ALL_PATH);
  258. $name = 'qti2_export_' . $exerciseId . '.zip';
  259. //DocumentManager::string_send_for_download($export,true,'qti2export_'.$exerciseId.'.xml');
  260. DocumentManager :: file_send_for_download($temp_zip_file, true, $name);
  261. unlink($temp_zip_file);
  262. unlink($temp_xml_file);
  263. rmdir($temp_zip_dir);
  264. exit; //otherwise following clicks may become buggy
  265. }
  266. if (!empty ($_GET['extra_data'])) {
  267. switch ($_GET['extra_data']) {
  268. case 'on' :
  269. $_SESSION['export_user_fields'] = true;
  270. break;
  271. default :
  272. $_SESSION['export_user_fields'] = false;
  273. break;
  274. }
  275. }
  276. if (!empty($_GET['export_report']) && $_GET['export_report'] == '1') {
  277. if (api_is_platform_admin() || api_is_course_admin() || api_is_course_tutor() || api_is_course_coach()) {
  278. $user_id = null;
  279. if (empty($_SESSION['export_user_fields']))
  280. $_SESSION['export_user_fields'] = false;
  281. if (!$is_allowedToEdit and !$is_tutor) {
  282. $user_id = api_get_user_id();
  283. }
  284. require_once 'exercise_result.class.php';
  285. switch ($_GET['export_format']) {
  286. case 'xls' :
  287. $export = new ExerciseResult();
  288. $export->exportCompleteReportXLS($documentPath, $user_id, $_SESSION['export_user_fields'], $_GET['export_filter'], $_GET['exerciseId'], $_GET['hotpotato_name']);
  289. exit;
  290. break;
  291. case 'csv' :
  292. default :
  293. $export = new ExerciseResult();
  294. $export->exportCompleteReportCSV($documentPath, $user_id, $_SESSION['export_user_fields'], $_GET['export_filter'], $_GET['exerciseId'], $_GET['hotpotato_name']);
  295. exit;
  296. break;
  297. }
  298. } else {
  299. api_not_allowed(true);
  300. }
  301. }
  302. if ($origin != 'learnpath') {
  303. //so we are not in learnpath tool
  304. Display :: display_header($nameTools, get_lang('Exercise'));
  305. if (isset ($_GET['message'])) {
  306. if (in_array($_GET['message'], array ('ExerciseEdited'))) {
  307. Display :: display_confirmation_message(get_lang($_GET['message']));
  308. }
  309. }
  310. } else {
  311. echo '<link rel="stylesheet" type="text/css" href="' . api_get_path(WEB_CODE_PATH) . 'css/default.css"/>';
  312. }
  313. event_access_tool(TOOL_QUIZ);
  314. // Tool introduction
  315. Display :: display_introduction_section(TOOL_QUIZ);
  316. HotPotGCt($documentPath, 1, api_get_user_id() );
  317. // only for administrator
  318. if ($is_allowedToEdit) {
  319. if (!empty($choice)) {
  320. // construction of Exercise
  321. $objExerciseTmp = new Exercise();
  322. $check = Security::check_token('get');
  323. if ($objExerciseTmp->read($exerciseId)) {
  324. if ($check) {
  325. switch ($choice) {
  326. case 'delete' : // deletes an exercise
  327. $objExerciseTmp->delete();
  328. require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/gradebook_functions.inc.php';
  329. $link_id = is_resource_in_course_gradebook(api_get_course_id(), 1 , $exerciseId, api_get_session_id());
  330. if ($link_id !== false) {
  331. remove_resource_from_course_gradebook($link_id);
  332. }
  333. Display :: display_confirmation_message(get_lang('ExerciseDeleted'));
  334. break;
  335. case 'enable' : // enables an exercise
  336. $objExerciseTmp->enable();
  337. $objExerciseTmp->save();
  338. // "WHAT'S NEW" notification: update table item_property (previously last_tooledit)
  339. Display :: display_confirmation_message(get_lang('VisibilityChanged'));
  340. break;
  341. case 'disable' : // disables an exercise
  342. $objExerciseTmp->disable();
  343. $objExerciseTmp->save();
  344. Display :: display_confirmation_message(get_lang('VisibilityChanged'));
  345. break;
  346. case 'disable_results' : //disable the results for the learners
  347. $objExerciseTmp->disable_results();
  348. $objExerciseTmp->save();
  349. Display :: display_confirmation_message(get_lang('ResultsDisabled'));
  350. break;
  351. case 'enable_results' : //disable the results for the learners
  352. $objExerciseTmp->enable_results();
  353. $objExerciseTmp->save();
  354. Display :: display_confirmation_message(get_lang('ResultsEnabled'));
  355. break;
  356. case 'clean_results' : //clean student results
  357. $quantity_results_deleted= $objExerciseTmp->clean_results();
  358. Display :: display_confirmation_message(sprintf(get_lang('XResultsCleaned'),$quantity_results_deleted));
  359. break;
  360. case 'copy_exercise' : //copy an exercise
  361. $objExerciseTmp->copy_exercise();
  362. Display :: display_confirmation_message(get_lang('ExerciseCopied'));
  363. break;
  364. }
  365. }
  366. }
  367. // destruction of Exercise
  368. unset ($objExerciseTmp);
  369. Security::clear_token();
  370. }
  371. if (!empty($hpchoice)) {
  372. switch($hpchoice) {
  373. case 'delete' : // deletes an exercise
  374. $imgparams = array ();
  375. $imgcount = 0;
  376. GetImgParams($file, $documentPath, $imgparams, $imgcount);
  377. $fld = GetFolderName($file);
  378. for ($i = 0; $i < $imgcount; $i++) {
  379. my_delete($documentPath . $uploadPath . "/" . $fld . "/" . $imgparams[$i]);
  380. update_db_info("delete", $uploadPath . "/" . $fld . "/" . $imgparams[$i]);
  381. }
  382. if (my_delete($documentPath . $file)) {
  383. update_db_info("delete", $file);
  384. }
  385. my_delete($documentPath . $uploadPath . "/" . $fld . "/");
  386. break;
  387. case 'enable' : // enables an exercise
  388. $newVisibilityStatus = "1"; //"visible"
  389. $query = "SELECT id FROM $TBL_DOCUMENT WHERE path='" . Database :: escape_string($file) . "'";
  390. $res = Database::query($query);
  391. $row = Database :: fetch_array($res, 'ASSOC');
  392. api_item_property_update($_course, TOOL_DOCUMENT, $row['id'], 'visible', $_user['user_id']);
  393. //$dialogBox = get_lang('ViMod');
  394. break;
  395. case 'disable' : // disables an exercise
  396. $newVisibilityStatus = "0"; //"invisible"
  397. $query = "SELECT id FROM $TBL_DOCUMENT WHERE path='" . Database :: escape_string($file) . "'";
  398. $res = Database::query($query);
  399. $row = Database :: fetch_array($res, 'ASSOC');
  400. api_item_property_update($_course, TOOL_DOCUMENT, $row['id'], 'invisible', $_user['user_id']);
  401. break;
  402. default :
  403. break;
  404. }
  405. }
  406. }
  407. // Actions div bar
  408. if ($is_allowedToEdit) {
  409. echo '<div class="actions">';
  410. } elseif ($show == 'result') {
  411. echo '<div class="actions">';
  412. }
  413. // Selects $limit exercises at the same time
  414. // maximum number of exercises on a same page
  415. $limit = 50;
  416. // Display the next and previous link if needed
  417. $from = $page * $limit;
  418. HotPotGCt($documentPath, 1, api_get_user_id());
  419. //condition for the session
  420. $session_id = api_get_session_id();
  421. $condition_session = api_get_session_condition($session_id,true,true);
  422. if ($show == 'test') {
  423. // Only for administrators
  424. if ($is_allowedToEdit) {
  425. $total_sql = "SELECT count(id) as count FROM $TBL_EXERCICES WHERE active<>'-1' $condition_session ";
  426. $sql = "SELECT * FROM $TBL_EXERCICES WHERE active<>'-1' $condition_session ORDER BY title LIMIT ".$from."," .$limit;
  427. } else {
  428. // Only for students
  429. $total_sql = "SELECT count(id) as count FROM $TBL_EXERCICES WHERE active = '1' $condition_session ";
  430. $sql = "SELECT id, title, type, description, results_disabled, session_id, start_time, end_time, max_attempt FROM $TBL_EXERCICES
  431. WHERE active='1' $condition_session
  432. ORDER BY title LIMIT ".$from."," .$limit;
  433. }
  434. $result = Database::query($sql);
  435. $exercises_count = Database :: num_rows($result);
  436. $result_total = Database::query($total_sql);
  437. $total_exercises = 0;
  438. if (Database :: num_rows($result_total)) {
  439. $result_total = Database::fetch_array($result_total);
  440. $total_exercises = $result_total['count'];
  441. }
  442. //get HotPotatoes files (active and inactive)
  443. if ($is_allowedToEdit) {
  444. $sql = "SELECT * FROM $TBL_DOCUMENT WHERE path LIKE '" . Database :: escape_string($uploadPath) . "/%/%'";
  445. $res = Database::query($sql);
  446. $hp_count = Database :: num_rows($res);
  447. } else {
  448. $res = Database::query("SELECT * FROM $TBL_DOCUMENT d, $TBL_ITEM_PROPERTY ip
  449. WHERE d.id = ip.ref AND ip.tool = '" . TOOL_DOCUMENT . "'
  450. AND d.path LIKE '" . Database :: escape_string($uploadPath) . "/%/%'
  451. AND ip.visibility='1'");
  452. $hp_count = Database :: num_rows($res);
  453. }
  454. $total = $total_exercises + $hp_count;
  455. }
  456. if ($is_allowedToEdit && $origin != 'learnpath') {
  457. if ($show != 'result') {
  458. echo '<a href="exercise_admin.php?' . api_get_cidreq() . '">' . Display :: return_icon('new_exercice.png', get_lang('NewEx'),'','32').'</a>';
  459. echo '<a href="question_create.php?' . api_get_cidreq() . '">' . Display :: return_icon('new_question.png', get_lang('AddQ'),'','32').'</a>';
  460. echo '<a href="hotpotatoes.php?' . api_get_cidreq() . '">' . Display :: return_icon('import_hotpotatoes.png', get_lang('ImportHotPotatoesQuiz'),'','32').'</a>';
  461. // link to import qti2 ...
  462. echo '<a href="qti2.php?' . api_get_cidreq() . '">' . Display :: return_icon('import_qti2.png', get_lang('ImportQtiQuiz'),'','32') .'</a>';
  463. echo '<a href="upload_exercise.php?' . api_get_cidreq() . '">' . Display :: return_icon('import_excel.png', get_lang('ImportExcelQuiz'),'','32') .'</a>';
  464. }
  465. // the actions for the statistics
  466. if ($show == 'result') {
  467. // the form
  468. if (api_is_platform_admin() || api_is_course_admin() || api_is_course_tutor() || api_is_course_coach()) {
  469. if ($_SESSION['export_user_fields']) {
  470. $alt = get_lang('ExportWithUserFields');
  471. $extra_user_fields = '<input type="hidden" name="export_user_fields" value="export_user_fields">';
  472. } else {
  473. $alt = get_lang('ExportWithoutUserFields');
  474. $extra_user_fields = '<input type="hidden" name="export_user_fields" value="do_not_export_user_fields">';
  475. }
  476. echo '<a href="admin.php?exerciseId='.intval($_GET['exerciseId']).'">' . Display :: return_icon('back.png', get_lang('GoBackToQuestionList'),'','32').'</a>';
  477. echo '<script type="text/javascript">
  478. $(document).ready(function() {
  479. $( "#dialog:ui-dialog" ).dialog( "destroy" );
  480. $( "#dialog-confirm" ).dialog({
  481. autoOpen: false,
  482. show: "blind",
  483. resizable: false,
  484. height:250,
  485. modal: true
  486. });
  487. $("#export_opener").click(function() {
  488. var targetUrl = $(this).attr("href");
  489. $( "#dialog-confirm" ).dialog({
  490. width:350,
  491. height:220,
  492. buttons: {
  493. "'.addslashes(get_lang('Download')).'": function() {
  494. var export_format = $("input[name=export_format]:checked").val();
  495. var extra_data = $("input[name=load_extra_data]:checked").val();
  496. location.href = targetUrl+"&export_format="+export_format+"&extra_data="+extra_data;
  497. $( this ).dialog( "close" );
  498. },
  499. }
  500. });
  501. $( "#dialog-confirm" ).dialog("open");
  502. return false;
  503. });
  504. });
  505. </script>';
  506. echo '<div id="dialog-confirm" title="'.get_lang("ConfirmYourChoice").'">';
  507. //echo Display::tag('p', get_lang("CSVOrExcel"));
  508. //Display::return_icon('export_excel.png', get_lang('ExportAsXLS'),'','32')
  509. echo Display::tag('p', Display::input('radio', 'export_format', 'csv', array('checked'=>'1', 'id'=>'export_format_csv_label')). Display::tag('label', get_lang('ExportAsCSV'), array('for'=>'export_format_csv_label')));
  510. echo Display::tag('p', Display::input('radio', 'export_format', 'xls', array('id'=>'export_format_xls_label')). Display::tag('label', get_lang('ExportAsXLS'), array('for'=>'export_format_xls_label')));
  511. echo Display::tag('p', Display::input('checkbox', 'load_extra_data', '0',array('id'=>'load_extra_data_id')). Display::tag('label', get_lang('LoadExtraData'), array('for'=>'load_extra_data_id')));
  512. echo '</div>';
  513. if ($_GET['filter'] == '1' or !isset ($_GET['filter']) or $_GET['filter'] == 0 ) {
  514. $filter = 1;
  515. } else {
  516. $filter = 2;
  517. }
  518. echo '<a id="export_opener" href="'.api_get_self().'?export_report=1&show=result&export_filter='.$filter.'&hotpotato_name='.Security::remove_XSS($_GET['path']).'&exerciseId='.intval($_GET['exerciseId']).'" >'.
  519. Display::return_icon('save.png', get_lang('Export'),'',32).'</a>';
  520. }
  521. }
  522. } else {
  523. //Student view
  524. if ($show == 'result') {
  525. echo '<a href="' . api_add_url_param($_SERVER['REQUEST_URI'], 'show=test') . '">' . Display :: return_icon('back.png', get_lang('GoBackToQuestionList'),'','32').'</a>';
  526. }
  527. }
  528. if ($show == 'result') {
  529. if (api_is_allowed_to_edit(null,true)) {
  530. if (!$_GET['filter']) {
  531. $filter_by_not_revised = true;
  532. $filter = 1;
  533. } else {
  534. $filter=Security::remove_XSS($_GET['filter']);
  535. }
  536. $filter = (int)$_GET['filter'];
  537. switch ($filter) {
  538. case 1 :
  539. $filter_by_not_revised = true;
  540. break;
  541. case 2 :
  542. $filter_by_revised = true;
  543. break;
  544. default :
  545. null;
  546. }
  547. if (!empty($_GET['exerciseId'])) {
  548. if ($_GET['filter'] == '1' or !isset ($_GET['filter']) or $_GET['filter'] == 0 ) {
  549. $view_result = '<a href="' . api_get_self() . '?cidReq=' . api_get_course_id() . '&show=result&filter=2&id_session='.intval($_GET['id_session']).'&exerciseId='.intval($_GET['exerciseId']).'&gradebook='.$gradebook.'" >'.Display :: return_icon('exercice_check.png', get_lang('ShowCorrectedOnly'),'','32').'</a>';
  550. } else {
  551. $view_result = '<a href="' .api_get_self() . '?cidReq=' . api_get_course_id() . '&show=result&filter=1&id_session='.intval($_GET['id_session']).'&exerciseId='.intval($_GET['exerciseId']).'&gradebook='.$gradebook.'" >'.Display :: return_icon('exercice_uncheck.png', get_lang('ShowUnCorrectedOnly'),'','32').'</a>';
  552. }
  553. echo $view_result;
  554. }
  555. }
  556. }
  557. if ($is_allowedToEdit) {
  558. echo '</div>'; // closing the actions div
  559. } elseif ($show == 'result') {
  560. echo '</div>'; // closing the actions div
  561. }
  562. if ($show == 'test') {
  563. if ($total > $limit) {
  564. echo '<div style="float:right;height:20px;">';
  565. //show pages navigation link for previous page
  566. if ($page) {
  567. echo "<a href=\"" . api_get_self() . "?" . api_get_cidreq() . "&amp;page=" . ($page -1) . "\">" . Display :: return_icon('action_prev.png', get_lang('PreviousPage'))."</a>";
  568. } elseif ($total_exercises + $hp_count > $limit) {
  569. echo Display :: return_icon('action_prev_na.png', get_lang('PreviousPage'));
  570. }
  571. //show pages navigation link for previous page
  572. if ($total_exercises > $from + $limit || $hp_count > $from + $limit ) {
  573. echo ' '."<a href=\"" . api_get_self() . "?" . api_get_cidreq() . "&amp;page=" . ($page +1) . "\">" .Display::return_icon('action_next.png', get_lang('NextPage')) . "</a>";
  574. } elseif ($page) {
  575. echo ' '.Display :: return_icon('action_next_na.png', get_lang('NextPage'));
  576. }
  577. echo '</div>';
  578. }
  579. }
  580. if ($show == 'test') {
  581. ?>
  582. <script type="text/javascript">
  583. $(function() {
  584. /*
  585. $( "a", ".operations" ).button();
  586. $(".tabs-left").tabs().addClass('ui-tabs-vertical ui-helper-clearfix');
  587. $(".tabs-left li").removeClass('ui-corner-top').addClass('ui-corner-left');
  588. */
  589. });
  590. </script>
  591. <style type="text/css">
  592. /*
  593. New interface not yet ready for 1.8.8
  594. Vertical Tabs
  595. .ui-tabs-vertical { width: 99%; }
  596. .ui-tabs-vertical .ui-tabs-nav { padding: .2em .1em .2em .2em; float: left; width: 20%; }
  597. .ui-tabs-vertical .ui-tabs-nav li { clear: left; width: 100%; border-bottom-width: 1px !important; border-right-width: 0 !important; margin: 0 -1px .2em 0; white-space:normal;}
  598. .ui-tabs-vertical .ui-tabs-nav li a { display:block; width:100%; }
  599. .ui-tabs-vertical .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 0; padding-right: .1em; border-right-width: 1px; border-right-width: 1px; }
  600. .ui-tabs-vertical .ui-tabs-panel { padding: 1em; float: left; width: 40em;}
  601. */
  602. </style>
  603. <?php
  604. $i =1;
  605. $lis = '';
  606. $exercise_list = array();
  607. $online_icon = Display::return_icon('online.png', get_lang('Visible'),array('width'=>'12px'));
  608. $offline_icon = Display::return_icon('offline.png',get_lang('Invisible'),array('width'=>'12px'));
  609. while ($row = Database :: fetch_array($result,'ASSOC')) {
  610. $exercise_list[] = $row;
  611. }
  612. echo '<table class="data_table">';
  613. if (!empty($exercise_list)) {
  614. //echo '<div id="exercise_tabs" class="tabs-left">';
  615. //echo '<div style="float:left;width:100%">';
  616. //echo Display::tag('ul', $lis);
  617. /* Listing exercises */
  618. if ($origin != 'learnpath') {
  619. //avoid sending empty parameters
  620. $myorigin = (empty ($origin) ? '' : '&origin=' . $origin);
  621. $mylpid = (empty ($learnpath_id) ? '' : '&learnpath_id=' . $learnpath_id);
  622. $mylpitemid = (empty ($learnpath_item_id) ? '' : '&learnpath_item_id=' . $learnpath_item_id);
  623. $token = Security::get_token();
  624. $i=1;
  625. if ($is_allowedToEdit) {
  626. $headers = array(array('name' => get_lang('ExerciseName')),
  627. array('name' => get_lang('QuantityQuestions'), 'params' => array('width'=>'80px')),
  628. array('name' => get_lang('Actions'), 'params' => array('width'=>'180px')));
  629. } else {
  630. $headers = array(array('name' => get_lang('ExerciseName')),
  631. array('name' => get_lang('Status')),
  632. array('name' => get_lang('Results')));
  633. }
  634. $header_list = '';
  635. foreach($headers as $header) {
  636. $params = isset($header['params'])? $header['params'] : null;
  637. $header_list .= Display::tag('th', $header['name'], $params);
  638. }
  639. echo Display::tag('tr', $header_list);
  640. $count = 0;
  641. if (!empty($exercise_list))
  642. foreach ($exercise_list as $row) {
  643. //echo '<div id="tabs-'.$i.'">';
  644. $i++;
  645. //validacion when belongs to a session
  646. $session_img = api_get_session_image($row['session_id'], $_user['status']);
  647. $time_limits = false;
  648. if ($row['start_time'] != '0000-00-00 00:00:00' || $row['end_time'] != '0000-00-00 00:00:00') {
  649. $time_limits = true;
  650. }
  651. if ($time_limits) {
  652. // check if start time
  653. $start_time = false;
  654. if ($row['start_time'] != '0000-00-00 00:00:00') {
  655. $start_time = api_strtotime($row['start_time'],'UTC');
  656. }
  657. $end_time = false;
  658. if ($row['end_time'] != '0000-00-00 00:00:00') {
  659. $end_time = api_strtotime($row['end_time'],'UTC');
  660. }
  661. $now = time();
  662. $is_actived_time = false;
  663. //If both "clocks" are enable
  664. if ($start_time && $end_time) {
  665. if ($now > $start_time && $end_time > $now ) {
  666. $is_actived_time = true;
  667. }
  668. } else {
  669. //we check the start and end
  670. if ($start_time) {
  671. if ($now > $start_time) {
  672. $is_actived_time = true;
  673. }
  674. }
  675. if ($end_time) {
  676. if ($end_time > $now ) {
  677. $is_actived_time = true;
  678. }
  679. }
  680. }
  681. }
  682. //Blocking empty start times see BT#2800
  683. global $_custom;
  684. if (isset($_custom['exercises_hidden_when_no_start_date']) && $_custom['exercises_hidden_when_no_start_date']) {
  685. if (empty($row['start_time']) || $row['start_time'] == '0000-00-00 00:00:00') {
  686. $time_limits = true;
  687. $is_actived_time = false;
  688. }
  689. }
  690. // Teacher only
  691. if ($is_allowedToEdit) {
  692. $show_quiz_edition = true;
  693. $table_lp_item = Database::get_course_table(TABLE_LP_ITEM);
  694. $sql="SELECT max_score FROM $table_lp_item
  695. WHERE item_type = '".TOOL_QUIZ."' AND path ='".Database::escape_string($row['id'])."'";
  696. $result = Database::query($sql);
  697. if (Database::num_rows($result) > 0) {
  698. $show_quiz_edition = false;
  699. }
  700. $lp_blocked = '';
  701. if (!$show_quiz_edition) {
  702. $lp_blocked = Display::tag('font', '<i>'.get_lang('AddedToALP').'</i>', array('style'=>'color:grey'));
  703. }
  704. //Showing exercise title
  705. $row['title'] = text_filter(cut($row['title'], EXERCISE_MAX_NAME_SIZE));
  706. if ($session_id == $row['session_id']) {
  707. //Settings
  708. //echo Display::url(Display::return_icon('settings.png',get_lang('Edit'), array('width'=>'22px'))." ".get_lang('Edit'), 'exercise_admin.php?'.api_get_cidreq().'&modifyExercise=yes&exerciseId='.$row['id']);
  709. }
  710. if ($row['active'] == 0) {
  711. $title = Display::tag('font', $row['title'], array('style'=>'color:grey'));
  712. } else {
  713. $title = $row['title'];
  714. }
  715. $url = '<a href="overview.php?'.api_get_cidreq().$myorigin.$mylpid.$mylpitemid.'&exerciseId='.$row['id'].'"><img src="../img/quiz.gif" /> '.$title.' </a>'.$lp_blocked;
  716. $item = Display::tag('td', $url.' '.$session_img);
  717. $exid = $row['id'];
  718. //count number exercice - teacher
  719. $sqlquery = "SELECT count(*) FROM $TBL_EXERCICE_QUESTION WHERE exercice_id = '" . $exid . "'";
  720. $sqlresult = Database::query($sqlquery);
  721. $rowi = Database :: result($sqlresult, 0);
  722. if ($session_id == $row['session_id']) {
  723. //Settings
  724. //$actions = Display::url(Display::return_icon('edit.png',get_lang('Edit'),'',22), 'exercise_admin.php?'.api_get_cidreq().'&modifyExercise=yes&exerciseId='.$row['id']);
  725. $actions = Display::url(Display::return_icon('edit.png',get_lang('Edit'),'',22), 'admin.php?'.api_get_cidreq().'&exerciseId='.$row['id']);
  726. $actions .='<a href="exercice.php?' . api_get_cidreq() . '&show=result&exerciseId='.$row['id'].'">' . Display :: return_icon('test_results.png', get_lang('Results'),'',22).'</a>';
  727. //Export
  728. $actions .= Display::url(Display::return_icon('cd.gif', get_lang('CopyExercise')), '', array('onclick'=>"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('AreYouSureToCopy'),ENT_QUOTES,$charset))." ".addslashes($row['title'])."?"."')) return false;",'href'=>'exercice.php?'.api_get_cidreq().'&choice=copy_exercise&sec_token='.$token.'&exerciseId='.$row['id']));
  729. //Clean exercise
  730. $actions .= Display::url(Display::return_icon('clean.png', get_lang('CleanStudentResults'),'',22),'', array('onclick'=>"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('AreYouSureToDeleteResults'),ENT_QUOTES,$charset))." ".addslashes($row['title'])."?"."')) return false;",'href'=>'exercice.php?'.api_get_cidreq().'&choice=clean_results&sec_token='.$token.'&exerciseId='.$row['id']));
  731. //Visible / invisible
  732. if ($row['active']) {
  733. $actions .= Display::url(Display::return_icon('visible.png', get_lang('Deactivate'),'',22) , 'exercice.php?'.api_get_cidreq().'&choice=disable&sec_token='.$token.'&page='.$page.'&exerciseId='.$row['id']);
  734. } else { // else if not active
  735. $actions .= Display::url(Display::return_icon('invisible.png', get_lang('Activate'),'',22) , 'exercice.php?'.api_get_cidreq().'&choice=enable&sec_token='.$token.'&page='.$page.'&exerciseId='.$row['id']);
  736. }
  737. // Export qti ...
  738. $actions .= Display::url(Display::return_icon('export_qti2.png','IMS/QTI','','22'), 'exercice.php?choice=exportqti2&exerciseId='.$row['id']);
  739. } else { // not session resource
  740. $actions = Display::return_icon('edit_na.png', get_lang('ExerciseEditionNotAvailableInSession'));
  741. $actions .='<a href="exercice.php?' . api_get_cidreq() . '&show=result&exerciseId='.$row['id'].'">' . Display :: return_icon('test_results.png', get_lang('Results'),'',22).'</a>';
  742. $actions .= Display::url(Display::return_icon('cd.gif', get_lang('CopyExercise')), '', array('onclick'=>"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('AreYouSureToCopy'),ENT_QUOTES,$charset))." ".addslashes($row['title'])."?"."')) return false;",'href'=>'exercice.php?'.api_get_cidreq().'&choice=copy_exercise&sec_token='.$token.'&exerciseId='.$row['id']));
  743. }
  744. //Delete
  745. if ($session_id == $row['session_id']) {
  746. $actions .= Display::url(Display::return_icon('delete.png', get_lang('Delete'),'',22), '', array('onclick'=>"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('AreYouSureToDelete'),ENT_QUOTES,$charset))." ".addslashes($row['title'])."?"."')) return false;",'href'=>'exercice.php?'.api_get_cidreq().'&choice=delete&sec_token='.$token.'&exerciseId='.$row['id']));
  747. }
  748. //$actions .= '<br />';
  749. $random_label = '';
  750. if ($row['random'] > 0) {
  751. $random_label = ' ('.get_lang('Random').') ';
  752. $number_of_questions = $row['random'] . ' ' . api_strtolower(get_lang(($row['random'] > 1 ? 'Questions' : 'Question'))) .$random_label;
  753. } else {
  754. $number_of_questions = $rowi . ' ' . api_strtolower(get_lang(($rowi > 1 || $rowi == 0 ? 'Questions' : 'Question')));
  755. }
  756. //Attempts
  757. //$attempts = get_count_exam_results($row['id']).' '.get_lang('Attempts');
  758. //$item .= Display::tag('td',$attempts);
  759. $item .= Display::tag('td', $number_of_questions);
  760. } else {
  761. // --- Student only
  762. $row['title'] = cut($row['title'], EXERCISE_MAX_NAME_SIZE);
  763. // if time is actived show link to exercise
  764. if ($time_limits) {
  765. if ($is_actived_time) {
  766. $url = '<a href="overview.php?'.api_get_cidreq().$myorigin.$mylpid.$mylpitemid.'&exerciseId='.$row['id'].'">'.$row['title'].'</a>';
  767. } else {
  768. $url = $row['title'];
  769. }
  770. } else {
  771. $url = '<a href="overview.php?'.api_get_cidreq().$myorigin.$mylpid.$mylpitemid.'&exerciseId='.$row['id'].'">'.$row['title'].'</a>';
  772. }
  773. //Link of the exercise
  774. $item = Display::tag('td',$url.' '.$session_img);
  775. //count number exercise questions
  776. $sqlquery = "SELECT count(*) FROM $TBL_EXERCICE_QUESTION WHERE exercice_id = ".$row['id'];
  777. $sqlresult = Database::query($sqlquery);
  778. $rowi = Database::result($sqlresult, 0);
  779. if ($row['random'] > 0) {
  780. $row['random'] . ' ' . api_strtolower(get_lang(($row['random'] > 1 ? 'Questions' : 'Question')));
  781. } else {
  782. //show results student
  783. $rowi . ' ' . api_strtolower(get_lang(($rowi > 1 ? 'Questions' : 'Question')));
  784. }
  785. //This query might be improved later on by ordering by the new "tms" field rather than by exe_id
  786. //Don't remove this marker: note-query-exe-results
  787. $qry = "SELECT * FROM $TBL_TRACK_EXERCICES
  788. WHERE exe_exo_id = ".$row['id']." AND
  789. exe_user_id = ".api_get_user_id()." AND
  790. exe_cours_id = '".api_get_course_id()."' AND
  791. status <> 'incomplete' AND
  792. orig_lp_id = 0 AND
  793. orig_lp_item_id = 0 AND
  794. session_id = '" . api_get_session_id() . "'
  795. ORDER BY exe_id DESC";
  796. $qryres = Database::query($qry);
  797. $num = Database :: num_rows($qryres);
  798. //Hide the results
  799. $my_result_disabled = $row['results_disabled'];
  800. //Time limits are on
  801. if ($time_limits) {
  802. // Examn is ready to be taken
  803. if ($is_actived_time) {
  804. //Show results
  805. if ($my_result_disabled == 0 || $my_result_disabled == 2) {
  806. //More than one attempt
  807. if ($num > 0) {
  808. $row_track = Database :: fetch_array($qryres);
  809. $attempt_text = get_lang('LatestAttempt') . ' : ';
  810. $attempt_text .= show_score($row_track['exe_result'], $row_track['exe_weighting']);
  811. } else {
  812. //No attempts
  813. $attempt_text = get_lang('NotAttempted');
  814. }
  815. } else {
  816. $attempt_text = get_lang('CantShowResults');
  817. }
  818. } else {
  819. //Quiz not ready due to time limits
  820. if ($row['start_time'] != '0000-00-00 00:00:00' && $row['end_time'] != '0000-00-00 00:00:00') {
  821. $attempt_text = sprintf(get_lang('ExerciseWillBeActivatedFromXToY'), api_convert_and_format_date($row['start_time']), api_convert_and_format_date($row['end_time']));
  822. } else {
  823. //$attempt_text = get_lang('ExamNotAvailableAtThisTime');
  824. if ($row['start_time'] != '0000-00-00 00:00:00') {
  825. $attempt_text = sprintf(get_lang('ExerciseAvailableFromX'), api_convert_and_format_date($row['start_time']));
  826. }
  827. if ($row['end_time'] != '0000-00-00 00:00:00') {
  828. $attempt_text = sprintf(get_lang('ExerciseAvailableUntilX'), api_convert_and_format_date($row['end_time']));
  829. }
  830. }
  831. }
  832. } else {
  833. //Normal behaviour
  834. //Show results
  835. if ($my_result_disabled == 0 || $my_result_disabled == 2) {
  836. if ($num > 0) {
  837. $row_track = Database :: fetch_array($qryres);
  838. $attempt_text = get_lang('LatestAttempt') . ' : ';
  839. $attempt_text .= show_score($row_track['exe_result'], $row_track['exe_weighting']);
  840. } else {
  841. $attempt_text = get_lang('NotAttempted');
  842. }
  843. } else {
  844. $attempt_text = get_lang('CantShowResults');
  845. }
  846. }
  847. //User Attempts
  848. /*
  849. if (empty($row['max_attempt'])) {
  850. //$item .= Display::tag('td',$num);
  851. } else {
  852. if (empty($num)) {
  853. $num = '';
  854. }
  855. //$item .= Display::tag('td',$num.' / '.$row['max_attempt']);
  856. }*/
  857. if (empty($num)) {
  858. $num = '';
  859. }
  860. $item .= Display::tag('td', $attempt_text);
  861. //See results
  862. $actions =' '.$num.' <a href="exercice.php?' . api_get_cidreq() . '&show=result&exerciseId='.$row['id'].'"> '.Display::return_icon('test_results.png', get_lang('Results'),'',22).' </a>';
  863. }
  864. $class = 'row_even';
  865. if ($count % 2) {
  866. $class = 'row_odd';
  867. }
  868. $item .= Display::tag('td', $actions);
  869. echo Display::tag('tr',$item, array('class'=>$class));
  870. $count++;
  871. } // end foreach()
  872. }
  873. }
  874. // end exercise list
  875. //Hotpotatoes results
  876. if ($is_allowedToEdit) {
  877. $sql = "SELECT d.path as path, d.comment as comment, ip.visibility as visibility
  878. FROM $TBL_DOCUMENT d, $TBL_ITEM_PROPERTY ip
  879. WHERE d.id = ip.ref AND ip.tool = '" . TOOL_DOCUMENT . "' AND (d.path LIKE '%htm%')
  880. AND d.path LIKE '" . Database :: escape_string($uploadPath) . "/%/%' LIMIT " .$from . "," .$limit; // only .htm or .html files listed
  881. } else {
  882. $sql = "SELECT d.path as path, d.comment as comment, ip.visibility as visibility
  883. FROM $TBL_DOCUMENT d, $TBL_ITEM_PROPERTY ip
  884. WHERE d.id = ip.ref AND ip.tool = '" . TOOL_DOCUMENT . "' AND (d.path LIKE '%htm%')
  885. AND d.path LIKE '" . Database :: escape_string($uploadPath) . "/%/%' AND ip.visibility='1' LIMIT " .$from . "," .$limit;
  886. }
  887. $result = Database::query($sql);
  888. while ($row = Database :: fetch_array($result, 'ASSOC')) {
  889. $attribute['path'][] = $row['path'];
  890. $attribute['visibility'][] = $row['visibility'];
  891. $attribute['comment'][] = $row['comment'];
  892. }
  893. $nbrActiveTests = 0;
  894. if (isset($attribute['path']) && is_array($attribute['path'])) {
  895. while (list($key, $path) = each($attribute['path'])) {
  896. $item = '';
  897. list ($a, $vis) = each($attribute['visibility']);
  898. if (strcmp($vis, "1") == 0) {
  899. $active = 1;
  900. } else {
  901. $active = 0;
  902. }
  903. $title = GetQuizName($path, $documentPath);
  904. if ($title == '') {
  905. $title = basename($path);
  906. }
  907. $class = 'row_even';
  908. if ($count % 2) {
  909. $class = 'row_odd';
  910. }
  911. // prof only
  912. if ($is_allowedToEdit) {
  913. $item = Display::tag('td','<img src="../img/hotpotatoes_s.png" alt="HotPotatoes" /> <a href="showinframes.php?file='.$path.'&cid='.api_get_course_id().'&uid='.api_get_user_id().'"'.(!$active?'class="invisible"':'').'>'.$title.'</a> ');
  914. $item .= Display::tag('td','-');
  915. $actions = Display::url(Display::return_icon('edit.png',get_lang('Edit'),'',22), 'adminhp.php?'.api_get_cidreq().'&hotpotatoesName='.$path);
  916. $actions .='<a href="exercice.php?' . api_get_cidreq() . '&show=result&path='.$path.'">' . Display :: return_icon('test_results.png', get_lang('Results'),'',22).'</a>';
  917. // if active
  918. if ($active) {
  919. $nbrActiveTests = $nbrActiveTests +1;
  920. $actions .= ' <a href="'.$exercicePath.'?'.api_get_cidreq().'&hpchoice=disable&amp;page='.$page.'&amp;file='.$path.'">'.Display::return_icon('visible.png', get_lang('Deactivate'),'',22).'</a>';
  921. } else { // else if not active
  922. $actions .=' <a href="'.$exercicePath.'?'.api_get_cidreq().'&hpchoice=enable&amp;page='.$page.'&amp;file='.$path.'">'.Display::return_icon('invisible.png', get_lang('Activate'),'',22).'</a>';
  923. }
  924. $actions .= '<a href="'.$exercicePath.'?'.api_get_cidreq().'&amp;hpchoice=delete&amp;file='.$path.'" onclick="javascript:if(!confirm(\''.addslashes(api_htmlentities(get_lang('AreYouSureToDelete'),ENT_QUOTES,$charset).' '.$title."?").'\')) return false;">'.Display::return_icon('delete.png', get_lang('Delete'),'',22).'</a>';
  925. //$actions .='<img src="../img/lp_quiz_na.gif" border="0" title="'.get_lang('NotMarkActivity').'" alt="" />';
  926. $item .= Display::tag('td', $actions);
  927. echo Display::tag('tr',$item, array('class'=>$class));
  928. } else { // student only
  929. if ($active == 1) {
  930. $nbrActiveTests = $nbrActiveTests +1;
  931. $item .= Display::tag('td', '<a href="showinframes.php?'.api_get_cidreq().'&file='.$path.'&cid='.api_get_course_id().'&uid='.api_get_user_id().'"'.(!$active?'class="invisible"':'').'">'.$title.'</a>');
  932. $item .= Display::tag('td', '');
  933. //$item .= Display::tag('td', '');
  934. $actions ='<a href="exercice.php?' . api_get_cidreq() . '&show=result&path='.$path.'">' . Display :: return_icon('test_results.png', get_lang('Results'),'',22).'</a>';
  935. $item .= Display::tag('td', $actions);
  936. echo Display::tag('tr',$item, array('class'=>$class));
  937. }
  938. }
  939. $count ++;
  940. }
  941. //echo '</div>';
  942. }
  943. echo '</table>';
  944. /*} else {
  945. echo '<div style="float:left;width:100%">';
  946. echo Display::display_warning_message(get_lang('NoExercises'));
  947. echo '</div>';
  948. }*/
  949. Display :: display_footer();
  950. exit;
  951. }
  952. /* Exercise Results (uses tracking tool) */
  953. // if tracking is enabled
  954. if ($show == 'result') {
  955. $parameters=array('cidReq'=>Security::remove_XSS($_GET['cidReq']),'show'=>Security::remove_XSS($_GET['show']),'filter' => Security::remove_XSS($_GET['filter']),'gradebook' =>Security::remove_XSS($_GET['gradebook']));
  956. $exercise_id = intval($_GET['exerciseId']);
  957. if (!empty($exercise_id))
  958. $parameters['exerciseId'] = $exercise_id;
  959. if (!empty($_GET['path'])) {
  960. $parameters['path'] = Security::remove_XSS($_GET['path']);
  961. }
  962. $table = new SortableTable('quiz_results', 'get_count_exam_results', 'get_exam_results_data');
  963. $table->set_additional_parameters($parameters);
  964. if ($is_allowedToEdit || $is_tutor) {
  965. if (api_is_western_name_order()) {
  966. $table->set_header(0, get_lang('FirstName'));
  967. $table->set_header(1, get_lang('LastName'));
  968. } else {
  969. $table->set_header(0, get_lang('LastName'));
  970. $table->set_header(1, get_lang('FirstName'));
  971. }
  972. $table->set_header(2, get_lang('Exercice'));
  973. $table->set_header(3, get_lang('Duration'),false);
  974. $table->set_header(4, get_lang('Date'));
  975. $table->set_header(5, get_lang('Score'),false);
  976. $table->set_header(6, get_lang('CorrectTest'), false);
  977. } else {
  978. $table->set_header(0, get_lang('Exercice'));
  979. $table->set_header(1, get_lang('Duration'),false);
  980. $table->set_header(2, get_lang('Date'));
  981. $table->set_header(3, get_lang('Score'),false);
  982. $table->set_header(4, get_lang('Result'), false);
  983. }
  984. $table->display();
  985. }
  986. if ($origin != 'learnpath') { //so we are not in learnpath tool
  987. Display :: display_footer();
  988. }