exercise_show_functions.lib.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  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. *
  13. * @todo convert queries to use Database API
  14. */
  15. /**
  16. * Class.
  17. *
  18. * @package chamilo.library
  19. */
  20. class ExerciseShowFunctions
  21. {
  22. /**
  23. * Shows the answer to a fill-in-the-blanks question, as HTML.
  24. *
  25. * @param Exercise $exercise
  26. * @param int $feedbackType
  27. * @param string $answer
  28. * @param int $id Exercise ID
  29. * @param int $questionId Question ID
  30. * @param int $resultsDisabled
  31. * @param string $originalStudentAnswer
  32. * @param bool $showTotalScoreAndUserChoices
  33. */
  34. public static function display_fill_in_blanks_answer(
  35. $exercise,
  36. $feedbackType,
  37. $answer,
  38. $id,
  39. $questionId,
  40. $resultsDisabled,
  41. $originalStudentAnswer = '',
  42. $showTotalScoreAndUserChoices
  43. ) {
  44. $answerHTML = FillBlanks::getHtmlDisplayForAnswer(
  45. $answer,
  46. $feedbackType,
  47. $resultsDisabled,
  48. $showTotalScoreAndUserChoices
  49. );
  50. if (empty($id)) {
  51. echo '<tr><td>';
  52. echo Security::remove_XSS($answerHTML, COURSEMANAGERLOWSECURITY);
  53. echo '</td></tr>';
  54. } else {
  55. echo '<tr><td>';
  56. echo Security::remove_XSS($answerHTML, COURSEMANAGERLOWSECURITY);
  57. echo '</td>';
  58. echo '</tr>';
  59. }
  60. }
  61. /**
  62. * Shows the answer to a calculated question, as HTML.
  63. *
  64. * @param Exercise $exercise
  65. * @param string Answer text
  66. * @param int Exercise ID
  67. * @param int Question ID
  68. */
  69. public static function display_calculated_answer(
  70. $exercise,
  71. $feedback_type,
  72. $answer,
  73. $id,
  74. $questionId,
  75. $resultsDisabled,
  76. $showTotalScoreAndUserChoices,
  77. $expectedChoice = '',
  78. $choice = '',
  79. $status = ''
  80. ) {
  81. if ($exercise->showExpectedChoice()) {
  82. if (empty($id)) {
  83. echo '<tr><td>'.Security::remove_XSS($answer).'</td>';
  84. echo '<td>'.Security::remove_XSS($choice).'</td>';
  85. if ($exercise->showExpectedChoiceColumn()) {
  86. echo '<td>'.Security::remove_XSS($expectedChoice).'</td>';
  87. }
  88. echo '<td>'.Security::remove_XSS($status).'</td>';
  89. echo '</tr>';
  90. } else {
  91. echo '<tr><td>';
  92. echo Security::remove_XSS($answer);
  93. echo '</td><td>';
  94. echo Security::remove_XSS($choice);
  95. echo '</td>';
  96. if ($exercise->showExpectedChoiceColumn()) {
  97. echo '<td>';
  98. echo Security::remove_XSS($expectedChoice);
  99. echo '</td>';
  100. }
  101. echo '<td>';
  102. echo Security::remove_XSS($status);
  103. echo '</td>';
  104. echo '</tr>';
  105. }
  106. } else {
  107. if (empty($id)) {
  108. echo '<tr><td>'.Security::remove_XSS($answer).'</td></tr>';
  109. } else {
  110. echo '<tr><td>';
  111. echo Security::remove_XSS($answer);
  112. echo '</tr>';
  113. }
  114. }
  115. }
  116. /**
  117. * Shows the answer to a free-answer question, as HTML.
  118. *
  119. * @param string Answer text
  120. * @param int Exercise ID
  121. * @param int Question ID
  122. */
  123. public static function display_free_answer(
  124. $feedback_type,
  125. $answer,
  126. $exe_id,
  127. $questionId,
  128. $questionScore = null,
  129. $resultsDisabled = 0
  130. ) {
  131. $comments = Event::get_comments($exe_id, $questionId);
  132. if (!empty($answer)) {
  133. echo '<tr><td>';
  134. echo Security::remove_XSS($answer);
  135. echo '</td></tr>';
  136. }
  137. if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
  138. if ($questionScore > 0 || !empty($comments)) {
  139. } else {
  140. echo '<tr>';
  141. echo Display::tag('td', ExerciseLib::getNotCorrectedYetText());
  142. echo '</tr>';
  143. }
  144. }
  145. }
  146. /**
  147. * @param $feedback_type
  148. * @param $answer
  149. * @param $id
  150. * @param $questionId
  151. * @param null $fileUrl
  152. * @param int $resultsDisabled
  153. * @param int $questionScore
  154. */
  155. public static function display_oral_expression_answer(
  156. $feedback_type,
  157. $answer,
  158. $id,
  159. $questionId,
  160. $fileUrl = null,
  161. $resultsDisabled = 0,
  162. $questionScore = 0
  163. ) {
  164. if (isset($fileUrl)) {
  165. echo '
  166. <tr>
  167. <td><audio src="'.$fileUrl.'" controls></audio></td>
  168. </tr>
  169. ';
  170. }
  171. if (empty($id)) {
  172. echo '<tr>';
  173. if (!empty($answer)) {
  174. echo Display::tag('td', Security::remove_XSS($answer), ['width' => '55%']);
  175. }
  176. echo '</tr>';
  177. if (!$questionScore && $feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
  178. echo '<tr>';
  179. echo Display::tag('td', ExerciseLib::getNotCorrectedYetText(), ['width' => '45%']);
  180. echo '</tr>';
  181. } else {
  182. echo '<tr><td>&nbsp;</td></tr>';
  183. }
  184. } else {
  185. echo '<tr>';
  186. echo '<td>';
  187. if (!empty($answer)) {
  188. echo Security::remove_XSS($answer);
  189. }
  190. echo '</td>';
  191. echo '</tr>';
  192. }
  193. }
  194. /**
  195. * Displays the answer to a hotspot question.
  196. *
  197. * @param int $feedback_type
  198. * @param int $answerId
  199. * @param string $answer
  200. * @param string $studentChoice
  201. * @param string $answerComment
  202. * @param int $resultsDisabled
  203. * @param int $orderColor
  204. * @param bool $showTotalScoreAndUserChoices
  205. */
  206. public static function display_hotspot_answer(
  207. $feedback_type,
  208. $answerId,
  209. $answer,
  210. $studentChoice,
  211. $answerComment,
  212. $resultsDisabled,
  213. $orderColor,
  214. $showTotalScoreAndUserChoices
  215. ) {
  216. $hide_expected_answer = false;
  217. switch ($resultsDisabled) {
  218. case RESULT_DISABLE_SHOW_SCORE_ONLY:
  219. if ($feedback_type == 0) {
  220. $hide_expected_answer = true;
  221. }
  222. break;
  223. case RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK:
  224. case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT:
  225. $hide_expected_answer = true;
  226. if ($showTotalScoreAndUserChoices) {
  227. $hide_expected_answer = false;
  228. }
  229. break;
  230. }
  231. $hotspot_colors = [
  232. '', // $i starts from 1 on next loop (ugly fix)
  233. '#4271B5',
  234. '#FE8E16',
  235. '#45C7F0',
  236. '#BCD631',
  237. '#D63173',
  238. '#D7D7D7',
  239. '#90AFDD',
  240. '#AF8640',
  241. '#4F9242',
  242. '#F4EB24',
  243. '#ED2024',
  244. '#3B3B3B',
  245. '#F7BDE2',
  246. ];
  247. $content = '<table class="data_table"><tr>';
  248. $content .= '<td class="text-center" width="5%">';
  249. $content .= '<span class="fa fa-square fa-fw fa-2x" aria-hidden="true" style="color:'.
  250. $hotspot_colors[$orderColor].'"></span>';
  251. $content .= '</td>';
  252. $content .= '<td class="text-left" width="25%">';
  253. $content .= "$answerId - $answer";
  254. $content .= '</td>';
  255. $content .= '<td class="text-left" width="10%">';
  256. if (!$hide_expected_answer) {
  257. $status = Display::label(get_lang('Incorrect'), 'danger');
  258. if ($studentChoice) {
  259. $status = Display::label(get_lang('Correct'), 'success');
  260. } else {
  261. if (in_array($resultsDisabled, [
  262. RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
  263. ])
  264. ) {
  265. return '';
  266. }
  267. }
  268. $content .= $status;
  269. }
  270. $content .= '</td>';
  271. if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
  272. $content .= '<td class="text-left" width="60%">';
  273. if ($studentChoice) {
  274. $content .= '<span style="font-weight: bold; color: #008000;">'.nl2br($answerComment).'</span>';
  275. }
  276. $content .= '</td>';
  277. } else {
  278. $content .= '<td class="text-left" width="60%">&nbsp;</td>';
  279. }
  280. $content .= '</tr>';
  281. echo $content;
  282. }
  283. /**
  284. * Display the answers to a multiple choice question.
  285. *
  286. * @param Exercise $exercise
  287. * @param int $feedbackType Feedback type
  288. * @param int $answerType Answer type
  289. * @param int $studentChoice Student choice
  290. * @param string $answer Textual answer
  291. * @param string $answerComment Comment on answer
  292. * @param string $answerCorrect Correct answer comment
  293. * @param int $id Exercise ID
  294. * @param int $questionId Question ID
  295. * @param bool $ans Whether to show the answer comment or not
  296. * @param bool $resultsDisabled
  297. * @param bool $showTotalScoreAndUserChoices
  298. * @param bool $export
  299. */
  300. public static function display_unique_or_multiple_answer(
  301. $exercise,
  302. $feedbackType,
  303. $answerType,
  304. $studentChoice,
  305. $answer,
  306. $answerComment,
  307. $answerCorrect,
  308. $id,
  309. $questionId,
  310. $ans,
  311. $resultsDisabled,
  312. $showTotalScoreAndUserChoices,
  313. $export = false
  314. ) {
  315. if ($export) {
  316. $answer = strip_tags_blacklist($answer, ['title', 'head']);
  317. // Fix answers that contains this tags
  318. $tags = [
  319. '<html>',
  320. '</html>',
  321. '<body>',
  322. '</body>',
  323. ];
  324. $answer = str_replace($tags, '', $answer);
  325. }
  326. $studentChoiceInt = (int) $studentChoice;
  327. $answerCorrectChoice = (int) $answerCorrect;
  328. $hide_expected_answer = false;
  329. $showComment = false;
  330. switch ($resultsDisabled) {
  331. case RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER:
  332. $hide_expected_answer = true;
  333. $showComment = true;
  334. if (!$answerCorrect && empty($studentChoice)) {
  335. return '';
  336. }
  337. break;
  338. case RESULT_DISABLE_SHOW_SCORE_ONLY:
  339. if ($feedbackType == 0) {
  340. $hide_expected_answer = true;
  341. }
  342. break;
  343. case RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK:
  344. case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT:
  345. $hide_expected_answer = true;
  346. if ($showTotalScoreAndUserChoices) {
  347. $hide_expected_answer = false;
  348. }
  349. break;
  350. }
  351. $icon = in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION]) ? 'radio' : 'checkbox';
  352. $icon .= $studentChoice ? '_on' : '_off';
  353. $icon .= '.png';
  354. $iconAnswer = in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION]) ? 'radio' : 'checkbox';
  355. $iconAnswer .= $answerCorrect ? '_on' : '_off';
  356. $iconAnswer .= '.png';
  357. $studentChoiceClass = '';
  358. if (in_array(
  359. $resultsDisabled,
  360. [
  361. RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
  362. RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING,
  363. ]
  364. )
  365. ) {
  366. if ($answerCorrect) {
  367. $studentChoiceClass = 'success';
  368. }
  369. }
  370. echo '<tr class="'.$studentChoiceClass.'">';
  371. echo '<td width="5%">';
  372. echo Display::return_icon($icon, null, null, ICON_SIZE_TINY);
  373. echo '</td>';
  374. if ($exercise->showExpectedChoiceColumn()) {
  375. if ($hide_expected_answer === false) {
  376. echo '<td width="5%">';
  377. echo Display::return_icon($iconAnswer, null, null, ICON_SIZE_TINY);
  378. echo '</td>';
  379. } else {
  380. echo '<td width="5%">';
  381. echo '-';
  382. echo '</td>';
  383. }
  384. }
  385. echo '<td width="40%">';
  386. echo $answer;
  387. echo '</td>';
  388. if ($exercise->showExpectedChoice()) {
  389. $status = Display::label(get_lang('Incorrect'), 'danger');
  390. if ($answerCorrect || ($answerCorrect && $studentChoiceInt === $answerCorrectChoice)) {
  391. $status = Display::label(get_lang('Correct'), 'success');
  392. }
  393. echo '<td width="20%">';
  394. // Show only status for the selected student answer BT#16256
  395. if ($studentChoice) {
  396. echo $status;
  397. }
  398. echo '</td>';
  399. }
  400. if ($feedbackType != EXERCISE_FEEDBACK_TYPE_EXAM) {
  401. $showComment = true;
  402. }
  403. if ($showComment) {
  404. echo '<td width="20%">';
  405. $color = 'black';
  406. if ($answerCorrect) {
  407. $color = 'green';
  408. }
  409. if ($hide_expected_answer) {
  410. $color = '';
  411. }
  412. $comment = '<span style="font-weight: bold; color: '.$color.';">'.
  413. Security::remove_XSS($answerComment).
  414. '</span>';
  415. echo $comment;
  416. echo '</td>';
  417. } else {
  418. echo '<td>&nbsp;</td>';
  419. }
  420. echo '</tr>';
  421. }
  422. /**
  423. * Display the answers to a multiple choice question.
  424. *
  425. * @param Exercise $exercise
  426. * @param int Answer type
  427. * @param int Student choice
  428. * @param string Textual answer
  429. * @param string Comment on answer
  430. * @param string Correct answer comment
  431. * @param int Exercise ID
  432. * @param int Question ID
  433. * @param bool Whether to show the answer comment or not
  434. */
  435. public static function display_multiple_answer_true_false(
  436. $exercise,
  437. $feedbackType,
  438. $answerType,
  439. $studentChoice,
  440. $answer,
  441. $answerComment,
  442. $answerCorrect,
  443. $id,
  444. $questionId,
  445. $ans,
  446. $resultsDisabled,
  447. $showTotalScoreAndUserChoices
  448. ) {
  449. $hide_expected_answer = false;
  450. $hideStudentChoice = false;
  451. switch ($resultsDisabled) {
  452. //case RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING:
  453. case RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER:
  454. $hideStudentChoice = false;
  455. $hide_expected_answer = true;
  456. break;
  457. case RESULT_DISABLE_SHOW_SCORE_ONLY:
  458. if ($feedbackType == 0) {
  459. $hide_expected_answer = true;
  460. }
  461. break;
  462. case RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK:
  463. case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT:
  464. $hide_expected_answer = true;
  465. if ($showTotalScoreAndUserChoices) {
  466. $hide_expected_answer = false;
  467. }
  468. break;
  469. }
  470. $content = '<tr>';
  471. if ($hideStudentChoice === false) {
  472. $content .= '<td width="5%">';
  473. $course_id = api_get_course_int_id();
  474. $new_options = Question::readQuestionOption($questionId, $course_id);
  475. // Your choice
  476. if (isset($new_options[$studentChoice])) {
  477. $content .= get_lang($new_options[$studentChoice]['name']);
  478. } else {
  479. $content .= '-';
  480. }
  481. $content .= '</td>';
  482. }
  483. // Expected choice
  484. if ($exercise->showExpectedChoiceColumn()) {
  485. if (!$hide_expected_answer) {
  486. $content .= '<td width="5%">';
  487. if (isset($new_options[$answerCorrect])) {
  488. $content .= get_lang($new_options[$answerCorrect]['name']);
  489. } else {
  490. $content .= '-';
  491. }
  492. $content .= '</td>';
  493. }
  494. }
  495. $content .= '<td width="40%">';
  496. $content .= $answer;
  497. $content .= '</td>';
  498. if ($exercise->showExpectedChoice()) {
  499. $status = Display::label(get_lang('Incorrect'), 'danger');
  500. if (isset($new_options[$studentChoice])) {
  501. if ($studentChoice == $answerCorrect) {
  502. $status = Display::label(get_lang('Correct'), 'success');
  503. }
  504. }
  505. $content .= '<td width="20%">';
  506. $content .= $status;
  507. $content .= '</td>';
  508. }
  509. if ($feedbackType != EXERCISE_FEEDBACK_TYPE_EXAM) {
  510. $content .= '<td width="20%">';
  511. $color = 'black';
  512. if (isset($new_options[$studentChoice]) || in_array(
  513. $exercise->results_disabled,
  514. [
  515. RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
  516. RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING,
  517. ]
  518. )
  519. ) {
  520. if ($studentChoice == $answerCorrect) {
  521. $color = 'green';
  522. }
  523. if ($hide_expected_answer) {
  524. $color = '';
  525. }
  526. $content .= '<span style="font-weight: bold; color: '.$color.';">'.nl2br($answerComment).'</span>';
  527. }
  528. $content .= '</td>';
  529. }
  530. $content .= '</tr>';
  531. echo $content;
  532. }
  533. /**
  534. * Display the answers to a multiple choice question.
  535. *
  536. * @param Exercise $exercise
  537. * @param int $feedbackType
  538. * @param int $studentChoice
  539. * @param int $studentChoiceDegree
  540. * @param string $answer
  541. * @param string $answerComment
  542. * @param int $answerCorrect
  543. * @param int $questionId
  544. * @param bool $inResultsDisabled
  545. */
  546. public static function displayMultipleAnswerTrueFalseDegreeCertainty(
  547. $exercise,
  548. $feedbackType,
  549. $studentChoice,
  550. $studentChoiceDegree,
  551. $answer,
  552. $answerComment,
  553. $answerCorrect,
  554. $questionId,
  555. $inResultsDisabled
  556. ) {
  557. $hideExpectedAnswer = false;
  558. if ($feedbackType == 0 && $inResultsDisabled == 2) {
  559. $hideExpectedAnswer = true;
  560. }
  561. echo '<tr><td width="5%">';
  562. $question = new MultipleAnswerTrueFalseDegreeCertainty();
  563. $courseId = api_get_course_int_id();
  564. $newOptions = Question::readQuestionOption($questionId, $courseId);
  565. // Your choice
  566. if (isset($newOptions[$studentChoice])) {
  567. echo get_lang($newOptions[$studentChoice]['name']);
  568. } else {
  569. echo '-';
  570. }
  571. echo '</td>';
  572. // Expected choice
  573. if ($exercise->showExpectedChoiceColumn()) {
  574. echo '<td width="5%">';
  575. if (!$hideExpectedAnswer) {
  576. if (isset($newOptions[$answerCorrect])) {
  577. echo get_lang($newOptions[$answerCorrect]['name']);
  578. } else {
  579. echo '-';
  580. }
  581. } else {
  582. echo '-';
  583. }
  584. echo '</td>';
  585. }
  586. echo '<td width="20%">';
  587. echo $answer;
  588. echo '</td><td width="5%" style="text-align:center;">';
  589. if (isset($newOptions[$studentChoiceDegree])) {
  590. echo $newOptions[$studentChoiceDegree]['name'];
  591. }
  592. echo '</td>';
  593. $position = isset($newOptions[$studentChoiceDegree]) ? $newOptions[$studentChoiceDegree]['position'] : '';
  594. $degreeInfo = $question->getResponseDegreeInfo(
  595. $studentChoice,
  596. $answerCorrect,
  597. $position
  598. );
  599. $degreeInfo['color'] = isset($degreeInfo['color']) ? $degreeInfo['color'] : '';
  600. $degreeInfo['background-color'] = isset($degreeInfo['background-color']) ? $degreeInfo['background-color'] : '';
  601. $degreeInfo['description'] = isset($degreeInfo['description']) ? $degreeInfo['description'] : '';
  602. $degreeInfo['label'] = isset($degreeInfo['label']) ? $degreeInfo['label'] : '';
  603. echo '
  604. <td width="15%">
  605. <div style="text-align:center;color: '.$degreeInfo['color'].';
  606. background-color: '.$degreeInfo['background-color'].';
  607. line-height:30px;height:30px;width: 100%;margin:auto;"
  608. title="'.$degreeInfo['description'].'">'.
  609. nl2br($degreeInfo['label']).
  610. '</div>
  611. </td>';
  612. if ($feedbackType != EXERCISE_FEEDBACK_TYPE_EXAM) {
  613. echo '<td width="20%">';
  614. if (isset($newOptions[$studentChoice])) {
  615. echo '<span style="font-weight: bold; color: black;">'.nl2br($answerComment).'</span>';
  616. }
  617. echo '</td>';
  618. } else {
  619. echo '<td>&nbsp;</td>';
  620. }
  621. echo '</tr>';
  622. }
  623. /**
  624. * Display the answers to a multiple choice question.
  625. *
  626. * @param Exercise $exercise
  627. * @param int Answer type
  628. * @param int Student choice
  629. * @param string Textual answer
  630. * @param string Comment on answer
  631. * @param string Correct answer comment
  632. * @param int Exercise ID
  633. * @param int Question ID
  634. * @param bool Whether to show the answer comment or not
  635. */
  636. public static function display_multiple_answer_combination_true_false(
  637. $exercise,
  638. $feedbackType,
  639. $answerType,
  640. $studentChoice,
  641. $answer,
  642. $answerComment,
  643. $answerCorrect,
  644. $id,
  645. $questionId,
  646. $ans,
  647. $resultsDisabled,
  648. $showTotalScoreAndUserChoices
  649. ) {
  650. $hide_expected_answer = false;
  651. $hideStudentChoice = false;
  652. switch ($resultsDisabled) {
  653. case RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING:
  654. case RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER:
  655. $hideStudentChoice = true;
  656. $hide_expected_answer = true;
  657. break;
  658. case RESULT_DISABLE_SHOW_SCORE_ONLY:
  659. if ($feedbackType == 0) {
  660. $hide_expected_answer = true;
  661. }
  662. break;
  663. case RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK:
  664. case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT:
  665. $hide_expected_answer = true;
  666. if ($showTotalScoreAndUserChoices) {
  667. $hide_expected_answer = false;
  668. }
  669. break;
  670. }
  671. echo '<tr>';
  672. if ($hideStudentChoice === false) {
  673. echo '<td width="5%">';
  674. // Your choice
  675. $question = new MultipleAnswerCombinationTrueFalse();
  676. if (isset($question->options[$studentChoice])) {
  677. echo $question->options[$studentChoice];
  678. } else {
  679. echo $question->options[2];
  680. }
  681. echo '</td>';
  682. }
  683. // Expected choice
  684. if ($exercise->showExpectedChoiceColumn()) {
  685. if (!$hide_expected_answer) {
  686. echo '<td width="5%">';
  687. if (isset($question->options[$answerCorrect])) {
  688. echo $question->options[$answerCorrect];
  689. } else {
  690. echo $question->options[2];
  691. }
  692. echo '</td>';
  693. }
  694. }
  695. echo '<td width="40%">';
  696. echo $answer;
  697. echo '</td>';
  698. if ($exercise->showExpectedChoice()) {
  699. $status = '';
  700. if (isset($studentChoice)) {
  701. $status = Display::label(get_lang('Incorrect'), 'danger');
  702. if ($studentChoice == $answerCorrect) {
  703. $status = Display::label(get_lang('Correct'), 'success');
  704. }
  705. }
  706. echo '<td width="20%">';
  707. echo $status;
  708. echo '</td>';
  709. }
  710. if ($feedbackType != EXERCISE_FEEDBACK_TYPE_EXAM) {
  711. echo '<td width="20%">';
  712. //@todo replace this harcoded value
  713. if ($studentChoice || in_array($resultsDisabled, [
  714. RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
  715. RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING,
  716. ])
  717. ) {
  718. $color = 'black';
  719. if ($studentChoice == $answerCorrect) {
  720. $color = 'green';
  721. }
  722. if ($hide_expected_answer) {
  723. $color = '';
  724. }
  725. echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br($answerComment).'</span>';
  726. }
  727. echo '</td>';
  728. } else {
  729. echo '<td>&nbsp;</td>';
  730. }
  731. echo '</tr>';
  732. }
  733. /**
  734. * @param int $feedbackType
  735. * @param int $exeId
  736. * @param int $questionId
  737. * @param null $questionScore
  738. * @param int $resultsDisabled
  739. */
  740. public static function displayAnnotationAnswer(
  741. $feedbackType,
  742. $exeId,
  743. $questionId,
  744. $questionScore = null,
  745. $resultsDisabled = 0
  746. ) {
  747. $comments = Event::get_comments($exeId, $questionId);
  748. if ($feedbackType != EXERCISE_FEEDBACK_TYPE_EXAM) {
  749. if ($questionScore <= 0 && empty($comments)) {
  750. echo '<br />'.ExerciseLib::getNotCorrectedYetText();
  751. }
  752. }
  753. }
  754. }