exercice_submit.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. <?php
  2. /*
  3. DOKEOS - elearning and course management software
  4. For a full list of contributors, see documentation/credits.html
  5. This program is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 2
  8. of the License, or (at your option) any later version.
  9. See "documentation/licence.html" more details.
  10. Contact:
  11. Dokeos
  12. Rue des Palais 44 Paleizenstraat
  13. B-1030 Brussels - Belgium
  14. Tel. +32 (2) 211 34 56
  15. */
  16. /**
  17. * Exercise submission
  18. * This script allows to run an exercise. According to the exercise type, questions
  19. * can be on an unique page, or one per page with a Next button.
  20. *
  21. * One exercise may contain different types of answers (unique or multiple selection,
  22. * matching and fill in blanks).
  23. *
  24. * Questions are selected randomly or not.
  25. *
  26. * When the user has answered all questions and clicks on the button "Ok",
  27. * it goes to exercise_result.php
  28. *
  29. * Notice : This script is also used to show a question before modifying it by
  30. * the administrator
  31. * @package dokeos.exercise
  32. * @author Olivier Brouckaert
  33. * @version $Id: exercice_submit.php 12447 2007-05-23 08:03:37Z elixir_julian $
  34. */
  35. include('exercise.class.php');
  36. include('question.class.php');
  37. include('answer.class.php');
  38. include('exercise.lib.php');
  39. // debug var. Set to 0 to hide all debug display. Set to 1 to display debug messages.
  40. $debug = 0;
  41. // answer types
  42. define('UNIQUE_ANSWER', 1);
  43. define('MULTIPLE_ANSWER', 2);
  44. define('FILL_IN_BLANKS', 3);
  45. define('MATCHING', 4);
  46. define('FREE_ANSWER', 5);
  47. define('HOT_SPOT', 6);
  48. define('HOT_SPOT_ORDER', 7);
  49. // name of the language file that needs to be included
  50. $language_file='exercice';
  51. include_once('../inc/global.inc.php');
  52. $this_section=SECTION_COURSES;
  53. include_once(api_get_path(LIBRARY_PATH).'text.lib.php');
  54. $is_allowedToEdit=$is_courseAdmin;
  55. $TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
  56. $TBL_EXERCICES = Database::get_course_table(TABLE_QUIZ_TEST);
  57. $TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
  58. $TBL_REPONSES = Database::get_course_table(TABLE_QUIZ_ANSWER);
  59. // general parameters passed via POST/GET
  60. if ( empty ( $origin ) ) {
  61. $origin = $_REQUEST['origin'];
  62. }
  63. if ( empty ( $learnpath_id ) ) {
  64. $learnpath_id = mysql_real_escape_string($_REQUEST['learnpath_id']);
  65. }
  66. if ( empty ( $learnpath_item_id ) ) {
  67. $learnpath_item_id = mysql_real_escape_string($_REQUEST['learnpath_item_id']);
  68. }
  69. if ( empty ( $formSent ) ) {
  70. $formSent = $_REQUEST['formSent'];
  71. }
  72. if ( empty ( $exerciseResult ) ) {
  73. $exerciseResult = $_REQUEST['exerciseResult'];
  74. }
  75. if ( empty ( $exerciseResultCoordinates ) ) {
  76. $exerciseResultCoordinates = $_REQUEST['exerciseResultCoordinates'];
  77. }
  78. if ( empty ( $exerciseType ) ) {
  79. $exerciseType = $_REQUEST['exerciseType'];
  80. }
  81. if ( empty ( $exerciseId ) ) {
  82. $exerciseId = $_REQUEST['exerciseId'];
  83. }
  84. if ( empty ( $choice ) ) {
  85. $choice = $_REQUEST['choice'];
  86. }
  87. if ( empty ( $questionNum ) ) {
  88. $questionNum = mysql_real_escape_string($_REQUEST['questionNum']);
  89. }
  90. if ( empty ( $nbrQuestions ) ) {
  91. $nbrQuestions = mysql_real_escape_string($_REQUEST['nbrQuestions']);
  92. }
  93. if ( empty ($buttonCancel) ) {
  94. $buttonCancel = $_REQUEST['buttonCancel'];
  95. }
  96. // if the user has clicked on the "Cancel" button
  97. if($buttonCancel)
  98. {
  99. // returns to the exercise list
  100. header("Location: exercice.php?origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id");
  101. exit();
  102. }
  103. if ($origin=='builder') {
  104. /*******************************/
  105. /* Clears the exercise session */
  106. /*******************************/
  107. if(isset($_SESSION['objExercise'])) { api_session_unregister('objExercise'); unset($objExercise); }
  108. if(isset($_SESSION['objQuestion'])) { api_session_unregister('objQuestion'); unset($objQuestion); }
  109. if(isset($_SESSION['objAnswer'])) { api_session_unregister('objAnswer'); unset($objAnswer); }
  110. if(isset($_SESSION['questionList'])) { api_session_unregister('questionList'); unset($questionList); }
  111. if(isset($_SESSION['exerciseResult'])) { api_session_unregister('exerciseResult'); unset($exerciseResult); }
  112. if(isset($_SESSION['exerciseResultCoordinates'])) { api_session_unregister('exerciseResultCoordinates'); unset($exerciseResultCoordinates); }
  113. }
  114. // if the user has submitted the form
  115. if($formSent)
  116. {
  117. if($debug>0){echo str_repeat('&nbsp;',0).'$formSent was set'."<br />\n";}
  118. // initializing
  119. if(!is_array($exerciseResult))
  120. {
  121. $exerciseResult=array();
  122. $exerciseResultCoordinates=array();
  123. }
  124. // if the user has answered at least one question
  125. if(is_array($choice))
  126. {
  127. if($debug>0){echo str_repeat('&nbsp;',0).'$choice is an array'."<br />\n";}
  128. if($exerciseType == 1)
  129. {
  130. // $exerciseResult receives the content of the form.
  131. // Each choice of the student is stored into the array $choice
  132. $exerciseResult=$choice;
  133. if (isset($_POST['hotspot']))
  134. {
  135. $exerciseResultCoordinates = $_POST['hotspot'];
  136. }
  137. }
  138. else
  139. {
  140. // gets the question ID from $choice. It is the key of the array
  141. list($key)=array_keys($choice);
  142. // if the user didn't already answer this question
  143. if(!isset($exerciseResult[$key]))
  144. {
  145. // stores the user answer into the array
  146. $exerciseResult[$key]=$choice[$key];
  147. if (isset($_POST['hotspot']))
  148. {
  149. $exerciseResultCoordinates[$key] = $_POST['hotspot'][$key];
  150. }
  151. }
  152. }
  153. if($debug>0){echo str_repeat('&nbsp;',0).'$choice is an array - end'."<br />\n";}
  154. }
  155. // the script "exercise_result.php" will take the variable $exerciseResult from the session
  156. api_session_register('exerciseResult');
  157. api_session_register('exerciseResultCoordinates');
  158. // if it is the last question (only for a sequential exercise)
  159. if($exerciseType == 1 || $questionNum >= $nbrQuestions)
  160. {
  161. if($debug>0){echo str_repeat('&nbsp;',0).'Redirecting to exercise_result.php - Remove debug option to let this happen'."<br />\n";}
  162. // goes to the script that will show the result of the exercise
  163. header("Location: exercise_result.php?origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id");
  164. exit();
  165. }
  166. if($debug>0){echo str_repeat('&nbsp;',0).'$formSent was set - end'."<br />\n";}
  167. }
  168. // if the object is not in the session
  169. if(!isset($_SESSION['objExercise']) || $origin == 'learnpath')
  170. {
  171. if($debug>0){echo str_repeat('&nbsp;',0).'$_SESSION[objExercise] was unset'."<br />\n";}
  172. // construction of Exercise
  173. $objExercise=new Exercise();
  174. #$sql="SELECT title,description,sound,type,random,active FROM `$TBL_EXERCICES` WHERE id='$exerciseId'";
  175. // if the specified exercise doesn't exist or is disabled
  176. if(!$objExercise->read($exerciseId) || (!$objExercise->selectStatus() && !$is_allowedToEdit && ($origin != 'learnpath') ))
  177. {
  178. die(get_lang('ExerciseNotFound'));
  179. }
  180. // saves the object into the session
  181. api_session_register('objExercise');
  182. if($debug>0){echo str_repeat('&nbsp;',0).'$_SESSION[objExercise] was unset - set now - end'."<br />\n";}
  183. }
  184. if(!isset($objExcercise) && isset($_SESSION['objExercise'])){
  185. $objExercise = $_SESSION['objExercise'];
  186. }
  187. if(!is_object($objExercise))
  188. {
  189. header('Location: exercice.php');
  190. exit();
  191. }
  192. $exerciseTitle=$objExercise->selectTitle();
  193. $exerciseDescription=$objExercise->selectDescription();
  194. $exerciseDescription=stripslashes($exerciseDescription);
  195. $exerciseSound=$objExercise->selectSound();
  196. $randomQuestions=$objExercise->isRandom();
  197. $exerciseType=$objExercise->selectType();
  198. if(!isset($_SESSION['questionList']) || $origin == 'learnpath')
  199. {
  200. if($debug>0){echo str_repeat('&nbsp;',0).'$_SESSION[questionList] was unset'."<br />\n";}
  201. // selects the list of question ID
  202. $questionList = ($randomQuestions?$objExercise->selectRandomList():$objExercise->selectQuestionList());
  203. // saves the question list into the session
  204. api_session_register('questionList');
  205. if($debug>0){echo str_repeat('&nbsp;',0).'$_SESSION[questionList] was unset - set now - end'."<br />\n";}
  206. }
  207. if(!isset($objExcercise) && isset($_SESSION['objExercise'])){
  208. $questionList = $_SESSION['questionList'];
  209. }
  210. $nbrQuestions=sizeof($questionList);
  211. // if questionNum comes from POST and not from GET
  212. if(!$questionNum || $_POST['questionNum'])
  213. {
  214. // only used for sequential exercises (see $exerciseType)
  215. if(!$questionNum)
  216. {
  217. $questionNum=1;
  218. }
  219. else
  220. {
  221. $questionNum++;
  222. }
  223. }
  224. //$nameTools=get_lang('Exercice');
  225. $interbreadcrumb[]=array("url" => "exercice.php","name" => get_lang('Exercices'));
  226. $interbreadcrumb[]=array("url" => "#","name" => $exerciseTitle);
  227. if ($origin != 'learnpath') { //so we are not in learnpath tool
  228. $htmlHeadXtra[] = "<script type=\"text/javascript\" src=\"../plugin/hotspot/JavaScriptFlashGateway.js\"></script>
  229. <script src=\"../plugin/hotspot/hotspot.js\" type=\"text/javascript\"></script>
  230. <script language=\"JavaScript\" type=\"text/javascript\">
  231. <!--
  232. // -----------------------------------------------------------------------------
  233. // Globals
  234. // Major version of Flash required
  235. var requiredMajorVersion = 7;
  236. // Minor version of Flash required
  237. var requiredMinorVersion = 0;
  238. // Minor version of Flash required
  239. var requiredRevision = 0;
  240. // the version of javascript supported
  241. var jsVersion = 1.0;
  242. // -----------------------------------------------------------------------------
  243. // -->
  244. </script>
  245. <script language=\"VBScript\" type=\"text/vbscript\">
  246. <!-- // Visual basic helper required to detect Flash Player ActiveX control version information
  247. Function VBGetSwfVer(i)
  248. on error resume next
  249. Dim swControl, swVersion
  250. swVersion = 0
  251. set swControl = CreateObject(\"ShockwaveFlash.ShockwaveFlash.\" + CStr(i))
  252. if (IsObject(swControl)) then
  253. swVersion = swControl.GetVariable(\"\$version\")
  254. end if
  255. VBGetSwfVer = swVersion
  256. End Function
  257. // -->
  258. </script>
  259. <script language=\"JavaScript1.1\" type=\"text/javascript\">
  260. <!-- // Detect Client Browser type
  261. var isIE = (navigator.appVersion.indexOf(\"MSIE\") != -1) ? true : false;
  262. var isWin = (navigator.appVersion.toLowerCase().indexOf(\"win\") != -1) ? true : false;
  263. var isOpera = (navigator.userAgent.indexOf(\"Opera\") != -1) ? true : false;
  264. jsVersion = 1.1;
  265. // JavaScript helper required to detect Flash Player PlugIn version information
  266. function JSGetSwfVer(i){
  267. // NS/Opera version >= 3 check for Flash plugin in plugin array
  268. if (navigator.plugins != null && navigator.plugins.length > 0) {
  269. if (navigator.plugins[\"Shockwave Flash 2.0\"] || navigator.plugins[\"Shockwave Flash\"]) {
  270. var swVer2 = navigator.plugins[\"Shockwave Flash 2.0\"] ? \" 2.0\" : \"\";
  271. var flashDescription = navigator.plugins[\"Shockwave Flash\" + swVer2].description;
  272. descArray = flashDescription.split(\" \");
  273. tempArrayMajor = descArray[2].split(\".\");
  274. versionMajor = tempArrayMajor[0];
  275. versionMinor = tempArrayMajor[1];
  276. if ( descArray[3] != \"\" ) {
  277. tempArrayMinor = descArray[3].split(\"r\");
  278. } else {
  279. tempArrayMinor = descArray[4].split(\"r\");
  280. }
  281. versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0;
  282. flashVer = versionMajor + \".\" + versionMinor + \".\" + versionRevision;
  283. } else {
  284. flashVer = -1;
  285. }
  286. }
  287. // MSN/WebTV 2.6 supports Flash 4
  288. else if (navigator.userAgent.toLowerCase().indexOf(\"webtv/2.6\") != -1) flashVer = 4;
  289. // WebTV 2.5 supports Flash 3
  290. else if (navigator.userAgent.toLowerCase().indexOf(\"webtv/2.5\") != -1) flashVer = 3;
  291. // older WebTV supports Flash 2
  292. else if (navigator.userAgent.toLowerCase().indexOf(\"webtv\") != -1) flashVer = 2;
  293. // Can't detect in all other cases
  294. else {
  295. flashVer = -1;
  296. }
  297. return flashVer;
  298. }
  299. // When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
  300. function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision)
  301. {
  302. reqVer = parseFloat(reqMajorVer + \".\" + reqRevision);
  303. // loop backwards through the versions until we find the newest version
  304. for (i=25;i>0;i--) {
  305. if (isIE && isWin && !isOpera) {
  306. versionStr = VBGetSwfVer(i);
  307. } else {
  308. versionStr = JSGetSwfVer(i);
  309. }
  310. if (versionStr == -1 ) {
  311. return false;
  312. } else if (versionStr != 0) {
  313. if(isIE && isWin && !isOpera) {
  314. tempArray = versionStr.split(\" \");
  315. tempString = tempArray[1];
  316. versionArray = tempString .split(\",\");
  317. } else {
  318. versionArray = versionStr.split(\".\");
  319. }
  320. versionMajor = versionArray[0];
  321. versionMinor = versionArray[1];
  322. versionRevision = versionArray[2];
  323. versionString = versionMajor + \".\" + versionRevision; // 7.0r24 == 7.24
  324. versionNum = parseFloat(versionString);
  325. // is the major.revision >= requested major.revision AND the minor version >= requested minor
  326. if ( (versionMajor > reqMajorVer) && (versionNum >= reqVer) ) {
  327. return true;
  328. } else {
  329. return ((versionNum >= reqVer && versionMinor >= reqMinorVer) ? true : false );
  330. }
  331. }
  332. }
  333. }
  334. // -->
  335. </script>";
  336. Display::display_header($nameTools,"Exercise");
  337. }
  338. else
  339. {
  340. if(empty($charset))
  341. {
  342. $charset = 'ISO-8859-15';
  343. }
  344. header('Content-Type: text/html; charset='. $charset);
  345. @$document_language = Database::get_language_isocode($language_interface);
  346. if(empty($document_language))
  347. {
  348. //if there was no valid iso-code, use the english one
  349. $document_language = 'en';
  350. }
  351. /*
  352. * HTML HEADER
  353. */
  354. ?>
  355. <!DOCTYPE html
  356. PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  357. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  358. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $document_language; ?>" lang="<?php echo $document_language; ?>">
  359. <head>
  360. <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
  361. </head>
  362. <body>
  363. <link rel="stylesheet" type="text/css" href="<?php echo api_get_path(WEB_CODE_PATH).'css/'.api_get_setting('stylesheets').'/frames.css'; ?>" />
  364. <?php
  365. }
  366. $exerciseTitle=api_parse_tex($exerciseTitle);
  367. echo "<h3>".$exerciseTitle."</h3>";
  368. if(!empty($exerciseSound))
  369. {
  370. echo "<a href=\"../document/download.php?doc_url=%2Faudio%2F".$exerciseSound."\" target=\"_blank\">",
  371. "<img src=\"../img/sound.gif\" border=\"0\" align=\"absmiddle\" alt=",get_lang('Sound')."\" /></a>";
  372. }
  373. /* <ERM> */
  374. // Get number of hotspot questions for javascript validation
  375. $number_of_hotspot_questions = 0;
  376. $onsubmit = '';
  377. $i=0;
  378. //var_dump($questionList);
  379. foreach($questionList as $questionId)
  380. {
  381. $i++;
  382. $objQuestionTmp = Question :: read($questionId);
  383. // for sequential exercises
  384. if($exerciseType == 2)
  385. {
  386. // if it is not the right question, goes to the next loop iteration
  387. if($questionNum != $i)
  388. {
  389. continue;
  390. }
  391. else
  392. {
  393. if ($objQuestionTmp->selectType() == HOT_SPOT)
  394. {
  395. $number_of_hotspot_questions++;
  396. }
  397. break;
  398. }
  399. }
  400. else
  401. {
  402. if ($objQuestionTmp->selectType() == HOT_SPOT)
  403. {
  404. $number_of_hotspot_questions++;
  405. }
  406. }
  407. }
  408. //echo ':' . $number_of_hotspot_questions;
  409. if($number_of_hotspot_questions > 0)
  410. {
  411. $onsubmit = "onsubmit=\"return validateFlashVar('".$number_of_hotspot_questions."', '".get_lang('HotspotValidateError1')."', '".get_lang('HotspotValidateError2')."');\"";
  412. }
  413. $s="
  414. <p>$exerciseDescription</p>";
  415. if($origin == 'learnpath' && $exerciseType==2){
  416. $s2 = "&exerciseId=".$exerciseId;
  417. }
  418. $s.=" <form method='post' action='".api_get_self()."?autocomplete=off".$s2."' name='frm_exercise' $onsubmit>
  419. <input type='hidden' name='formSent' value='1' />
  420. <input type='hidden' name='exerciseType' value='".$exerciseType."' />
  421. <input type='hidden' name='questionNum' value='".$questionNum."' />
  422. <input type='hidden' name='nbrQuestions' value='".$nbrQuestions."' />
  423. <input type='hidden' name='origin' value='".$origin."' />
  424. <input type='hidden' name='learnpath_id' value='".$learnpath_id."' />
  425. <input type='hidden' name='learnpath_item_id' value='".$learnpath_item_id."' />
  426. <table width='100%' border='0' cellpadding='1' cellspacing='0'>
  427. <tr>
  428. <td>
  429. <table width='100%' cellpadding='3' cellspacing='2' border='0'>";
  430. echo $s;
  431. /* </ERM> */
  432. $i=0;
  433. foreach($questionList as $questionId)
  434. {
  435. $i++;
  436. // for sequential exercises
  437. if($exerciseType == 2)
  438. {
  439. // if it is not the right question, goes to the next loop iteration
  440. if($questionNum != $i)
  441. {
  442. continue;
  443. }
  444. else
  445. {
  446. // if the user has already answered this question
  447. if(isset($exerciseResult[$questionId]))
  448. {
  449. // construction of the Question object
  450. $objQuestionTmp = Question::read($questionId);
  451. $questionName=$objQuestionTmp->selectTitle();
  452. // destruction of the Question object
  453. unset($objQuestionTmp);
  454. echo '<tr><td>'.get_lang('AlreadyAnswered').' &quot;'.$questionName.'&quot;</td></tr>';
  455. break;
  456. }
  457. }
  458. }
  459. $s="<tr>
  460. <td width='3%'><img src=\"".api_get_path(WEB_IMG_PATH)."test.gif\" align=\"absmiddle\"></td>
  461. <td valign='middle' bgcolor='#e6e6e6'>
  462. ".get_lang('Question')." ";
  463. $s.=$i;
  464. if($exerciseType == 2) $s.=' / '.$nbrQuestions;
  465. $s.='</td></tr>';
  466. echo $s;
  467. // shows the question and its answers
  468. showQuestion($questionId, false, $origin);
  469. // for sequential exercises
  470. if($exerciseType == 2)
  471. {
  472. // quits the loop
  473. break;
  474. }
  475. } // end foreach()
  476. $s="</table>
  477. </td>
  478. </tr>
  479. <tr>
  480. <td><br/>
  481. <!-- <input type='submit' name='buttonCancel' value=".get_lang('Cancel')." />
  482. &nbsp;&nbsp; //-->
  483. <input type='submit' name='submit' value='";
  484. if ($exerciseType == 1 || $nbrQuestions == $questionNum) {
  485. $s.=get_lang('Ok');
  486. }
  487. else
  488. {
  489. $s.=get_lang('Next').' &gt;';
  490. }
  491. //$s.='\'&gt;';
  492. $s.= '\' />';
  493. $s.="</td></tr></form></table>";
  494. $b=2;
  495. echo $s;
  496. if ($origin != 'learnpath') { //so we are not in learnpath tool
  497. Display::display_footer();
  498. }
  499. ?>