From 531f5aa24e3f66c730bf48d2cd78f8e950c3364c Mon Sep 17 00:00:00 2001 From: jmontoyaa Date: Fri, 16 Feb 2018 08:15:47 +0100 Subject: [PATCH] Add setting "show_exercise_expected_choice" BT#13950 Show more information when resolving an exercise --- app/Resources/public/css/base.css | 44 +++ main/exercise/Draggable.php | 15 +- main/exercise/Hpdownload.php | 1 + main/exercise/MatchingDraggable.php | 17 +- main/exercise/TestCategory.php | 52 +-- main/exercise/UniqueAnswerImage.php | 24 ++ main/exercise/admin.php | 37 +- main/exercise/answer.class.php | 10 +- main/exercise/calculated_answer.class.php | 13 +- main/exercise/evalmathnotation.php | 1 + main/exercise/exercise.class.php | 268 ++++++++++--- main/exercise/exercise.php | 2 +- main/exercise/exercise_show.php | 15 + main/exercise/exercise_submit.php | 7 +- main/exercise/exercise_submit_modal.php | 2 - main/exercise/export/qti2/qti2_classes.php | 1 + main/exercise/fill_blanks.class.php | 30 +- .../exercise/global_multiple_answer.class.php | 15 +- main/exercise/hotspot.class.php | 2 +- main/exercise/matching.class.php | 14 +- main/exercise/multiple_answer.class.php | 14 +- .../multiple_answer_combination.class.php | 14 +- .../multiple_answer_true_false.class.php | 21 +- main/exercise/overview.php | 5 - main/exercise/question.class.php | 18 +- main/exercise/question_admin.inc.php | 2 - main/exercise/question_pool.php | 3 +- main/exercise/stats.php | 1 + main/exercise/unique_answer.class.php | 14 +- .../unique_answer_no_option.class.php | 18 +- main/img/icons/22/attempt-check.png | Bin 0 -> 1114 bytes main/img/icons/22/attempt-nocheck.png | Bin 0 -> 913 bytes main/inc/lib/exercise.lib.php | 46 ++- main/inc/lib/exercise_show_functions.lib.php | 359 +++++++++--------- main/install/configuration.dist.php | 3 +- 35 files changed, 672 insertions(+), 416 deletions(-) create mode 100644 main/img/icons/22/attempt-check.png create mode 100644 main/img/icons/22/attempt-nocheck.png diff --git a/app/Resources/public/css/base.css b/app/Resources/public/css/base.css index d7e42fa14d..8c6696cf21 100644 --- a/app/Resources/public/css/base.css +++ b/app/Resources/public/css/base.css @@ -7327,3 +7327,47 @@ input.form-control[type="color"] { .popover-content .popover-teacher .teachers-details{ text-align: left; } + + + +.feedback-green { + color: green; +} + +.feedback-red { + color: red; + text-decoration: line-through; +} + +.feedback-question { + margin-top: 5px; + margin-bottom: 5px; + display: block; +} + +.feedback-separator { + font-size:120%; +} + +.score-title { + color: #162a83; + font-weight: bold; + font-size: 16px; +} +.score-limits{ + padding-top: 5px; + padding-bottom: 5px; +} +.score-limits .score-img{ + display: inline-block; + padding-right: 5px; +} + +.feedback-question img { + padding-right: 5px; +} + +.question_row_answer img, .question_row img { + max-width: 80%; + height: auto !important; +} \ No newline at end of file diff --git a/main/exercise/Draggable.php b/main/exercise/Draggable.php index 0ee6c97002..17dd4d78c8 100644 --- a/main/exercise/Draggable.php +++ b/main/exercise/Draggable.php @@ -213,11 +213,16 @@ class Draggable extends Question public function return_header($exercise, $counter = null, $score = null) { $header = parent::return_header($exercise, $counter, $score); - $header .= ' - - - - '; + $header .= '
' . get_lang('ElementList').'' . get_lang('Status').'
'; + + if ($exercise->showExpectedChoice()) { + $header .= ''; + $header .= ''; + } else { + $header .= ''; + } + $header .= ''; + $header .= ''; return $header; } diff --git a/main/exercise/Hpdownload.php b/main/exercise/Hpdownload.php index 419e86da1d..06c0a133f9 100755 --- a/main/exercise/Hpdownload.php +++ b/main/exercise/Hpdownload.php @@ -144,3 +144,4 @@ if ($content_type == 'text/html') { $fp = fopen($full_file_name, 'rb'); fpassthru($fp); fclose($fp); + diff --git a/main/exercise/MatchingDraggable.php b/main/exercise/MatchingDraggable.php index 8833a38357..108c4bd812 100644 --- a/main/exercise/MatchingDraggable.php +++ b/main/exercise/MatchingDraggable.php @@ -264,11 +264,18 @@ class MatchingDraggable extends Question public function return_header($exercise, $counter = null, $score = null) { $header = parent::return_header($exercise, $counter, $score); - $header .= '
'.get_lang('YourChoice').''.get_lang('ExpectedChoice').''.get_lang('ElementList').''.get_lang('Status').'
- - - - '; + $header .= '
' . get_lang('ElementList').'' . get_lang('CorrespondsTo').'
'; + + $header .= ''; + if ($exercise->showExpectedChoice()) { + $header .= ''; + $header .= ''; + $header .= ''; + } else { + $header .= ''; + $header .= ''; + } + $header .= ''; return $header; } diff --git a/main/exercise/TestCategory.php b/main/exercise/TestCategory.php index e9d54b09c7..7b9d280b01 100644 --- a/main/exercise/TestCategory.php +++ b/main/exercise/TestCategory.php @@ -615,36 +615,34 @@ class TestCategory /** * @param int $questionId + * @param int $displayCategoryName */ - public static function displayCategoryAndTitle($questionId) + public static function displayCategoryAndTitle($questionId, $displayCategoryName = 1) { - echo self::returnCategoryAndTitle($questionId); + echo self::returnCategoryAndTitle($questionId, $displayCategoryName); } /** * @param int $questionId + * @param int $in_display_category_name * @return null|string */ - public static function returnCategoryAndTitle($questionId) + public static function returnCategoryAndTitle($questionId, $in_display_category_name = 1) { - $isStudent = !(api_is_allowed_to_edit(null, true) || api_is_session_admin()); + $is_student = !(api_is_allowed_to_edit(null, true) || api_is_session_admin()); $objExercise = Session::read('objExercise'); - if (empty($objExercise)) { - return ''; + if (!empty($objExercise)) { + $in_display_category_name = $objExercise->display_category_name; } - - $showCategoryName = !!$objExercise->display_category_name; //double negation to get a boolean value - $categoryName = self::getCategoryNameForQuestion($questionId); - - if (empty($categoryName) || (!$showCategoryName && $isStudent)) { - return ''; + $content = null; + if (self::getCategoryNameForQuestion($questionId) != '' && + ($in_display_category_name == 1 || !$is_student) + ) { + $content .= '"; } - - return Display::page_header( - get_lang('Category').': '.$categoryName, - null, - 'h4' - ); + return $content; } /** @@ -1018,7 +1016,7 @@ class TestCategory public function returnCategoryForm(Exercise $exercise) { $categories = $this->getListOfCategoriesForTest($exercise); - $saved_categories = $exercise->get_categories_in_exercise(); + $saved_categories = $exercise->getCategoriesInExercise(); $return = null; if (!empty($categories)) { @@ -1054,7 +1052,6 @@ class TestCategory $cat_id = $category['iid']; $return .= ''; $return .= ''; $return .= '
'.get_lang('ElementList').''.get_lang('YourChoice').''.get_lang('ExpectedChoice').''.get_lang('Status').''.get_lang('ElementList').''.get_lang('CorrespondsTo').'
'; - //$return .= Display::div(isset($category['parent_path']) ? $category['parent_path'] : ''); $return .= Display::div($category['name']); $return .= ''; @@ -1234,13 +1231,18 @@ class TestCategory return $html; } - // To allowed " in javascript dialog box without bad surprises - // replace " with two ' - public function protectJSDialogQuote($in_txt) + /** + * To allowed " in javascript dialog box without bad surprises + * replace " with two ' + * @param string $text + * @return mixed + */ + public function protectJSDialogQuote($text) { - $res = $in_txt; + $res = $text; $res = str_replace("'", "\'", $res); - $res = str_replace('"', "\'\'", $res); // super astuce pour afficher les " dans les boite de dialogue + // super astuce pour afficher les " dans les boite de dialogue + $res = str_replace('"', "\'\'", $res); return $res; } } diff --git a/main/exercise/UniqueAnswerImage.php b/main/exercise/UniqueAnswerImage.php index 87b291d854..2c1b541a96 100644 --- a/main/exercise/UniqueAnswerImage.php +++ b/main/exercise/UniqueAnswerImage.php @@ -367,4 +367,28 @@ class UniqueAnswerImage extends UniqueAnswer $this->updateWeighting($questionWeighting); $this->save($exercise); } + + /** + * @param Exercise $exercise + * @param null $counter + * @param null $score + * @return string + */ + public function return_header($exercise, $counter = null, $score = null) + { + if ($exercise->showExpectedChoice()) { + $header = ' + + + + '; + $header .= ''; + $header .= ''; + $header .= ''; + } else { + $header = parent::return_header($exercise, $counter, $score); + } + + return $header; + } } diff --git a/main/exercise/admin.php b/main/exercise/admin.php index a438559f49..55fbd8c828 100755 --- a/main/exercise/admin.php +++ b/main/exercise/admin.php @@ -24,7 +24,6 @@ use ChamiloSession as Session; * - $objExercise : exercise object * - $objQuestion : question object * - $objAnswer : answer object - * - $aType : array with answer types * - $exerciseId : the exercise ID * - $picturePath : the path of question pictures * - $newQuestion : ask to create a new question @@ -135,17 +134,7 @@ $picturePath = $documentPath.'/images'; // audio path $audioPath = $documentPath.'/audio'; -// the 5 types of answers -$aType = [ - get_lang('UniqueSelect'), - get_lang('MultipleSelect'), - get_lang('FillBlanks'), - get_lang('Matching'), - get_lang('FreeAnswer') -]; - // tables used in the exercise tool - if (!empty($_GET['action']) && $_GET['action'] == 'exportqti2' && !empty($_GET['questionId'])) { require_once 'export/qti2/qti2_export.php'; $export = export_question_qti($_GET['questionId'], true); @@ -264,7 +253,7 @@ if (!empty($clone_question) && !empty($objExercise->id)) { $new_answer_obj->read(); $new_answer_obj->duplicate($new_question_obj); - //Reloading tne $objExercise obj + // Reloading tne $objExercise obj $objExercise->read($objExercise->id); header('Location: admin.php?'.api_get_cidreq().'&exerciseId='.$objExercise->id); @@ -317,25 +306,6 @@ if ($modifyIn == 'thisExercise') { $modifyIn = 'allExercises'; } } -$htmlHeadXtra[] = ''; - $htmlHeadXtra[] = api_get_js('jqueryui-touch-punch/jquery.ui.touch-punch.min.js'); $htmlHeadXtra[] = api_get_js('jquery.jsPlumb.all.js'); @@ -391,11 +361,9 @@ if ($inATest) { } echo ''; - if ($objExercise->added_in_lp()) { echo Display::return_message(get_lang('AddedToLPCannotBeAccessed'), 'warning'); } - echo '
'; echo sprintf( get_lang('XQuestionsWithTotalScoreY'), @@ -404,8 +372,7 @@ if ($inATest) { ); if ($objExercise->random > 0) { - echo '
'. - sprintf(get_lang('OnlyXQuestionsPickedRandomly'), $objExercise->random); + echo '
'.sprintf(get_lang('OnlyXQuestionsPickedRandomly'), $objExercise->random); } echo '
'; } elseif (isset($_GET['newQuestion'])) { diff --git a/main/exercise/answer.class.php b/main/exercise/answer.class.php index 1f73e06edb..e9667e5b05 100755 --- a/main/exercise/answer.class.php +++ b/main/exercise/answer.class.php @@ -647,10 +647,8 @@ class Answer $hotspot_coordinates = isset($this->new_hotspot_coordinates[$i]) ? $this->new_hotspot_coordinates[$i] : ''; $hotspot_type = isset($this->new_hotspot_type[$i]) ? $this->new_hotspot_type[$i] : ''; $destination = isset($this->new_destination[$i]) ? $this->new_destination[$i] : ''; - $autoId = $this->selectAutoId($i); $iid = isset($this->iid[$i]) ? $this->iid[$i] : 0; - $questionType = $this->getQuestionType(); if (!isset($this->position[$i])) { $quizAnswer = new CQuizAnswer(); @@ -672,7 +670,6 @@ class Answer $iid = $quizAnswer->getIid(); - if ($iid) { $quizAnswer ->setId($iid) @@ -681,7 +678,12 @@ class Answer $em->merge($quizAnswer); $em->flush(); - if (in_array($questionType, [MATCHING, MATCHING_DRAGGABLE])) { + $questionType = $this->getQuestionType(); + + if (in_array( + $questionType, + [MATCHING, MATCHING_DRAGGABLE] + )) { $answer = new Answer($this->questionId); $answer->read(); $correctAnswerId = $answer->selectAnswerIdByPosition($correct); diff --git a/main/exercise/calculated_answer.class.php b/main/exercise/calculated_answer.class.php index d4d8ac927b..c63abfc1c5 100644 --- a/main/exercise/calculated_answer.class.php +++ b/main/exercise/calculated_answer.class.php @@ -250,10 +250,15 @@ class CalculatedAnswer extends Question public function return_header($exercise, $counter = null, $score = null) { $header = parent::return_header($exercise, $counter, $score); - $header .= '
'.get_lang('Choice').''.get_lang('ExpectedChoice').''.get_lang('Answer').''.get_lang('Status').''.get_lang('Comment').'
- - - '; + $header .= '
'.get_lang("Answer").'
'; + $header .= ''; + if ($exercise->showExpectedChoice()) { + $header .= ''; + $header .= ''; + $header .= ''; + } + $header .= ''; + return $header; } diff --git a/main/exercise/evalmathnotation.php b/main/exercise/evalmathnotation.php index b5f39732b8..ffea807957 100644 --- a/main/exercise/evalmathnotation.php +++ b/main/exercise/evalmathnotation.php @@ -1,5 +1,6 @@ ". diff --git a/main/exercise/exercise.class.php b/main/exercise/exercise.class.php index 7bdc5ffb9d..a7f4ada23b 100755 --- a/main/exercise/exercise.class.php +++ b/main/exercise/exercise.class.php @@ -462,6 +462,7 @@ class Exercise */ public function updateRandomByCat($random) { + $this->randomByCat = EXERCISE_CATEGORY_RANDOM_DISABLED; if (in_array( $random, [ @@ -471,8 +472,6 @@ class Exercise ] )) { $this->randomByCat = $random; - } else { - $this->randomByCat = EXERCISE_CATEGORY_RANDOM_DISABLED; } } @@ -495,11 +494,11 @@ class Exercise */ public function isRandom() { + $isRandom = false; if ($this->random > 0 || $this->random == -1) { - return true; - } else { - return false; + $isRandom = true; } + return $isRandom; } /** @@ -792,7 +791,6 @@ class Exercise e.c_id = {$this->course_id} AND e.exercice_id = '".$this->id."' ORDER BY question_order"; - $result = Database::query($sql); // Fills the array with the question ID for this exercise @@ -1065,6 +1063,7 @@ class Exercise // Adding category info in the category list with question list: if (!empty($questions_by_category)) { $newCategoryList = []; + $em = Database::getManager(); foreach ($questions_by_category as $categoryId => $questionList) { $cat = new TestCategory(); $cat = $cat->getCategory($categoryId); @@ -1239,11 +1238,11 @@ class Exercise */ public function isInList($questionId) { + $inList = false; if (is_array($this->questionList)) { - return in_array($questionId, $this->questionList); - } else { - return false; + $inList = in_array($questionId, $this->questionList); } + return $inList; } /** @@ -1483,9 +1482,6 @@ class Exercise */ public function setRandom($random) { - /*if ($random == 'all') { - $random = $this->selectNbrQuestions(); - }*/ $this->random = $random; } @@ -1573,28 +1569,24 @@ class Exercise $pass_percentage = intval($this->pass_percentage); $session_id = $this->sessionId; - //If direct we do not show results + // If direct we do not show results + $results_disabled = intval($this->results_disabled); if ($feedback_type == EXERCISE_FEEDBACK_TYPE_DIRECT) { $results_disabled = 0; - } else { - $results_disabled = intval($this->results_disabled); } - $expired_time = intval($this->expired_time); // Exercise already exists if ($id) { // we prepare date in the database using the api_get_utc_datetime() function + $start_time = null; if (!empty($this->start_time)) { $start_time = $this->start_time; - } else { - $start_time = null; } + $end_time = null; if (!empty($this->end_time)) { $end_time = $this->end_time; - } else { - $end_time = null; } $params = [ @@ -1662,22 +1654,19 @@ class Exercise } } else { // Creates a new exercise - // In this case of new exercise, we don't do the api_get_utc_datetime() // for date because, bellow, we call function api_set_default_visibility() // In this function, api_set_default_visibility, // the Quiz is saved too, with an $id and api_get_utc_datetime() is done. // If we do it now, it will be done twice (cf. https://support.chamilo.org/issues/6586) + $start_time = null; if (!empty($this->start_time)) { $start_time = $this->start_time; - } else { - $start_time = null; } + $end_time = null; if (!empty($this->end_time)) { $end_time = $this->end_time; - } else { - $end_time = null; } $params = [ @@ -1956,7 +1945,8 @@ class Exercise ); if (api_get_setting('enable_quiz_scenario') == 'true') { - //Can't convert a question from one feedback to another if there is more than 1 question already added + // Can't convert a question from one feedback to another + // if there is more than 1 question already added if ($this->selectNbrQuestions() == 0) { $radios_feedback[] = $form->createElement( 'radio', @@ -2133,7 +2123,7 @@ class Exercise ); $form->addGroup($radios, null, get_lang('ExerciseType')); } else { - //Show options freeze + // Show options freeze $radios_results_disabled[] = $form->createElement( 'radio', 'results_disabled', @@ -2165,7 +2155,7 @@ class Exercise ); $result_disable_group->freeze(); - //we force the options to the DirectFeedback exercisetype + // we force the options to the DirectFeedback exercisetype $form->addElement('hidden', 'exerciseFeedbackType', EXERCISE_FEEDBACK_TYPE_DIRECT); $form->addElement('hidden', 'exerciseType', ONE_PER_PAGE); @@ -2471,7 +2461,6 @@ class Exercise $defaults = []; if (api_get_setting('search_enabled') === 'true') { require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php'; - $form->addElement('checkbox', 'index_document', '', get_lang('SearchFeatureDoIndexDocument')); $form->addSelectLanguage('language', get_lang('SearchFeatureDocumentLanguage')); $specific_fields = get_specific_field_list(); @@ -2972,10 +2961,10 @@ class Exercise /** * Copies an exercise (duplicate all questions and answers) */ - public function copy_exercise() + public function copyExercise() { $exerciseObject = $this; - $categories = $exerciseObject->get_categories_in_exercise(); + $categories = $exerciseObject->getCategoriesInExercise(); // Get all questions no matter the order/category settings $questionList = $exerciseObject->getQuestionOrderedList(); // Force the creation of a new exercise @@ -3398,7 +3387,6 @@ class Exercise "; } - /** * This function was originally found in the exercise_show.php * @param int $exeId @@ -4114,6 +4102,10 @@ class Exercise } $answer = ''; $realCorrectTags = $correctTags; + $calculatedStatus = Display::label(get_lang('Incorrect'), 'danger'); + $expectedAnswer = ''; + $calculatedChoice = ''; + for ($i = 0; $i < count($realCorrectTags); $i++) { if ($i == 0) { $answer .= $realText[0]; @@ -4127,11 +4119,13 @@ class Exercise $totalScore += $answerWeighting[$i]; // adds the word in green at the end of the string $answer .= $correctTags[$i]; + $calculatedChoice = $correctTags[$i]; } elseif (!empty($userTags[$i])) { // else if the word entered by the student IS NOT the same as // the one defined by the professor // adds the word in red at the end of the string, and strikes it - $answer .= ''.$userTags[$i].''; + $answer .= '' . $userTags[$i] . ''; + $calculatedChoice = $userTags[$i]; } else { // adds a tabulation if no word has been typed by the student $answer .= ''; // remove   that causes issue @@ -4140,8 +4134,9 @@ class Exercise if ($this->results_disabled != EXERCISE_FEEDBACK_TYPE_EXAM) { $answer .= ' / '.$realCorrectTags[$i].''; + $calculatedStatus = Display::label(get_lang('Correct'), 'success'); + $expectedAnswer = $realCorrectTags[$i]; } - $answer .= ']'; if (isset($realText[$i + 1])) { @@ -4213,7 +4208,9 @@ class Exercise } break; case DRAGGABLE: + //no break case MATCHING_DRAGGABLE: + //no break case MATCHING: if ($from_database) { $sql = "SELECT id, answer, id_auto @@ -4238,10 +4235,14 @@ class Exercise correct <> 0 ORDER BY id_auto"; $res_answers = Database::query($sql); + $options = []; + while ($a_answers = Database::fetch_array($res_answers)) { + $options[] = $a_answers; + } $questionScore = 0; - - while ($a_answers = Database::fetch_array($res_answers)) { + $counterAnswer = 1; + foreach ($options as $a_answers) { $i_answer_id = $a_answers['id']; //3 $s_answer_label = $a_answers['answer']; // your daddy - your mother $i_answer_correct_answer = $a_answers['correct']; //1 - 2 @@ -4265,19 +4266,30 @@ class Exercise $i_answerWeighting = $a_answers['ponderation']; $user_answer = ''; + $status = Display::label(get_lang('Incorrect'), 'danger'); + if (!empty($s_user_answer)) { if ($answerType == DRAGGABLE) { if ($s_user_answer == $i_answer_correct_answer) { $questionScore += $i_answerWeighting; $totalScore += $i_answerWeighting; $user_answer = Display::label(get_lang('Correct'), 'success'); + if ($this->showExpectedChoice()) { + $user_answer = $answerMatching[$i_answer_id_auto]; + } + $status = Display::label(get_lang('Correct'), 'success'); } else { $user_answer = Display::label(get_lang('Incorrect'), 'danger'); + if ($this->showExpectedChoice()) { + $data = $options[$real_list[$s_user_answer] - 1]; + $user_answer = $data['answer']; + } } } else { if ($s_user_answer == $i_answer_correct_answer) { $questionScore += $i_answerWeighting; $totalScore += $i_answerWeighting; + $status = Display::label(get_lang('Correct'), 'success'); // Try with id if (isset($real_list[$i_answer_id])) { @@ -4297,10 +4309,18 @@ class Exercise $real_list[$s_user_answer], ['style' => 'color: #FF0000; text-decoration: line-through;'] ); + if ($this->showExpectedChoice()) { + $user_answer = Display::span( + $real_list[$s_user_answer] + ); + } } } } elseif ($answerType == DRAGGABLE) { $user_answer = Display::label(get_lang('Incorrect'), 'danger'); + if ($this->showExpectedChoice()) { + $user_answer = ''; + } } else { $user_answer = Display::span( get_lang('Incorrect').'  ', @@ -4312,23 +4332,73 @@ class Exercise if ($showTotalScoreAndUserChoicesInLastAttempt === false) { $user_answer = ''; } - echo ''; - echo ''; - echo ''; + if ($this->showExpectedChoice()) { + echo ''; + echo ''; + echo ''; + echo ''; + } else { + echo ''; + echo ''; + echo ''; + } + echo ''; + break; + case DRAGGABLE: + if ($showTotalScoreAndUserChoicesInLastAttempt == false) { + $s_answer_label = ''; + } + echo ''; + if ($this->showExpectedChoice()) { + echo ''; + echo ''; + echo ''; + } else { + echo ''; + echo ''; + echo ''; + } + echo ''; + break; } - echo ''; - echo ''; } + $counterAnswer++; } break(2); // break the switch and the "for" condition } else { @@ -4565,6 +4635,7 @@ class Exercise ] )) { ExerciseShowFunctions::display_unique_or_multiple_answer( + $this, $feedback_type, $answerType, $studentChoice, @@ -4580,6 +4651,7 @@ class Exercise ); } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) { ExerciseShowFunctions::display_multiple_answer_true_false( + $this, $feedback_type, $answerType, $studentChoice, @@ -4594,6 +4666,7 @@ class Exercise ); } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { ExerciseShowFunctions::display_multiple_answer_combination_true_false( + $this, $feedback_type, $answerType, $studentChoice, @@ -4618,12 +4691,16 @@ class Exercise ); } elseif ($answerType == CALCULATED_ANSWER) { ExerciseShowFunctions::display_calculated_answer( + $this, $feedback_type, $answer, 0, 0, $results_disabled, - $showTotalScoreAndUserChoicesInLastAttempt + $showTotalScoreAndUserChoicesInLastAttempt, + $expectedAnswer, + $calculatedChoice, + $calculatedStatus ); } elseif ($answerType == FREE_ANSWER) { ExerciseShowFunctions::display_free_answer( @@ -4657,6 +4734,9 @@ class Exercise } } + // force to show whether the choice is correct or not + $showTotalScoreAndUserChoicesInLastAttempt = true; + ExerciseShowFunctions::display_hotspot_answer( $feedback_type, ++$correctAnswerId, @@ -4781,7 +4861,7 @@ class Exercise $result_comment = get_lang('Unacceptable'); $comment = $answerDestination = $objAnswerTmp->selectComment(1); $answerDestination = $objAnswerTmp->selectDestination(1); - //checking the destination parameters parsing the "@@" + // checking the destination parameters parsing the "@@" $destination_items = explode('@@', $answerDestination); } } elseif ($answerId > 1) { @@ -4796,10 +4876,6 @@ class Exercise if ($debug > 0) { error_log(__LINE__.' - answerId is >1 so we\'re probably in OAR', 0); } - //check the intersection between the oar and the user - //echo 'user'; print_r($x_user_list); print_r($y_user_list); - //echo 'official';print_r($x_list);print_r($y_list); - //$result = get_intersection_data($x_list,$y_list,$x_user_list,$y_user_list); $inter = $result['success']; $delineation_cord = $objAnswerTmp->selectHotspotCoordinates($answerId); $poly_answer = convert_coordinates($delineation_cord, '|'); @@ -4863,14 +4939,21 @@ class Exercise switch ($answerType) { case UNIQUE_ANSWER: + //no break case UNIQUE_ANSWER_IMAGE: + //no break case UNIQUE_ANSWER_NO_OPTION: + //no break case MULTIPLE_ANSWER: + //no break case GLOBAL_MULTIPLE_ANSWER: + //no break case MULTIPLE_ANSWER_COMBINATION: + //no break case READING_COMPREHENSION: if ($answerId == 1) { ExerciseShowFunctions::display_unique_or_multiple_answer( + $this, $feedback_type, $answerType, $studentChoice, @@ -4886,6 +4969,7 @@ class Exercise ); } else { ExerciseShowFunctions::display_unique_or_multiple_answer( + $this, $feedback_type, $answerType, $studentChoice, @@ -4904,6 +4988,7 @@ class Exercise case MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE: if ($answerId == 1) { ExerciseShowFunctions::display_multiple_answer_combination_true_false( + $this, $feedback_type, $answerType, $studentChoice, @@ -4918,6 +5003,7 @@ class Exercise ); } else { ExerciseShowFunctions::display_multiple_answer_combination_true_false( + $this, $feedback_type, $answerType, $studentChoice, @@ -4935,6 +5021,7 @@ class Exercise case MULTIPLE_ANSWER_TRUE_FALSE: if ($answerId == 1) { ExerciseShowFunctions::display_multiple_answer_true_false( + $this, $feedback_type, $answerType, $studentChoice, @@ -4949,6 +5036,7 @@ class Exercise ); } else { ExerciseShowFunctions::display_multiple_answer_true_false( + $this, $feedback_type, $answerType, $studentChoice, @@ -4976,6 +5064,7 @@ class Exercise break; case CALCULATED_ANSWER: ExerciseShowFunctions::display_calculated_answer( + $this, $feedback_type, $answer, $exeId, @@ -5186,7 +5275,9 @@ class Exercise ); break; case DRAGGABLE: + //no break case MATCHING_DRAGGABLE: + //no break case MATCHING: echo ''; echo Display::tag('td', $answerMatching[$answerId]); @@ -6947,7 +7038,7 @@ class Exercise * Get categories added in the exercise--category matrix * @return array */ - public function get_categories_in_exercise() + public function getCategoriesInExercise() { $table = Database::get_course_table(TABLE_QUIZ_REL_CATEGORY); if (!empty($this->id)) { @@ -7695,7 +7786,6 @@ class Exercise } $sessionId = intval($sessionId); - $ids = is_array($quizId) ? $quizId : [$quizId]; $ids = array_map('intval', $ids); $ids = implode(',', $ids); @@ -7867,7 +7957,9 @@ class Exercise $isCorrect = FillBlanks::isCorrect($answer['answer']); break; case MATCHING: + //no break case DRAGGABLE: + //no break case MATCHING_DRAGGABLE: $isCorrect = Matching::isCorrect( $answer['position'], @@ -7940,4 +8032,62 @@ class Exercise { return $this->notifications; } + + /** + * @return bool + */ + public function showExpectedChoice() + { + return api_get_configuration_value('show_exercise_expected_choice'); + } + + /** + * @param string $class + * @param string $scoreLabel + * @param string $result + * @param array + * + * @return string + */ + public function getQuestionRibbon($class, $scoreLabel, $result, $array) + { + if ($this->showExpectedChoice()) { + $html = null; + $hideLabel = api_get_configuration_value('exercise_hide_label'); + $label = '
+

'.$scoreLabel.'

+
+

'.get_lang('Score').': '.$result.'

'; + if ($hideLabel === true) { + $answerUsed = (int) $array['used']; + $answerMissing = (int) $array['missing'] - $answerUsed; + for ($i = 1; $i <= $answerUsed; $i++) { + $html.= ''. + Display::return_icon('attempt-check.png', null, null, ICON_SIZE_SMALL). + ''; + } + for ($i = 1; $i <= $answerMissing; $i++) { + $html.= ''. + Display::return_icon('attempt-nocheck.png', null, null, ICON_SIZE_SMALL). + ''; + } + $label = '
'.get_lang('CorrectAnswers').': '.$result.'
'; + $label .= '
'; + $label .= $html; + $label .= '
'; + } + return '
+ '.$label.' +
' + ; + } else { + return '
+
+

'.$scoreLabel.'

+
+

'.get_lang('Score').': '.$result.'

+
' + ; + } + } } diff --git a/main/exercise/exercise.php b/main/exercise/exercise.php index b0170ed739..45259d659b 100644 --- a/main/exercise/exercise.php +++ b/main/exercise/exercise.php @@ -296,7 +296,7 @@ if ($is_allowedToEdit) { } break; case 'copy_exercise': //copy an exercise - $objExerciseTmp->copy_exercise(); + $objExerciseTmp->copyExercise(); echo Display::return_message( get_lang('ExerciseCopied'), 'confirmation' diff --git a/main/exercise/exercise_show.php b/main/exercise/exercise_show.php index f1ab3e21f1..db86575d90 100755 --- a/main/exercise/exercise_show.php +++ b/main/exercise/exercise_show.php @@ -396,20 +396,35 @@ foreach ($questionList as $questionId) { $relPath = api_get_path(WEB_CODE_PATH); switch ($answerType) { case MULTIPLE_ANSWER_COMBINATION: + //no break case MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE: + //no break case UNIQUE_ANSWER: + //no break; case UNIQUE_ANSWER_NO_OPTION: + //no break case UNIQUE_ANSWER_IMAGE: + //no break case MULTIPLE_ANSWER: + //no break case MULTIPLE_ANSWER_TRUE_FALSE: + //no break case FILL_IN_BLANKS: + //no break case CALCULATED_ANSWER: + //no break case GLOBAL_MULTIPLE_ANSWER: + //no break case FREE_ANSWER: + //no break case ORAL_EXPRESSION: + //no break case MATCHING: + //no break case DRAGGABLE: + //no break case READING_COMPREHENSION: + //no break case MATCHING_DRAGGABLE: $question_result = $objExercise->manage_answer( $id, diff --git a/main/exercise/exercise_submit.php b/main/exercise/exercise_submit.php index d1ea8786a7..5ebef2edf4 100755 --- a/main/exercise/exercise_submit.php +++ b/main/exercise/exercise_submit.php @@ -1369,10 +1369,13 @@ if (!empty($error)) { false, $origin, $i, - true, + $objExercise->getHideQuestionTitle() ? false : true, false, $user_choice, - false + false, + null, + false, + true ); // Button save and continue diff --git a/main/exercise/exercise_submit_modal.php b/main/exercise/exercise_submit_modal.php index 6e71c26758..fcaa1e5874 100755 --- a/main/exercise/exercise_submit_modal.php +++ b/main/exercise/exercise_submit_modal.php @@ -223,9 +223,7 @@ if (!empty($choice_value)) { break; } - if ($answerType == UNIQUE_ANSWER || $answerType == MULTIPLE_ANSWER) { - //display_unique_or_multiple_answer($answerType, $studentChoice, $answer, $answerComment, $answerCorrect); if ($studentChoice) { $destination = $answerDestination; $comment = $answerComment; diff --git a/main/exercise/export/qti2/qti2_classes.php b/main/exercise/export/qti2/qti2_classes.php index e02285474b..dff84e9749 100755 --- a/main/exercise/export/qti2/qti2_classes.php +++ b/main/exercise/export/qti2/qti2_classes.php @@ -33,6 +33,7 @@ class Ims2Question extends Question return $answer; case MATCHING: + //no break case MATCHING_DRAGGABLE: $answer = new ImsAnswerMatching($this->id); diff --git a/main/exercise/fill_blanks.class.php b/main/exercise/fill_blanks.class.php index 0a9d5d5d7b..fcd0a9f45c 100755 --- a/main/exercise/fill_blanks.class.php +++ b/main/exercise/fill_blanks.class.php @@ -537,8 +537,6 @@ class FillBlanks extends Question $resultOptions[sha1($item)] = $item; } - //var_dump($resultOptions, $correctItem); - foreach ($resultOptions as $key => $value) { if ($correctItem == $value) { $selected = $key; @@ -556,6 +554,7 @@ class FillBlanks extends Question ); break; case self::FILL_THE_BLANK_SEVERAL_ANSWER: + //no break case self::FILL_THE_BLANK_STANDARD: default: $attributes['id'] = 'choice_id_'.$currentQuestion.'_'.$inBlankNumber; @@ -1232,26 +1231,28 @@ class FillBlanks extends Question $showTotalScoreAndUserChoices = false ) { $hideExpectedAnswer = false; - if ($feedbackType == 0 && ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ONLY)) { + if ($feedbackType == 0 && $resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ONLY) { $hideExpectedAnswer = true; } if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) { + $hideExpectedAnswer = true; if ($showTotalScoreAndUserChoices) { $hideExpectedAnswer = false; - } else { - $hideExpectedAnswer = true; } } - $style = "color: green"; + $style = 'feedback-green'; + $iconAnswer = Display::return_icon('attempt-check.png', get_lang('Correct'), null, ICON_SIZE_SMALL); if (!$right) { - $style = "color: red; text-decoration: line-through;"; + $style = 'feedback-red'; + $iconAnswer = Display::return_icon('attempt-nocheck.png', get_lang('Incorrect'), null, ICON_SIZE_SMALL); } + + $correctAnswerHtml = ''; $type = self::getFillTheBlankAnswerType($correct); switch ($type) { case self::FILL_THE_BLANK_MENU: - $correctAnswerHtml = ''; $listPossibleAnswers = self::getFillTheBlankMenuAnswers($correct, false); $correctAnswerHtml .= "".$listPossibleAnswers[0].""; $correctAnswerHtml .= " ("; @@ -1269,20 +1270,21 @@ class FillBlanks extends Question if (count($listCorrects) > 0) { $firstCorrect = $listCorrects[0]; } - $correctAnswerHtml = "".$firstCorrect.""; + $correctAnswerHtml = ""; break; case self::FILL_THE_BLANK_STANDARD: + // no break default: - $correctAnswerHtml = "".$correct.""; + $correctAnswerHtml = ""; } if ($hideExpectedAnswer) { - $correctAnswerHtml = " - "; + $correctAnswerHtml = ""; } - $result = ""; - $result .= "".$answer.""; - $result .= " / "; + $result = ""; diff --git a/main/exercise/global_multiple_answer.class.php b/main/exercise/global_multiple_answer.class.php index de94b9804d..c1a84a9d69 100755 --- a/main/exercise/global_multiple_answer.class.php +++ b/main/exercise/global_multiple_answer.class.php @@ -265,12 +265,15 @@ class GlobalMultipleAnswer extends Question $score = null ) { $header = parent::return_header($exercise, $counter, $score); - $header .= '
'.get_lang('Answer').''.get_lang('YourChoice').''.get_lang('ExpectedChoice').''.get_lang('Status').'
'.$s_answer_label.''.$user_answer; - - if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) { - if (isset($real_list[$i_answer_correct_answer]) && - $showTotalScoreAndUserChoicesInLastAttempt === true - ) { - echo Display::span( - $real_list[$i_answer_correct_answer], - ['style' => 'color: #008000; font-weight: bold;'] - ); - } + switch ($answerType) { + case MATCHING: + case MATCHING_DRAGGABLE: + echo '
'.$s_answer_label.''.$user_answer.''; + if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) { + if (isset($real_list[$i_answer_correct_answer]) && + $showTotalScoreAndUserChoicesInLastAttempt == true + ) { + echo Display::span( + $real_list[$i_answer_correct_answer] + ); + } + } + echo ''.$status.''.$s_answer_label.''.$user_answer.''; + if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) { + if (isset($real_list[$i_answer_correct_answer]) && + $showTotalScoreAndUserChoicesInLastAttempt === true + ) { + echo Display::span( + $real_list[$i_answer_correct_answer], + ['style' => 'color: #008000; font-weight: bold;'] + ); + } + } + echo '
'.$user_answer.''.$s_answer_label.''.$status.''.$s_answer_label.''.$user_answer.''; + if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) { + if (isset($real_list[$i_answer_correct_answer]) && + $showTotalScoreAndUserChoicesInLastAttempt === true + ) { + echo Display::span( + $real_list[$i_answer_correct_answer], + ['style' => 'color: #008000; font-weight: bold;'] + ); + } + } + echo '
- - - - '; - $header .= ''; + $header .= '
' . get_lang("Choice").'' . get_lang("ExpectedChoice").'' . get_lang("Answer").''.get_lang("Comment").'
'; + + $header .= ''; + $header .= ''; + $header .= ''; + if ($exercise->showExpectedChoice()) { + $header .= ''; + } + $header .= ''; $header .= ''; return $header; diff --git a/main/exercise/hotspot.class.php b/main/exercise/hotspot.class.php index 796346dd11..525cde6a90 100755 --- a/main/exercise/hotspot.class.php +++ b/main/exercise/hotspot.class.php @@ -67,7 +67,7 @@ class HotSpot extends Question } else { // setting the save button here and not in the question class.php // Editing a question - $form->addButtonUpdate(get_lang('ModifyExercise'), 'submitQuestion'); + $form->addButtonUpdate(get_lang('ModifyQuestion'), 'submitQuestion'); } } diff --git a/main/exercise/matching.class.php b/main/exercise/matching.class.php index c997146750..ae4a5d522c 100755 --- a/main/exercise/matching.class.php +++ b/main/exercise/matching.class.php @@ -283,10 +283,16 @@ class Matching extends Question { $header = parent::return_header($exercise, $counter, $score); $header .= '
'.get_lang('Choice').''.get_lang('ExpectedChoice').''.get_lang('Answer').''.get_lang('Status').''.get_lang('Comment').'
'; - $header .= ' - - - '; + $header .= ''; + $header .= ''; + if ($exercise->showExpectedChoice()) { + $header .= ''; + $header .= ''; + $header .= ''; + } else { + $header .= ''; + } + $header .= ''; return $header; } diff --git a/main/exercise/multiple_answer.class.php b/main/exercise/multiple_answer.class.php index b52357103f..fe5cd3c426 100755 --- a/main/exercise/multiple_answer.class.php +++ b/main/exercise/multiple_answer.class.php @@ -228,12 +228,14 @@ class MultipleAnswer extends Question public function return_header($exercise, $counter = null, $score = null) { $header = parent::return_header($exercise, $counter, $score); - $header .= '
'.get_lang('ElementList').''.get_lang('CorrespondsTo').'
'.get_lang('ElementList').''.get_lang('YourChoice').''.get_lang('ExpectedChoice').''.get_lang('Status').''.get_lang('CorrespondsTo').'
- - - - '; - $header .= ''; + $header .= '
'.get_lang("Choice").''. get_lang("ExpectedChoice").''. get_lang("Answer").''.get_lang("Comment").'
'; + $header .= ''; + $header .= ''; + $header .= ''; + if ($exercise->showExpectedChoice()) { + $header .= ''; + } + $header .= ''; $header .= ''; return $header; } diff --git a/main/exercise/multiple_answer_combination.class.php b/main/exercise/multiple_answer_combination.class.php index 172adf8764..ef8633dc02 100755 --- a/main/exercise/multiple_answer_combination.class.php +++ b/main/exercise/multiple_answer_combination.class.php @@ -227,12 +227,14 @@ class MultipleAnswerCombination extends Question public function return_header($exercise, $counter = null, $score = null) { $header = parent::return_header($exercise, $counter, $score); - $header .= '
'.get_lang('Choice').''.get_lang('ExpectedChoice').''.get_lang('Answer').''.get_lang('Status').''.get_lang('Comment').'
- - - - '; - $header .= ''; + $header .= '
'.get_lang("Choice").''. get_lang("ExpectedChoice").''. get_lang("Answer").''.get_lang("Comment").'
+ + + '; + if ($exercise->showExpectedChoice()) { + $header .= ''; + } + $header .= ''; $header .= ''; return $header; diff --git a/main/exercise/multiple_answer_true_false.class.php b/main/exercise/multiple_answer_true_false.class.php index 2f329a0cd0..8c95e7d970 100755 --- a/main/exercise/multiple_answer_true_false.class.php +++ b/main/exercise/multiple_answer_true_false.class.php @@ -267,11 +267,10 @@ class MultipleAnswerTrueFalse extends Question /* Getting quiz_question_options (true, false, doubt) because it's possible that there are more options in the future */ - $new_options = Question::readQuestionOption($this->id, $course_id); - $sorted_by_position = []; + $sortedByPosition = []; foreach ($new_options as $item) { - $sorted_by_position[$item['position']] = $item; + $sortedByPosition[$item['position']] = $item; } /* Saving quiz_question.extra values that has the correct scores of @@ -291,7 +290,7 @@ class MultipleAnswerTrueFalse extends Question if (empty($options)) { //If this is the first time that the question is created when // change the default values from the form 1 and 2 by the correct "option id" registered - $goodAnswer = $sorted_by_position[$goodAnswer]['id']; + $goodAnswer = isset($sortedByPosition[$goodAnswer]) ? $sortedByPosition[$goodAnswer]['id'] : ''; } $questionWeighting += $extra_values[0]; //By default 0 has the correct answers $objAnswer->createAnswer($answer, $goodAnswer, $comment, '', $i); @@ -310,13 +309,15 @@ class MultipleAnswerTrueFalse extends Question public function return_header($exercise, $counter = null, $score = null) { $header = parent::return_header($exercise, $counter, $score); - $header .= '
'.get_lang('Choice').''.get_lang('ExpectedChoice').''.get_lang('Answer').''.get_lang('Status').''.get_lang('Comment').'
- - - - '; + $header .= '
'.get_lang("Choice").''. get_lang("ExpectedChoice").''. get_lang("Answer").'
'; + $header .= ' + + '; + if ($exercise->showExpectedChoice()) { + $header .= ''; + } if ($exercise->feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) { - $header .= ''; + $header .= ''; } else { $header .= ''; } diff --git a/main/exercise/overview.php b/main/exercise/overview.php index 185a18d159..e37e4ef54d 100755 --- a/main/exercise/overview.php +++ b/main/exercise/overview.php @@ -110,11 +110,6 @@ $exercise_stat_info = $objExercise->get_stat_track_exercise_info( 0 ); -/*$attempt_list = null; -if (isset($exercise_stat_info['exe_id'])) { - $attempt_list = Event::getAllExerciseEventByExeId($exercise_stat_info['exe_id']); -}*/ - //1. Check if this is a new attempt or a previous $label = get_lang('StartTest'); if ($time_control && !empty($clock_expired_time) || isset($exercise_stat_info['exe_id'])) { diff --git a/main/exercise/question.class.php b/main/exercise/question.class.php index 6fcdb7fcd1..589a4afe6b 100755 --- a/main/exercise/question.class.php +++ b/main/exercise/question.class.php @@ -1682,7 +1682,6 @@ abstract class Question $form->addGroup($buttonGroup); break; } - //Medias //$course_medias = self::prepare_course_media_select(api_get_course_int_id()); //$form->addElement('select', 'parent_id', get_lang('AttachToMedia'), $course_medias); @@ -1954,9 +1953,9 @@ abstract class Question */ public function return_header($exercise, $counter = null, $score = []) { - $counter_label = ''; + $counterLabel = ''; if (!empty($counter)) { - $counter_label = intval($counter); + $counterLabel = intval($counter); } $score_label = get_lang('Wrong'); $class = 'error'; @@ -1992,13 +1991,16 @@ abstract class Question if ($exercise->display_category_name) { $header = TestCategory::returnCategoryAndTitle($this->id); } - $show_media = null; + $show_media = ''; if ($show_media) { $header .= $this->show_media_content(); } - - $header .= Display::page_subheader2($counter_label.". ".$this->question); - $header .= ExerciseLib::getQuestionRibbon($class, $score_label, $score['result']); + $scoreCurrent = [ + 'used' => $score['score'], + 'missing' => $score['weight'] + ]; + $header .= Display::page_subheader2($counterLabel.'. '.$this->question); + $header .= $exercise->getQuestionRibbon($class, $score_label, $score['result'], $scoreCurrent); if ($this->type != READING_COMPREHENSION) { // Do not show the description (the text to read) if the question is of type READING_COMPREHENSION $header .= Display::div( @@ -2303,6 +2305,6 @@ abstract class Question */ public function returnFormatFeedback() { - return Display::return_message($this->feedback, 'normal', false); + return '
'.Display::return_message($this->feedback, 'normal', false); } } diff --git a/main/exercise/question_admin.inc.php b/main/exercise/question_admin.inc.php index dabab671fb..e31ffd4a92 100755 --- a/main/exercise/question_admin.inc.php +++ b/main/exercise/question_admin.inc.php @@ -52,9 +52,7 @@ if (is_object($objQuestion)) { // Question $objQuestion->processCreation($form, $objExercise); $objQuestion->processAnswersCreation($form, $objExercise); - // TODO: maybe here is the better place to index this tool, including answers text - // redirect if ($objQuestion->type != HOT_SPOT && $objQuestion->type != HOT_SPOT_DELINEATION diff --git a/main/exercise/question_pool.php b/main/exercise/question_pool.php index 757149c023..a1ea4183e8 100755 --- a/main/exercise/question_pool.php +++ b/main/exercise/question_pool.php @@ -48,7 +48,7 @@ if (empty($objExercise) && !empty($fromExercise)) { } $nameTools = get_lang('QuestionPool'); -$interbreadcrumb[] = ["url" => "exercise.php", "name" => get_lang('Exercises')]; +$interbreadcrumb[] = ["url" => "exercise.php?".api_get_cidreq(), "name" => get_lang('Exercises')]; if (!empty($objExercise)) { $interbreadcrumb[] = [ @@ -299,7 +299,6 @@ if (empty($selected_course) || $selected_course == '-1') { } else { $course_info = api_get_course_info_by_id($selected_course); } - // If course has changed, reset the menu default if ($course_id_changed) { reset_menu_exo_lvl_type(); diff --git a/main/exercise/stats.php b/main/exercise/stats.php index 2470741b8a..2189db2564 100755 --- a/main/exercise/stats.php +++ b/main/exercise/stats.php @@ -185,6 +185,7 @@ if (!empty($question_list)) { } break; case MATCHING: + //no break case MATCHING_DRAGGABLE: if ($is_correct == 0) { if ($answer_id == 1) { diff --git a/main/exercise/unique_answer.class.php b/main/exercise/unique_answer.class.php index cb140b4250..7dff831dc9 100755 --- a/main/exercise/unique_answer.class.php +++ b/main/exercise/unique_answer.class.php @@ -417,12 +417,14 @@ class UniqueAnswer extends Question $score = null ) { $header = parent::return_header($exercise, $counter, $score); - $header .= '
'.get_lang('Choice').''.get_lang('ExpectedChoice').''.get_lang('Answer').''.get_lang('Status').''.get_lang("Comment").''.get_lang('Comment').' 
- - - - '; - $header .= ''; + $header .= '
'.get_lang("Choice").''.get_lang("ExpectedChoice").''.get_lang("Answer").''.get_lang("Comment").'
'; + $header .= ''; + $header .= ''; + $header .= ''; + if ($exercise->showExpectedChoice()) { + $header .= ''; + } + $header .= ''; $header .= ''; return $header; diff --git a/main/exercise/unique_answer_no_option.class.php b/main/exercise/unique_answer_no_option.class.php index 28da41c9ba..5860da039f 100755 --- a/main/exercise/unique_answer_no_option.class.php +++ b/main/exercise/unique_answer_no_option.class.php @@ -23,8 +23,8 @@ class UniqueAnswerNoOption extends Question public function __construct() { parent::__construct(); - $this -> type = UNIQUE_ANSWER_NO_OPTION; - $this -> isContent = $this-> getIsContent(); + $this->type = UNIQUE_ANSWER_NO_OPTION; + $this->isContent = $this->getIsContent(); } /** @@ -409,12 +409,14 @@ class UniqueAnswerNoOption extends Question public function return_header($exercise, $counter = null, $score = null) { $header = parent::return_header($exercise, $counter, $score); - $header .= '
'.get_lang('Choice').''.get_lang('ExpectedChoice').''.get_lang('Answer').''.get_lang('Status').''.get_lang('Comment').'
- - - - '; - $header .= ''; + $header .= '
'.get_lang("Choice").''.get_lang("ExpectedChoice").''.get_lang("Answer").''.get_lang("Comment").'
'; + $header .= ''; + $header .= ''; + $header .= ''; + if ($exercise->showExpectedChoice()) { + $header .= ''; + } + $header .= ''; $header .= ''; return $header; diff --git a/main/img/icons/22/attempt-check.png b/main/img/icons/22/attempt-check.png new file mode 100644 index 0000000000000000000000000000000000000000..2c328db047af930c29840fdc933196d3ce772f10 GIT binary patch literal 1114 zcmV-g1f~0lP)n+a8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H11J_AJK~y-6jg(DHTvZgufA_tC83q{WP)dP;;-Z4ZQfZLbiV~?! z+619)SoDJhrY`(SLyTI3$t=_+jj18ACSoL3+l5UN`Dm;zplFLIZBrWB5)dO$7+NUI z3^2?LZ{A!NFb|QT^sL^y@BDxF|IWSV2-XNkzSAC*$^iit2$6@x0f1l>NuPw41=ZB# z?LF>}rWdP#j#F`3qOVp8-UDoFZM>xR3Mo#;%ve7k9j*1R3Er6N%n+*DB;Z+q)RcJk zmF2RlD4UGUi+i~4&(L*!giCGxJe>ALq&+5~SGw*vM^=ID1x|-aSN}kgX|b4i_l*}h zdZ-wS#T3c$MP!*MEZ!REUP?A)|5f$vXO@yyd1 zkE}u@ZuYu3^5zdrPWcd$>v4Ylg`pv5Kn1X5l^h2Sn$0H8e|?a`?aR=x)EIKNGceiA zn70c}pCie#1tAmw($f-ozBq>qt+&ziaK=Kc>YJZzzbYL0PWysX{{d`uwPn2h+HM1S z&vS*=z8c*A!4)p;)~%H1HIkKFVyx9Sbno!v0<%JkwU%#uzydkaZq8Y(b`vo9uBTqTRj}4 zwXcS-3;_^liD6$^E&u{56j1U3b`@nCqG5MORHv(*4>02S)p*}+FvKm)iOX1Qt(N5hlv> z8c`MVnow0SQ~p#Videi!{(#0Wmj{-<%4WqZ^kxL!htob9&UPEZtmG077q(%yJ{i^N z;lg$tNz2Xj)tNt;nw|&nESSSB0w8VM#~(`MCuXyWrf-k1vmnzDgk^|fcLx)`UI5Y( z3dl|_HJk$6x-(8i^_j&#mg4=1zPghFAScIZ@yDrGq@XA@C7$oTs9FJkRNS~VM)h0g zBO|oiIw=KY%O!o}MtieN{6Ix!|SD$pO$IQ>l*$3D8q>|78D z_oS}xb^YyhLzF?UsOpbEF+hsl%KrZi`mymDx^9f{b9;ZJrT{lhLO&37&_^OC$7%7! zn~n+O2S}3Ese}h9PS`YC{ovp`D+bFda3qqppV$x^)+&V*l>(V35spQH9F>ATiPEga ggql4)PER!bzk~LF|Gn+a8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10}e?t>00WL?SjjUVW0y8=Htk z?2?Dg=RNlA@8R8#ex^|H08+jukBwZ|HFR5?NVG>MW7(s?sznRu^ZA|)Jn~@OtW^l; zJDujG*S_M~NET6gqdEVHfdMCP04A%lJAhT;u+3*5mM;Z(bY&f1eEb5@NC*`gvz2xm zfR$));=Y;#KzQf2r%AT1C|ep(yJ!I-!Y{`L5Mi}l`|Muh7Om%jSWR^$n>RMywKU-6 zO-)qCD?q85S9Fs`MV|v$+fqN{MU_J|5~6iYJpcmh444Lh=EkLSmIge2+aW6qXf43v z`)B_Pb!%r7(jkLpr#qU5EyFQv_-~OICi}!wdjFHg^fXrmL*lCSl zJCd7U(_(;@p1vzQ)%?I+zmQXBhuOC4TRg7_DsPXRd8^9+L?^sY?#Qov9AxE!5HD;hQ)+ztE4cOciHnv zH*Ieo;^sdE6t1Z6Ka;-X+<+2|-dNT*KodZ9yn?m=Y4k(G<8+@GL+2XG+ z+2{k7EpsB-O1n+aH&CknrxF=dcE{Y<`xh^6E!?>Wif1 literal 0 HcmV?d00001 diff --git a/main/inc/lib/exercise.lib.php b/main/inc/lib/exercise.lib.php index 2cf4641a22..b9f7f91d83 100644 --- a/main/inc/lib/exercise.lib.php +++ b/main/inc/lib/exercise.lib.php @@ -39,7 +39,8 @@ class ExerciseLib $freeze = false, $user_choice = [], $show_comment = false, - $show_answers = false + $show_answers = false, + $show_icon = false ) { $course_id = empty($exercise->course_id) ? api_get_course_int_id() : $exercise->course_id; $course = api_get_course_info_by_id($course_id); @@ -309,8 +310,11 @@ class ExerciseLib switch ($answerType) { case UNIQUE_ANSWER: + //no break case UNIQUE_ANSWER_NO_OPTION: + //no break case UNIQUE_ANSWER_IMAGE: + //no break case READING_COMPREHENSION: $input_id = 'choice-'.$questionId.'-'.$answerId; if (isset($user_choice[0]['answer']) && $user_choice[0]['answer'] == $numAnswer) { @@ -390,7 +394,9 @@ class ExerciseLib } break; case MULTIPLE_ANSWER: + //no break case MULTIPLE_ANSWER_TRUE_FALSE: + //no break case GLOBAL_MULTIPLE_ANSWER: $input_id = 'choice-'.$questionId.'-'.$answerId; $answer = Security::remove_XSS($answer, STUDENT); @@ -987,7 +993,6 @@ HTML; $draggableSelectOptions[$selectItem['id']] = $selectItem['letter']; } - foreach ($draggableSelectOptions as $value => $text) { if ($value == $selectedValue) { break; @@ -3643,7 +3648,9 @@ EOT; $select_condition = " e.exe_id, answer "; break; case MATCHING: + //no break case MATCHING_DRAGGABLE: + //no break default: $answer_condition = " answer = $answer_id AND "; $select_condition = " DISTINCT exe_user_id "; @@ -3700,7 +3707,9 @@ EOT; return $good_answers; break; case MATCHING: + //no break case MATCHING_DRAGGABLE: + //no break default: $return = Database::num_rows($result); } @@ -4225,11 +4234,18 @@ EOT; if ($show_results) { $question_content .= ''; } - if (!$show_only_score) { + if ($objExercise->showExpectedChoice()) { $exercise_content .= Display::div( Display::panel($question_content), ['class' => 'question-panel'] ); + } else { + if (!$show_only_score) { + $exercise_content .= Display::div( + Display::panel($question_content), + ['class' => 'question-panel'] + ); + } } } // end foreach() block that loops over all questions } @@ -4271,6 +4287,12 @@ EOT; ); echo $total_score_text; + + // Ofaj change BT#11784 + if (!empty($objExercise->description)) { + echo Display::div($objExercise->description, array('class'=>'exercise_description')); + } + echo $exercise_content; if (!$show_only_score) { @@ -4322,24 +4344,6 @@ EOT; } } - /** - * @param string $class - * @param string $scoreLabel - * @param string $result - * - * @return string - */ - public static function getQuestionRibbon($class, $scoreLabel, $result) - { - return '
-
-

'.$scoreLabel.'

-
-

'.get_lang('Score').': '.$result.'

-
' - ; - } - /** * @param Exercise $objExercise * @param float $score diff --git a/main/inc/lib/exercise_show_functions.lib.php b/main/inc/lib/exercise_show_functions.lib.php index 45cc4b4c34..eede926bb2 100755 --- a/main/inc/lib/exercise_show_functions.lib.php +++ b/main/inc/lib/exercise_show_functions.lib.php @@ -44,71 +44,85 @@ class ExerciseShowFunctions $resultsDisabled, $showTotalScoreAndUserChoices ); - if (strpos($originalStudentAnswer, 'font color') !== false) { + // ofaj + /*if (strpos($originalStudentAnswer, 'font color') !== false) { $answerHTML = $originalStudentAnswer; - } - + }*/ if (empty($id)) { echo '
'; } else { - ?> - - - - - - - - '; + if (!api_is_allowed_to_edit(null, true) && $feedbackType != EXERCISE_FEEDBACK_TYPE_EXAM) { + echo ''; + } + echo ''; } } /** * Shows the answer to a calculated question, as HTML + * @param Exercise $exercise * @param string Answer text * @param int Exercise ID * @param int Question ID * @return void */ public static function display_calculated_answer( + $exercise, $feedback_type, $answer, $id, $questionId, $results_disabled, - $showTotalScoreAndUserChoices + $showTotalScoreAndUserChoices, + $expectedChoice = '', + $choice = '', + $status = '' ) { - if (empty($id)) { - echo ''; + if ($exercise->showExpectedChoice()) { + if (empty($id)) { + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } else { + echo ''; + if (!api_is_allowed_to_edit(null, true) && $feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) { + echo ''; + } + echo ''; + } } else { - ?> - - + if (empty($id)) { + echo ''; + } else { + echo ''; - - - - - '; + } } } @@ -226,10 +240,9 @@ class ExerciseShowFunctions } if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) { + $hide_expected_answer = true; if ($showTotalScoreAndUserChoices) { $hide_expected_answer = false; - } else { - $hide_expected_answer = true; } } @@ -248,42 +261,38 @@ class ExerciseShowFunctions "#ED2024", "#3B3B3B", "#F7BDE2" - ]; ?> -
'.get_lang('Choice').''.get_lang('ExpectedChoice').''.get_lang('Answer').''.get_lang('Status').''.get_lang('Comment').'
'; echo Security::remove_XSS($answerHTML, COURSEMANAGERLOWSECURITY); echo '
- - - -
'; + echo Security::remove_XSS($answerHTML, COURSEMANAGERLOWSECURITY); + echo ''; + $comm = Event::get_comments($id, $questionId); + echo '
'.Security::remove_XSS($answer).'
'. Security::remove_XSS($answer).''. Security::remove_XSS($choice).''. Security::remove_XSS($expectedChoice).''. Security::remove_XSS($status).'
'; + echo Security::remove_XSS($answer); + echo ''; + echo Security::remove_XSS($choice); + echo ''; + echo Security::remove_XSS($expectedChoice); + echo ''; + echo Security::remove_XSS($status); + echo ''; + $comm = Event::get_comments($id, $questionId); + echo '
- -
'.Security::remove_XSS($answer).'
'; + echo Security::remove_XSS($answer); + if (!api_is_allowed_to_edit(null, true) && $feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) { + echo ''; + $comm = Event::get_comments($id, $questionId); + echo ' - -
- - - - - - - - - - - '; + echo ''; + echo ''; + echo ''; + if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) { + echo ''; + } else { + echo ''; + } + echo ''; } /** * Display the answers to a multiple choice question + * @param Exercise $exercise * @param int $feedback_type Feedback type * @param int $answerType Answer type * @param int $studentChoice Student choice @@ -299,6 +308,7 @@ class ExerciseShowFunctions * @return void */ public static function display_unique_or_multiple_answer( + $exercise, $feedback_type, $answerType, $studentChoice, @@ -330,10 +340,9 @@ class ExerciseShowFunctions } if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) { + $hide_expected_answer = true; if ($showTotalScoreAndUserChoices) { $hide_expected_answer = false; - } else { - $hide_expected_answer = true; } } @@ -342,58 +351,59 @@ class ExerciseShowFunctions $icon .= '.png'; $iconAnswer = in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION]) ? 'radio' : 'checkbox'; $iconAnswer .= $answerCorrect ? '_on' : '_off'; - $iconAnswer .= '.png'; ?> - - - - + } + echo ''; + + if ($exercise->showExpectedChoice()) { + $status = Display::label(get_lang('Incorrect'), 'danger'); + if ($studentChoice) { + if ($answerCorrect) { + $status = Display::label(get_lang('Correct'), 'success'); + } + } + echo ''; + } - - - '.strip_tags($answerComment).''; + } + echo ''; if ($ans == 1) { $comm = Event::get_comments($id, $questionId); - } ?> - - - - -  '; + } + echo ''; } /** * Display the answers to a multiple choice question * + * @param Exercise $exercise * @param integer Answer type * @param integer Student choice * @param string Textual answer @@ -405,6 +415,7 @@ class ExerciseShowFunctions * @return void */ public static function display_multiple_answer_true_false( + $exercise, $feedback_type, $answerType, $studentChoice, @@ -418,35 +429,27 @@ class ExerciseShowFunctions $showTotalScoreAndUserChoices ) { $hide_expected_answer = false; - if ($feedback_type == 0 && ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ONLY)) { $hide_expected_answer = true; } if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) { + $hide_expected_answer = true; if ($showTotalScoreAndUserChoices) { $hide_expected_answer = false; - } else { - $hide_expected_answer = true; } - } ?> - - - - - - - '; + if ($exercise->showExpectedChoice()) { + $status = Display::label(get_lang('Incorrect'), 'danger'); + if (isset($new_options[$studentChoice])) { + if ($studentChoice == $answerCorrect) { + $status = Display::label(get_lang('Correct'), 'success'); + } + } + echo ''; + } + if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) { + echo ' - '; if ($ans == 1) { $comm = Event::get_comments($id, $questionId); - } ?> - - - - -  '; + } + echo ''; } /** * Display the answers to a multiple choice question * + * @param Exercise $exercise * @param integer Answer type * @param integer Student choice * @param string Textual answer @@ -506,6 +511,7 @@ class ExerciseShowFunctions * @return void */ public static function display_multiple_answer_combination_true_false( + $exercise, $feedback_type, $answerType, $studentChoice, @@ -524,26 +530,22 @@ class ExerciseShowFunctions } if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) { + $hide_expected_answer = true; if ($showTotalScoreAndUserChoices) { $hide_expected_answer = false; - } else { - $hide_expected_answer = true; } - } ?> - - - - - '; + echo ''; + + if ($exercise->showExpectedChoice()) { + $status = ''; + if (isset($studentChoice)) { + $status = Display::label(get_lang('Incorrect'), 'danger'); + if ($studentChoice == $answerCorrect) { + $status = Display::label(get_lang('Correct'), 'success'); + } + } + echo ''; + } + if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) { - ?> - - '; if ($ans == 1) { $comm = Event::get_comments($id, $questionId); } diff --git a/main/install/configuration.dist.php b/main/install/configuration.dist.php index 1458235bc0..ef4b585cb0 100755 --- a/main/install/configuration.dist.php +++ b/main/install/configuration.dist.php @@ -760,7 +760,8 @@ ALTER TABLE skill_rel_item ADD CONSTRAINT FK_EB5B2A0D5585C142 FOREIGN KEY (skill // LP view custom settings // $_configuration['lp_view_settings'] = ['display' => ['show_reporting_icon' => true]]; - +// Show more expected choice and status in exercise results BT#13950 +//$_configuration['show_exercise_expected_choice'] = false; // ------ Custom DB changes // Add user activation by confirmation email
- - - - - - - '.nl2br($answerComment).''; - } ?> -  
'; + echo ''; + echo ''; + echo "$answerId - $answer"; + echo ''; + if (!$hide_expected_answer) { + $status = Display::label(get_lang('Incorrect'), 'danger'); + if ($studentChoice) { + $status = Display::label(get_lang('Correct'), 'success'); + } + echo $status; + } + echo ''; + if ($studentChoice) { + echo ''.nl2br($answerComment).''; + } + echo ' 
- - - '; + echo ''; + echo Display::return_icon($icon, null, null, ICON_SIZE_TINY); + echo ''; + if (!$hide_expected_answer) { echo Display::return_icon($iconAnswer, null, null, ICON_SIZE_TINY); } else { echo "-"; - } ?> - - - '; + echo $answer; + echo ''; + echo $status; + echo ' - '; if ($studentChoice) { + $color = 'black'; if ($answerCorrect) { $color = 'green'; - //echo ''.nl2br($answerComment).''; - } else { - $color = 'black'; - //echo ''.nl2br($answerComment).''; } if ($hide_expected_answer) { $color = ''; } - echo ''.nl2br($answerComment).''; - } ?> -  
- '; + $course_id = api_get_course_int_id(); $new_options = Question::readQuestionOption($questionId, $course_id); - - //Your choice + // Your choice if (isset($new_options[$studentChoice])) { echo get_lang($new_options[$studentChoice]['name']); } else { echo '-'; - } ?> - - '; + // Expected choice if (!$hide_expected_answer) { if (isset($new_options[$answerCorrect])) { echo get_lang($new_options[$answerCorrect]['name']); @@ -455,16 +458,23 @@ class ExerciseShowFunctions } } else { echo '-'; - } ?> - - - - '; + echo $answer; + echo ''; + echo $status; + echo ''; $color = "black"; if (isset($new_options[$studentChoice])) { if ($studentChoice == $answerCorrect) { @@ -474,27 +484,22 @@ class ExerciseShowFunctions if ($hide_expected_answer) { $color = ''; } - echo ''.nl2br($answerComment).''; - } ?> -  
- '; + // Your choice $question = new MultipleAnswerCombinationTrueFalse(); if (isset($question->options[$studentChoice])) { echo $question->options[$studentChoice]; } else { echo $question->options[2]; - } ?> - - '; + // Expected choice if (!$hide_expected_answer) { if (isset($question->options[$answerCorrect])) { echo $question->options[$answerCorrect]; @@ -552,18 +554,28 @@ class ExerciseShowFunctions } } else { echo '-'; - } ?> - - - '; + // my answer + echo $answer; + echo ''; + echo $status; + echo ' - '; //@todo replace this harcoded value if ($studentChoice) { $color = "black"; @@ -574,9 +586,8 @@ class ExerciseShowFunctions $color = ''; } echo ''.nl2br($answerComment).''; - } ?> -