exercice.php 56 KB

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