exercise_show_functions.lib.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. <?php
  2. /* See license terms in /license.txt */
  3. /**
  4. * EVENTS LIBRARY
  5. *
  6. * This is the events library for Chamilo.
  7. * Functions of this library are used to record informations when some kind
  8. * of event occur. Each event has his own types of informations then each event
  9. * use its own function.
  10. *
  11. * @package chamilo.library
  12. * @todo convert queries to use Database API
  13. */
  14. /**
  15. * Class
  16. * @package chamilo.library
  17. */
  18. class ExerciseShowFunctions
  19. {
  20. /**
  21. * Shows the answer to a fill-in-the-blanks question, as HTML
  22. * @param int $feedbackType
  23. * @param string $answer
  24. * @param int $id Exercise ID
  25. * @param int $questionId Question ID
  26. * @param int $resultsDisabled
  27. * @param string $originalStudentAnswer
  28. * @param bool $showTotalScoreAndUserChoices
  29. *
  30. * @return void
  31. */
  32. public static function display_fill_in_blanks_answer(
  33. $feedbackType,
  34. $answer,
  35. $id,
  36. $questionId,
  37. $resultsDisabled,
  38. $originalStudentAnswer = '',
  39. $showTotalScoreAndUserChoices
  40. ) {
  41. $answerHTML = FillBlanks::getHtmlDisplayForAnswer($answer, $feedbackType, $resultsDisabled, $showTotalScoreAndUserChoices);
  42. if (strpos($originalStudentAnswer, 'font color') !== false) {
  43. $answerHTML = $originalStudentAnswer;
  44. }
  45. if (empty($id)) {
  46. echo '<tr><td>';
  47. echo Security::remove_XSS($answerHTML, COURSEMANAGERLOWSECURITY);
  48. echo '</td></tr>';
  49. } else {
  50. ?>
  51. <tr>
  52. <td>
  53. <?php echo Security::remove_XSS($answerHTML, COURSEMANAGERLOWSECURITY); ?>
  54. </td>
  55. <?php
  56. if (!api_is_allowed_to_edit(null, true) && $feedbackType != EXERCISE_FEEDBACK_TYPE_EXAM) { ?>
  57. <td>
  58. <?php
  59. $comm = Event::get_comments($id, $questionId);
  60. ?>
  61. </td>
  62. <?php } ?>
  63. </tr>
  64. <?php
  65. }
  66. }
  67. /**
  68. * Shows the answer to a calculated question, as HTML
  69. * @param string Answer text
  70. * @param int Exercise ID
  71. * @param int Question ID
  72. * @return void
  73. */
  74. public static function display_calculated_answer(
  75. $feedback_type,
  76. $answer,
  77. $id,
  78. $questionId,
  79. $results_disabled,
  80. $showTotalScoreAndUserChoices
  81. ) {
  82. if (empty($id)) {
  83. echo '<tr><td>'.Security::remove_XSS($answer).'</td></tr>';
  84. } else {
  85. ?>
  86. <tr>
  87. <td>
  88. <?php
  89. echo Security::remove_XSS($answer);
  90. ?>
  91. </td>
  92. <?php
  93. if (!api_is_allowed_to_edit(null, true) && $feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) { ?>
  94. <td>
  95. <?php
  96. $comm = Event::get_comments($id, $questionId);
  97. ?>
  98. </td>
  99. <?php } ?>
  100. </tr>
  101. <?php
  102. }
  103. }
  104. /**
  105. * Shows the answer to a free-answer question, as HTML
  106. * @param string Answer text
  107. * @param int Exercise ID
  108. * @param int Question ID
  109. * @return void
  110. */
  111. public static function display_free_answer(
  112. $feedback_type,
  113. $answer,
  114. $exe_id,
  115. $questionId,
  116. $questionScore = null,
  117. $results_disabled = 0
  118. ) {
  119. $comments = Event::get_comments($exe_id, $questionId);
  120. if (!empty($answer)) {
  121. echo '<tr><td>';
  122. echo Security::remove_XSS($answer);
  123. echo '</td></tr>';
  124. }
  125. if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
  126. if ($questionScore > 0 || !empty($comments)) {
  127. } else {
  128. echo '<tr>';
  129. echo Display::tag('td', ExerciseLib::getNotCorrectedYetText(), []);
  130. echo '</tr>';
  131. }
  132. }
  133. }
  134. /**
  135. * @param $feedback_type
  136. * @param $answer
  137. * @param $id
  138. * @param $questionId
  139. * @param null $fileUrl
  140. * @param int $results_disabled
  141. * @param int $questionScore
  142. */
  143. public static function display_oral_expression_answer(
  144. $feedback_type,
  145. $answer,
  146. $id,
  147. $questionId,
  148. $fileUrl = null,
  149. $results_disabled = 0,
  150. $questionScore = 0
  151. )
  152. {
  153. if (isset($fileUrl)) {
  154. echo '
  155. <tr>
  156. <td><audio src="' . $fileUrl.'" controls></audio></td>
  157. </tr>
  158. ';
  159. }
  160. if (empty($id)) {
  161. echo '<tr>';
  162. echo Display::tag('td', Security::remove_XSS($answer), array('width'=>'55%'));
  163. echo '</tr>';
  164. if (!$questionScore && $feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
  165. echo '<tr>';
  166. echo Display::tag('td', ExerciseLib::getNotCorrectedYetText(), array('width'=>'45%'));
  167. echo '</tr>';
  168. } else {
  169. echo '<tr><td>&nbsp;</td></tr>';
  170. }
  171. } else {
  172. echo '<tr>';
  173. echo '<td>';
  174. if (!empty($answer)) {
  175. echo Security::remove_XSS($answer);
  176. }
  177. echo '</td>';
  178. if (!api_is_allowed_to_edit(null, true) && $feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
  179. echo '<td>';
  180. $comm = Event::get_comments($id, $questionId);
  181. echo '</td>';
  182. }
  183. echo '</tr>';
  184. }
  185. }
  186. /**
  187. * Displays the answer to a hotspot question
  188. * @param int $feedback_type
  189. * @param int $answerId
  190. * @param string $answer
  191. * @param string $studentChoice
  192. * @param string $answerComment
  193. * @param int $resultsDisabled
  194. * @param int $orderColor
  195. * @param bool $showTotalScoreAndUserChoices
  196. */
  197. public static function display_hotspot_answer(
  198. $feedback_type,
  199. $answerId,
  200. $answer,
  201. $studentChoice,
  202. $answerComment,
  203. $resultsDisabled,
  204. $orderColor,
  205. $showTotalScoreAndUserChoices
  206. ) {
  207. $hide_expected_answer = false;
  208. if ($feedback_type == 0 && $resultsDisabled == 2) {
  209. $hide_expected_answer = true;
  210. }
  211. if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
  212. if ($showTotalScoreAndUserChoices) {
  213. $hide_expected_answer = false;
  214. } else {
  215. $hide_expected_answer = true;
  216. }
  217. }
  218. $hotspot_colors = array(
  219. "", // $i starts from 1 on next loop (ugly fix)
  220. "#4271B5",
  221. "#FE8E16",
  222. "#45C7F0",
  223. "#BCD631",
  224. "#D63173",
  225. "#D7D7D7",
  226. "#90AFDD",
  227. "#AF8640",
  228. "#4F9242",
  229. "#F4EB24",
  230. "#ED2024",
  231. "#3B3B3B",
  232. "#F7BDE2"
  233. );
  234. ?>
  235. <table class="data_table">
  236. <tr>
  237. <td class="text-center" width="5%">
  238. <span class="fa fa-square fa-fw fa-2x" aria-hidden="true" style="color: <?php echo $hotspot_colors[$orderColor]; ?>"></span>
  239. </td>
  240. <td class="text-left" width="25%">
  241. <?php echo "$answerId - $answer"; ?>
  242. </td>
  243. <td class="text-left" width="10%">
  244. <?php
  245. if (!$hide_expected_answer) {
  246. $my_choice = $studentChoice ? get_lang('Correct') : get_lang('Fault');
  247. echo $my_choice;
  248. }
  249. ?>
  250. </td>
  251. <?php if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) { ?>
  252. <td class="text-left" width="60%">
  253. <?php
  254. if ($studentChoice) {
  255. echo '<span style="font-weight: bold; color: #008000;">'.nl2br($answerComment).'</span>';
  256. }
  257. ?>
  258. </td>
  259. <?php } else { ?>
  260. <td class="text-left" width="60%">&nbsp;</td>
  261. <?php } ?>
  262. </tr>
  263. <?php
  264. }
  265. /**
  266. * Display the answers to a multiple choice question
  267. * @param int $feedback_type Feedback type
  268. * @param int $answerType Answer type
  269. * @param int $studentChoice Student choice
  270. * @param string $answer Textual answer
  271. * @param string $answerComment Comment on answer
  272. * @param string $answerCorrect Correct answer comment
  273. * @param int $id Exercise ID
  274. * @param int $questionId Question ID
  275. * @param boolean $ans Whether to show the answer comment or not
  276. * @param bool $resultsDisabled
  277. * @param bool $showTotalScoreAndUserChoices
  278. * @param bool $export
  279. * @return void
  280. */
  281. public static function display_unique_or_multiple_answer(
  282. $feedback_type,
  283. $answerType,
  284. $studentChoice,
  285. $answer,
  286. $answerComment,
  287. $answerCorrect,
  288. $id,
  289. $questionId,
  290. $ans,
  291. $resultsDisabled,
  292. $showTotalScoreAndUserChoices,
  293. $export = false
  294. ) {
  295. if ($export) {
  296. $answer = strip_tags_blacklist($answer, ['title', 'head']);
  297. // Fix answers that contains this tags
  298. $tags = [
  299. '<html>',
  300. '</html>',
  301. '<body>',
  302. '</body>'
  303. ];
  304. $answer = str_replace($tags, '', $answer);
  305. }
  306. $hide_expected_answer = false;
  307. if ($feedback_type == 0 && ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ONLY)) {
  308. $hide_expected_answer = true;
  309. }
  310. if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
  311. if ($showTotalScoreAndUserChoices) {
  312. $hide_expected_answer = false;
  313. } else {
  314. $hide_expected_answer = true;
  315. }
  316. }
  317. $icon = in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION)) ? 'radio' : 'checkbox';
  318. $icon .= $studentChoice ? '_on' : '_off';
  319. $icon .= '.png';
  320. $iconAnswer = in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION)) ? 'radio' : 'checkbox';
  321. $iconAnswer .= $answerCorrect ? '_on' : '_off';
  322. $iconAnswer .= '.png';
  323. ?>
  324. <tr>
  325. <td width="5%">
  326. <?php echo Display::return_icon($icon, null, null, ICON_SIZE_TINY); ?>
  327. </td>
  328. <td width="5%">
  329. <?php if (!$hide_expected_answer) {
  330. echo Display::return_icon($iconAnswer, null, null, ICON_SIZE_TINY);
  331. } else {
  332. echo "-";
  333. } ?>
  334. </td>
  335. <td width="40%">
  336. <?php
  337. echo $answer;
  338. ?>
  339. </td>
  340. <?php if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) { ?>
  341. <td width="20%">
  342. <?php
  343. if ($studentChoice) {
  344. if ($answerCorrect) {
  345. $color = 'green';
  346. //echo '<span style="font-weight: bold; color: #008000;">'.nl2br($answerComment).'</span>';
  347. } else {
  348. $color = 'black';
  349. //echo '<span style="font-weight: bold; color: #FF0000;">'.nl2br($answerComment).'</span>';
  350. }
  351. if ($hide_expected_answer) {
  352. $color = '';
  353. }
  354. echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br($answerComment).'</span>';
  355. }
  356. ?>
  357. </td>
  358. <?php
  359. if ($ans == 1) {
  360. $comm = Event::get_comments($id, $questionId);
  361. }
  362. ?>
  363. <?php } else { ?>
  364. <td>&nbsp;</td>
  365. <?php } ?>
  366. </tr>
  367. <?php
  368. }
  369. /**
  370. * Display the answers to a multiple choice question
  371. *
  372. * @param integer Answer type
  373. * @param integer Student choice
  374. * @param string Textual answer
  375. * @param string Comment on answer
  376. * @param string Correct answer comment
  377. * @param integer Exercise ID
  378. * @param integer Question ID
  379. * @param boolean Whether to show the answer comment or not
  380. * @return void
  381. */
  382. public static function display_multiple_answer_true_false(
  383. $feedback_type,
  384. $answerType,
  385. $studentChoice,
  386. $answer,
  387. $answerComment,
  388. $answerCorrect,
  389. $id,
  390. $questionId,
  391. $ans,
  392. $resultsDisabled,
  393. $showTotalScoreAndUserChoices
  394. ) {
  395. $hide_expected_answer = false;
  396. if ($feedback_type == 0 && ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ONLY)) {
  397. $hide_expected_answer = true;
  398. }
  399. if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
  400. if ($showTotalScoreAndUserChoices) {
  401. $hide_expected_answer = false;
  402. } else {
  403. $hide_expected_answer = true;
  404. }
  405. }
  406. ?>
  407. <tr>
  408. <td width="5%">
  409. <?php
  410. $course_id = api_get_course_int_id();
  411. $new_options = Question::readQuestionOption($questionId, $course_id);
  412. //Your choice
  413. if (isset($new_options[$studentChoice])) {
  414. echo get_lang($new_options[$studentChoice]['name']);
  415. } else {
  416. echo '-';
  417. }
  418. ?>
  419. </td>
  420. <td width="5%">
  421. <?php
  422. //Expected choice
  423. if (!$hide_expected_answer) {
  424. if (isset($new_options[$answerCorrect])) {
  425. echo get_lang($new_options[$answerCorrect]['name']);
  426. } else {
  427. echo '-';
  428. }
  429. } else {
  430. echo '-';
  431. }
  432. ?>
  433. </td>
  434. <td width="40%">
  435. <?php echo $answer; ?>
  436. </td>
  437. <?php if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) { ?>
  438. <td width="20%">
  439. <?php
  440. $color = "black";
  441. if (isset($new_options[$studentChoice])) {
  442. if ($studentChoice == $answerCorrect) {
  443. $color = "green";
  444. }
  445. if ($hide_expected_answer) {
  446. $color = '';
  447. }
  448. echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br($answerComment).'</span>';
  449. }
  450. ?>
  451. </td>
  452. <?php
  453. if ($ans == 1) {
  454. $comm = Event::get_comments($id, $questionId);
  455. }
  456. ?>
  457. <?php } else { ?>
  458. <td>&nbsp;</td>
  459. <?php } ?>
  460. </tr>
  461. <?php
  462. }
  463. /**
  464. * Display the answers to a multiple choice question
  465. *
  466. * @param integer Answer type
  467. * @param integer Student choice
  468. * @param string Textual answer
  469. * @param string Comment on answer
  470. * @param string Correct answer comment
  471. * @param integer Exercise ID
  472. * @param integer Question ID
  473. * @param boolean Whether to show the answer comment or not
  474. * @return void
  475. */
  476. public static function display_multiple_answer_combination_true_false(
  477. $feedback_type,
  478. $answerType,
  479. $studentChoice,
  480. $answer,
  481. $answerComment,
  482. $answerCorrect,
  483. $id,
  484. $questionId,
  485. $ans,
  486. $resultsDisabled,
  487. $showTotalScoreAndUserChoices
  488. ) {
  489. $hide_expected_answer = false;
  490. if ($feedback_type == 0 && ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ONLY)) {
  491. $hide_expected_answer = true;
  492. }
  493. if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
  494. if ($showTotalScoreAndUserChoices) {
  495. $hide_expected_answer = false;
  496. } else {
  497. $hide_expected_answer = true;
  498. }
  499. }
  500. ?>
  501. <tr>
  502. <td width="5%">
  503. <?php
  504. //Your choice
  505. $question = new MultipleAnswerCombinationTrueFalse();
  506. if (isset($question->options[$studentChoice])) {
  507. echo $question->options[$studentChoice];
  508. } else {
  509. echo $question->options[2];
  510. }
  511. ?>
  512. </td>
  513. <td width="5%">
  514. <?php
  515. //Expected choice
  516. if (!$hide_expected_answer) {
  517. if (isset($question->options[$answerCorrect])) {
  518. echo $question->options[$answerCorrect];
  519. } else {
  520. echo $question->options[2];
  521. }
  522. } else {
  523. echo '-';
  524. }
  525. ?>
  526. </td>
  527. <td width="40%">
  528. <?php
  529. //my answer
  530. echo $answer;
  531. ?>
  532. </td>
  533. <?php
  534. if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) { ?>
  535. <td width="20%">
  536. <?php
  537. //@todo replace this harcoded value
  538. if ($studentChoice) {
  539. $color = "black";
  540. if ($studentChoice == $answerCorrect) {
  541. $color = "green";
  542. }
  543. if ($hide_expected_answer) {
  544. $color = '';
  545. }
  546. echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br($answerComment).'</span>';
  547. }
  548. ?>
  549. </td>
  550. <?php
  551. if ($ans == 1) {
  552. $comm = Event::get_comments($id, $questionId);
  553. }
  554. } else {
  555. echo '<td>&nbsp;</td>';
  556. }
  557. echo '</tr>';
  558. }
  559. /**
  560. * @param $feedback_type
  561. * @param $exe_id
  562. * @param $questionId
  563. * @param null $questionScore
  564. * @param int $results_disabled
  565. */
  566. public static function displayAnnotationAnswer(
  567. $feedback_type,
  568. $exe_id,
  569. $questionId,
  570. $questionScore = null,
  571. $results_disabled = 0
  572. ) {
  573. $comments = Event::get_comments($exe_id, $questionId);
  574. if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
  575. if ($questionScore <= 0 && empty($comments)) {
  576. echo '<br />'.ExerciseLib::getNotCorrectedYetText();
  577. }
  578. }
  579. }
  580. }