upload_exercise.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use \ChamiloSession as Session;
  4. /**
  5. * Upload quiz: This script shows the upload quiz feature
  6. * Initial work by Isaac flores on Nov 4 of 2010
  7. * Encoding fixes Julio Montoya
  8. * @package chamilo.exercise
  9. */
  10. // setting the help
  11. $help_content = 'exercise_upload';
  12. require_once api_get_path(LIBRARY_PATH) . 'pear/excelreader/reader.php';
  13. // Security check
  14. $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
  15. if (!$is_allowed_to_edit) {
  16. api_not_allowed(true);
  17. }
  18. // setting the tabs
  19. $this_section = SECTION_COURSES;
  20. $htmlHeadXtra[] = "<script>
  21. $(document).ready( function(){
  22. $('#user_custom_score').click(function() {
  23. $('#options').toggle();
  24. });
  25. });
  26. </script>";
  27. // Action handling
  28. lp_upload_quiz_action_handling();
  29. $interbreadcrumb[] = array(
  30. "url" => "exercise.php?".api_get_cidreq(),
  31. "name" => get_lang('Exercises'),
  32. );
  33. Display::display_header(get_lang('ImportExcelQuiz'), 'Exercises');
  34. if (isset($_GET['message'])) {
  35. if (in_array($_GET['message'], array('ExerciseEdited'))) {
  36. Display :: display_confirmation_message(get_lang($_GET['message']));
  37. }
  38. }
  39. // display the actions
  40. echo '<div class="actions">';
  41. echo lp_upload_quiz_actions();
  42. echo '</div>';
  43. // the main content
  44. lp_upload_quiz_main();
  45. function lp_upload_quiz_actions()
  46. {
  47. $return = '<a href="exercise.php?'.api_get_cidReq().'">'.
  48. Display::return_icon('back.png', get_lang('BackToExercisesList'),'',ICON_SIZE_MEDIUM).'</a>';
  49. return $return;
  50. }
  51. function lp_upload_quiz_secondary_actions()
  52. {
  53. $return = '<a href="exercise_report.php?' . api_get_cidreq() . '">' .
  54. Display :: return_icon('reporting32.png', get_lang('Tracking')) . get_lang('Tracking') . '</a>';
  55. return $return;
  56. }
  57. function lp_upload_quiz_main()
  58. {
  59. // variable initialisation
  60. $lp_id = isset($_GET['lp_id']) ? intval($_GET['lp_id']) : null;
  61. $form = new FormValidator(
  62. 'upload',
  63. 'POST',
  64. api_get_self().'?'.api_get_cidreq().'&lp_id='.$lp_id,
  65. '',
  66. array('enctype' => 'multipart/form-data')
  67. );
  68. $form->addElement('header', get_lang('ImportExcelQuiz'));
  69. $form->addElement('file', 'user_upload_quiz', get_lang('FileUpload'));
  70. $link = '<a href="../exercise/quiz_template.xls">'.
  71. Display::return_icon('export_excel.png', get_lang('DownloadExcelTemplate')).get_lang('DownloadExcelTemplate').'</a>';
  72. $form->addElement('label', '', $link);
  73. $table = new HTML_Table(array('class' => 'table'));
  74. $tableList = array(
  75. UNIQUE_ANSWER => get_lang('UniqueSelect'),
  76. MULTIPLE_ANSWER => get_lang('MultipleSelect'),
  77. FILL_IN_BLANKS => get_lang('FillBlanks'),
  78. MATCHING => get_lang('Matching'),
  79. FREE_ANSWER => get_lang('FreeAnswer'),
  80. GLOBAL_MULTIPLE_ANSWER => get_lang('GlobalMultipleAnswer')
  81. );
  82. $table->setHeaderContents(0, 0, get_lang('QuestionType'));
  83. $table->setHeaderContents(0, 1, '#');
  84. $row = 1;
  85. foreach ($tableList as $key => $label ) {
  86. $table->setCellContents($row, 0, $label);
  87. $table->setCellContents($row, 1, $key);
  88. $row++;
  89. }
  90. $table = $table->toHtml();
  91. $form->addElement('label', get_lang('QuestionType'), $table);
  92. $form->addElement(
  93. 'checkbox',
  94. 'user_custom_score',
  95. null,
  96. get_lang('UseCustomScoreForAllQuestions'),
  97. array('id' => 'user_custom_score')
  98. );
  99. $form->addElement('html', '<div id="options" style="display:none">');
  100. $form->addElement('text', 'correct_score', get_lang('CorrectScore'));
  101. $form->addElement('text', 'incorrect_score', get_lang('IncorrectScore'));
  102. $form->addElement('html', '</div>');
  103. $form->addRule('user_upload_quiz', get_lang('ThisFieldIsRequired'), 'required');
  104. $form->addProgress();
  105. $form->addButtonUpload(get_lang('Upload'), 'submit_upload_quiz');
  106. // Display the upload field
  107. $form->display();
  108. }
  109. /**
  110. * Handles a given Excel spreadsheets as in the template provided
  111. */
  112. function lp_upload_quiz_action_handling()
  113. {
  114. global $debug;
  115. $_course = api_get_course_info();
  116. $courseId = $_course['real_id'];
  117. if (!isset($_POST['submit_upload_quiz'])) {
  118. return;
  119. }
  120. // Get the extension of the document.
  121. $path_info = pathinfo($_FILES['user_upload_quiz']['name']);
  122. // Check if the document is an Excel document
  123. if ($path_info['extension'] != 'xls') {
  124. return;
  125. }
  126. // Read the Excel document
  127. $data = new Spreadsheet_Excel_Reader();
  128. // Set output Encoding.
  129. $data->setOutputEncoding(api_get_system_encoding());
  130. // Reading the xls document.
  131. $data->read($_FILES['user_upload_quiz']['tmp_name']);
  132. $correctScore = isset($_POST['correct_score']) ? $_POST['correct_score'] : null;
  133. $incorrectScore = isset($_POST['incorrect_score']) ? $_POST['incorrect_score'] : null;
  134. $useCustomScore = isset($_POST['user_custom_score']) ? true : false;
  135. $propagateNegative = 0;
  136. if ($useCustomScore && !empty($incorrectScore)) {
  137. if ($incorrectScore < 0) {
  138. $propagateNegative = 1;
  139. }
  140. }
  141. // Variables
  142. $quiz_index = 0;
  143. $question_title_index = array();
  144. $question_name_index_init = array();
  145. $question_name_index_end = array();
  146. $score_index = array();
  147. $feedback_true_index = array();
  148. $feedback_false_index = array();
  149. $number_questions = 0;
  150. $question_description_index = array();
  151. $noNegativeScoreIndex = array();
  152. $questionTypeList = array();
  153. $questionTypeIndex = array();
  154. $categoryList = array();
  155. // Reading all the first column items sequentially to create breakpoints
  156. for ($i = 1; $i <= $data->sheets[0]['numRows']; $i++) {
  157. if ($data->sheets[0]['cells'][$i][1] == 'Quiz' && $i == 1) {
  158. $quiz_index = $i; // Quiz title position, only occurs once
  159. } elseif ($data->sheets[0]['cells'][$i][1] == 'Question') {
  160. $question_title_index[] = $i; // Question title position line
  161. $question_name_index_init[] = $i + 1; // Questions name 1st position line
  162. $number_questions++;
  163. } elseif ($data->sheets[0]['cells'][$i][1] == 'Score') {
  164. $question_name_index_end[] = $i - 1; // Question name position
  165. $score_index[] = $i; // Question score position
  166. } elseif ($data->sheets[0]['cells'][$i][1] == 'FeedbackTrue') {
  167. $feedback_true_index[] = $i; // FeedbackTrue position (line)
  168. } elseif ($data->sheets[0]['cells'][$i][1] == 'FeedbackFalse') {
  169. $feedback_false_index[] = $i; // FeedbackFalse position (line)
  170. } elseif ($data->sheets[0]['cells'][$i][1] == 'EnrichQuestion') {
  171. $question_description_index[] = $i;
  172. } elseif ($data->sheets[0]['cells'][$i][1] == 'NoNegativeScore') {
  173. $noNegativeScoreIndex[] = $i;
  174. } elseif ($data->sheets[0]['cells'][$i][1] == 'QuestionType') {
  175. $questionTypeIndex[] = $i;
  176. }
  177. }
  178. // Variables
  179. $quiz = array();
  180. $question = array();
  181. $new_answer = array();
  182. $score_list = array();
  183. $feedback_true_list = array();
  184. $feedback_false_list = array();
  185. $question_description = array();
  186. $noNegativeScoreList = array();
  187. // Getting questions.
  188. $k = $z = $q = $l = $m = $n = 0;
  189. for ($i = 1; $i <= $data->sheets[0]['numRows']; $i++) {
  190. if (is_array($data->sheets[0]['cells'][$i])) {
  191. $column_data = $data->sheets[0]['cells'][$i];
  192. // Fill all column with data to have a full array
  193. for ($x = 1; $x <= $data->sheets[0]['numCols']; $x++) {
  194. if (empty($column_data[$x])) {
  195. $data->sheets[0]['cells'][$i][$x] = '';
  196. }
  197. }
  198. // Array filled with data
  199. $column_data = $data->sheets[0]['cells'][$i];
  200. } else {
  201. $column_data = '';
  202. }
  203. // Fill quiz data
  204. if ($quiz_index == $i) {
  205. // The title always in the first position
  206. $quiz = $column_data;
  207. } elseif (in_array($i, $question_title_index)) {
  208. //a complete line where 1st column is 'Question'
  209. $question[$k] = $column_data;
  210. for ($counter = 0; $counter < 12; $counter++) {
  211. $myData = isset($data->sheets[0]['cells'][$i + $counter]) ? $data->sheets[0]['cells'][$i + $counter] : null;
  212. if (isset($myData[1]) && $myData[1] == 'QuestionType') {
  213. $questionTypeList[$k] = $myData[3];
  214. }
  215. if (isset($myData[1]) && $myData[1] == 'Category') {
  216. $categoryList[$k] = $myData[2];
  217. }
  218. }
  219. if (!isset($questionTypeList[$k])) {
  220. $questionTypeList[$k] = null;
  221. }
  222. $k++;
  223. } elseif (in_array($i, $score_index)) {
  224. //a complete line where 1st column is 'Score'
  225. $score_list[$z] = $column_data;
  226. $z++;
  227. } elseif (in_array($i, $feedback_true_index)) {
  228. //a complete line where 1st column is 'FeedbackTrue'
  229. $feedback_true_list[$q] = $column_data;
  230. $q++;
  231. } elseif (in_array($i, $feedback_false_index)) {
  232. //a complete line where 1st column is 'FeedbackFalse' for wrong answers
  233. $feedback_false_list[$l] = $column_data;
  234. $l++;
  235. } elseif (in_array($i, $question_description_index)) {
  236. //a complete line where 1st column is 'EnrichQuestion'
  237. $question_description[$m] = $column_data;
  238. $m++;
  239. } elseif (in_array($i, $noNegativeScoreIndex)) {
  240. //a complete line where 1st column is 'NoNegativeScore'
  241. $noNegativeScoreList[$z - 1] = $column_data;
  242. }
  243. }
  244. // Get answers
  245. for ($i = 0; $i < count($question_name_index_init); $i++) {
  246. for ($j = $question_name_index_init[$i]; $j <= $question_name_index_end[$i]; $j++) {
  247. if (is_array($data->sheets[0]['cells'][$j])) {
  248. $column_data = $data->sheets[0]['cells'][$j];
  249. // Fill all column with data
  250. for ($x = 1; $x <= $data->sheets[0]['numCols']; $x++) {
  251. if (empty($column_data[$x])) {
  252. $data->sheets[0]['cells'][$j][$x] = '';
  253. }
  254. }
  255. $column_data = $data->sheets[0]['cells'][$j];
  256. // Array filled of data
  257. if (is_array($column_data) && count($column_data) > 0) {
  258. $new_answer[$i][$j] = $column_data;
  259. }
  260. }
  261. }
  262. }
  263. // Quiz title.
  264. $quiz_title = $quiz[2];
  265. if ($quiz_title != '') {
  266. // Variables
  267. $type = 2;
  268. $random = $active = $results = $max_attempt = $expired_time = 0;
  269. // Make sure feedback is enabled (3 to disable), otherwise the fields
  270. // added to the XLS are not shown, which is confusing
  271. $feedback = 0;
  272. // Quiz object
  273. $exercise = new Exercise();
  274. $quiz_id = $exercise->createExercise(
  275. $quiz_title,
  276. $expired_time,
  277. $type,
  278. $random,
  279. $active,
  280. $results,
  281. $max_attempt,
  282. $feedback,
  283. $propagateNegative
  284. );
  285. if ($quiz_id) {
  286. // insert into the item_property table
  287. api_item_property_update(
  288. $_course,
  289. TOOL_QUIZ,
  290. $quiz_id,
  291. 'QuizAdded',
  292. api_get_user_id()
  293. );
  294. // Import questions.
  295. for ($i = 0; $i < $number_questions; $i++) {
  296. // Question name
  297. $question_title = $question[$i][2];
  298. $description = isset($question_description[$i][2]) ? $question_description[$i][2] : '';
  299. $categoryId = null;
  300. if (isset($categoryList[$i]) && !empty($categoryList[$i])) {
  301. $categoryName = $categoryList[$i];
  302. $categoryId = TestCategory::get_category_id_for_title($categoryName, $courseId);
  303. if (empty($categoryId)) {
  304. $category = new TestCategory();
  305. $category->name = $categoryName;
  306. $categoryId = $category->addCategoryInBDD();
  307. }
  308. }
  309. $question_description_text = "<p></p>";
  310. if (!empty($description)) {
  311. // Question description.
  312. $question_description_text = "<p>".$description."</p>";
  313. }
  314. // Unique answers are the only question types available for now
  315. // through xls-format import
  316. $answerList = isset($new_answer[$i]) ? $new_answer[$i] : '';
  317. $question_id = null;
  318. if (isset($questionTypeList[$i])) {
  319. $detectQuestionType = intval($questionTypeList[$i]);
  320. } else {
  321. $detectQuestionType = detectQuestionType(
  322. $answerList,
  323. $score_list
  324. );
  325. }
  326. /** @var Question $answer */
  327. switch ($detectQuestionType) {
  328. case FREE_ANSWER:
  329. $answer = new FreeAnswer();
  330. break;
  331. case GLOBAL_MULTIPLE_ANSWER:
  332. $answer = new GlobalMultipleAnswer();
  333. break;
  334. case MULTIPLE_ANSWER:
  335. $answer = new MultipleAnswer();
  336. break;
  337. case FILL_IN_BLANKS:
  338. $answer = new FillBlanks();
  339. $question_description_text = '';
  340. break;
  341. case MATCHING:
  342. $answer = new Matching();
  343. break;
  344. case UNIQUE_ANSWER:
  345. default:
  346. $answer = new UniqueAnswer();
  347. break;
  348. }
  349. if ($question_title != '') {
  350. $question_id = $answer->create_question(
  351. $quiz_id,
  352. $question_title,
  353. $question_description_text,
  354. 0, // max score
  355. $answer->type
  356. );
  357. if (!empty($categoryId)) {
  358. TestCategory::add_category_for_question_id(
  359. $categoryId,
  360. $question_id,
  361. $courseId
  362. );
  363. }
  364. }
  365. switch ($detectQuestionType) {
  366. case GLOBAL_MULTIPLE_ANSWER:
  367. case MULTIPLE_ANSWER:
  368. case UNIQUE_ANSWER:
  369. $total = 0;
  370. if (is_array($answerList) && !empty($question_id)) {
  371. $id = 1;
  372. $objAnswer = new Answer($question_id, $courseId);
  373. $globalScore = $score_list[$i][3];
  374. // Calculate the number of correct answers to divide the
  375. // score between them when importing from CSV
  376. $numberRightAnswers = 0;
  377. foreach ($answerList as $answer_data) {
  378. if (strtolower($answer_data[3]) == 'x') {
  379. $numberRightAnswers++;
  380. }
  381. }
  382. foreach ($answerList as $answer_data) {
  383. $answerValue = $answer_data[2];
  384. $correct = 0;
  385. $score = 0;
  386. if (strtolower($answer_data[3]) == 'x') {
  387. $correct = 1;
  388. $score = $score_list[$i][3];
  389. $comment = $feedback_true_list[$i][2];
  390. } else {
  391. $comment = $feedback_false_list[$i][2];
  392. $floatVal = (float)$answer_data[3];
  393. if (is_numeric($floatVal)) {
  394. $score = $answer_data[3];
  395. }
  396. }
  397. if ($useCustomScore) {
  398. if ($correct) {
  399. $score = $correctScore;
  400. } else {
  401. $score = $incorrectScore;
  402. }
  403. }
  404. // Fixing scores:
  405. switch ($detectQuestionType) {
  406. case GLOBAL_MULTIPLE_ANSWER:
  407. if (isset($noNegativeScoreList[$i][3])) {
  408. if (!(strtolower($noNegativeScoreList[$i][3]) == 'x') &&
  409. !$correct
  410. ) {
  411. $score = $score_list[$i][3] * -1;
  412. }
  413. } else {
  414. $score = $score_list[$i][3] * -1;
  415. }
  416. $score /= $numberRightAnswers;
  417. break;
  418. case UNIQUE_ANSWER:
  419. break;
  420. case MULTIPLE_ANSWER:
  421. if (!$correct) {
  422. //$total = $total - $score;
  423. }
  424. break;
  425. }
  426. $objAnswer->createAnswer(
  427. $answerValue,
  428. $correct,
  429. $comment,
  430. $score,
  431. $id
  432. );
  433. $total += $score;
  434. $id++;
  435. }
  436. $objAnswer->save();
  437. $questionObj = Question::read(
  438. $question_id,
  439. $courseId
  440. );
  441. if ($questionObj) {
  442. switch ($detectQuestionType) {
  443. case GLOBAL_MULTIPLE_ANSWER:
  444. $questionObj->updateWeighting($globalScore);
  445. break;
  446. case UNIQUE_ANSWER:
  447. case MULTIPLE_ANSWER:
  448. default:
  449. $questionObj->updateWeighting($total);
  450. break;
  451. }
  452. $questionObj->save();
  453. }
  454. }
  455. break;
  456. case FREE_ANSWER:
  457. $globalScore = $score_list[$i][3];
  458. $questionObj = Question::read($question_id, $courseId);
  459. if ($questionObj) {
  460. $questionObj->updateWeighting($globalScore);
  461. $questionObj->save();
  462. }
  463. break;
  464. case FILL_IN_BLANKS:
  465. $scoreList = array();
  466. $size = array();
  467. $globalScore = 0;
  468. foreach ($answerList as $data) {
  469. $score = isset($data[3]) ? $data[3] : 0;
  470. $globalScore += $score;
  471. $scoreList[] = $score;
  472. $size[] = 200;
  473. }
  474. $scoreToString = implode(',', $scoreList);
  475. $sizeToString = implode(',', $size);
  476. //<p>Texte long avec les [mots] à [remplir] mis entre [crochets]</p>::10,10,10:200.36363999999998,200,200:0@'
  477. $answerValue = $description.'::'.$scoreToString.':'.$sizeToString.':0@';
  478. $objAnswer = new Answer($question_id, $courseId);
  479. $objAnswer->createAnswer(
  480. $answerValue,
  481. '', //$correct,
  482. '', //$comment,
  483. $globalScore,
  484. 1
  485. );
  486. $objAnswer->save();
  487. $questionObj = Question::read($question_id, $courseId);
  488. if ($questionObj) {
  489. $questionObj->updateWeighting($globalScore);
  490. $questionObj->save();
  491. }
  492. break;
  493. case MATCHING:
  494. $globalScore = $score_list[$i][3];
  495. $position = 1;
  496. $objAnswer = new Answer($question_id, $courseId);
  497. foreach ($answerList as $data) {
  498. $option = isset($data[3]) ? $data[3] : '';
  499. $objAnswer->createAnswer($option, 0, '', 0, $position);
  500. $position++;
  501. }
  502. $counter = 1;
  503. foreach ($answerList as $data) {
  504. $value = isset($data[2]) ? $data[2] : '';
  505. $position++;
  506. $objAnswer->createAnswer(
  507. $value,
  508. $counter,
  509. ' ',
  510. $globalScore,
  511. $position
  512. );
  513. $counter++;
  514. }
  515. $objAnswer->save();
  516. $questionObj = Question::read($question_id, $courseId);
  517. if ($questionObj) {
  518. $questionObj->updateWeighting($globalScore);
  519. $questionObj->save();
  520. }
  521. break;
  522. }
  523. }
  524. }
  525. $lpFromSession = Session::read('lpobject');
  526. if (isset($lpFromSession)) {
  527. if ($debug > 0) {
  528. error_log('New LP - SESSION[lpobject] is defined', 0);
  529. }
  530. $oLP = unserialize($lpFromSession);
  531. if (is_object($oLP)) {
  532. if ($debug > 0) {
  533. error_log('New LP - oLP is object', 0);
  534. }
  535. if ((empty($oLP->cc)) OR $oLP->cc != api_get_course_id()) {
  536. if ($debug > 0) {
  537. error_log('New LP - Course has changed, discard lp object', 0);
  538. }
  539. $oLP = null;
  540. Session::erase('oLP');
  541. Session::erase('lpobject');
  542. } else {
  543. Session::write('oLP', $oLP);
  544. }
  545. }
  546. }
  547. /** @var learnpath $lpFromSession */
  548. $lpFromSession = Session::read('oLP');
  549. if (isset($lpFromSession) && isset($_GET['lp_id'])) {
  550. $previous = $lpFromSession->select_previous_item_id();
  551. $parent = 0;
  552. // Add a Quiz as Lp Item
  553. $lpFromSession->add_item(
  554. $parent,
  555. $previous,
  556. TOOL_QUIZ,
  557. $quiz_id,
  558. $quiz_title,
  559. ''
  560. );
  561. // Redirect to home page for add more content
  562. header(
  563. 'location: ../newscorm/lp_controller.php?'.api_get_cidreq(
  564. ).'&action=add_item&type=step&lp_id='.intval($_GET['lp_id'])
  565. );
  566. exit;
  567. } else {
  568. echo '<script>window.location.href = "'.api_get_path(WEB_CODE_PATH).'exercice/admin.php?'.api_get_cidReq().'&exerciseId='.$quiz_id.'&session_id='.api_get_session_id().'"</script>';
  569. }
  570. }
  571. }
  572. /**
  573. * @param array $answers_data
  574. * @return int
  575. */
  576. function detectQuestionType($answers_data)
  577. {
  578. $correct = 0;
  579. $isNumeric = false;
  580. if (empty($answers_data)) {
  581. return FREE_ANSWER;
  582. }
  583. foreach ($answers_data as $answer_data) {
  584. if (strtolower($answer_data[3]) == 'x') {
  585. $correct++;
  586. } else {
  587. if (is_numeric($answer_data[3])) {
  588. $isNumeric = true;
  589. }
  590. }
  591. }
  592. if ($correct == 1) {
  593. $type = UNIQUE_ANSWER;
  594. } else {
  595. if ($correct > 1) {
  596. $type = MULTIPLE_ANSWER;
  597. } else {
  598. $type = FREE_ANSWER;
  599. }
  600. }
  601. if ($type == MULTIPLE_ANSWER) {
  602. if ($isNumeric) {
  603. $type = MULTIPLE_ANSWER;
  604. } else {
  605. $type = GLOBAL_MULTIPLE_ANSWER;
  606. }
  607. }
  608. return $type;
  609. }
  610. if (!isset($origin) || isset($origin) && $origin != 'learnpath') {
  611. //so we are not in learnpath tool
  612. Display :: display_footer();
  613. }