diff --git a/main/admin/access_url_edit_usergroup_to_url.php b/main/admin/access_url_edit_usergroup_to_url.php index 8fcbc2be79..fdfd814d09 100755 --- a/main/admin/access_url_edit_usergroup_to_url.php +++ b/main/admin/access_url_edit_usergroup_to_url.php @@ -109,7 +109,7 @@ echo ''; api_display_tool_title($tool_name); $noUserGroupList = $userGroupList = []; -$ajax_search = $add_type == 'unique' ? true : false; +$ajax_search = $add_type === 'unique' ? true : false; if ($ajax_search) { $userGroups = UrlManager::get_url_rel_usergroup_data($access_url_id); diff --git a/main/badge/assign.php b/main/badge/assign.php index 73a82c0d4f..f52acc0d5e 100644 --- a/main/badge/assign.php +++ b/main/badge/assign.php @@ -2,7 +2,6 @@ /* For licensing terms, see /license.txt */ use Chamilo\CoreBundle\Entity\Skill; -use Chamilo\CoreBundle\Entity\SkillRelUser; use Chamilo\UserBundle\Entity\User; use Skill as SkillManager; @@ -289,22 +288,13 @@ if ($form->validate()) { exit; } - $skillUser = new SkillRelUser(); - $skillUser->setUser($user); - $skillUser->setSkill($skill); - - if ($showLevels) { - $level = $skillLevelRepo->find($values['acquired_level']); - $skillUser->setAcquiredLevel($level); - } - - $skillUser->setArgumentation($values['argumentation']); - $skillUser->setArgumentationAuthorId(api_get_user_id()); - $skillUser->setAcquiredSkillAt(new DateTime()); - $skillUser->setAssignedBy(0); - - $entityManager->persist($skillUser); - $entityManager->flush(); + $skillUser = $skillManager->addSkillToUserBadge( + $user, + $skill, + $values['acquired_level'], + $values['argumentation'], + api_get_user_id() + ); // Send email depending of children_auto_threshold $skillRelSkill = new SkillRelSkill(); @@ -334,9 +324,9 @@ if ($form->validate()) { Display::addFlash(Display::return_message(get_lang('MessageSent'))); $url = api_get_path(WEB_CODE_PATH).'badge/assign.php?user='.$userId.'&id='.$parentId; $link = Display::url($url, $url); - $subject = get_lang("StudentHadEnoughSkills"); + $subject = get_lang('StudentHadEnoughSkills'); $message = sprintf( - get_lang("StudentXHadEnoughSkillsToGetSkillXToAssignClickHereX"), + get_lang('StudentXHadEnoughSkillsToGetSkillXToAssignClickHereX'), UserManager::formatUserFullName($user), $parentData['name'], $link diff --git a/main/exercise/Draggable.php b/main/exercise/Draggable.php index bc08cde916..3916aea886 100644 --- a/main/exercise/Draggable.php +++ b/main/exercise/Draggable.php @@ -217,7 +217,9 @@ class Draggable extends Question if ($exercise->showExpectedChoice()) { $header .= ''.get_lang('YourChoice').''; - $header .= ''.get_lang('ExpectedChoice').''; + if ($exercise->showExpectedChoiceColumn()) { + $header .= ''.get_lang('ExpectedChoice').''; + } } else { $header .= ''.get_lang('ElementList').''; } diff --git a/main/exercise/MatchingDraggable.php b/main/exercise/MatchingDraggable.php index a19838e12f..666c1802e0 100644 --- a/main/exercise/MatchingDraggable.php +++ b/main/exercise/MatchingDraggable.php @@ -274,7 +274,9 @@ class MatchingDraggable extends Question } if ($exercise->showExpectedChoice()) { - $header .= ''.get_lang('ExpectedChoice').''; + if ($exercise->showExpectedChoiceColumn()) { + $header .= ''.get_lang('ExpectedChoice').''; + } $header .= ''.get_lang('Status').''; } else { $header .= ''.get_lang('CorrespondsTo').''; diff --git a/main/exercise/MultipleAnswerTrueFalseDegreeCertainty.php b/main/exercise/MultipleAnswerTrueFalseDegreeCertainty.php index ec06be784c..c4d630ce7c 100644 --- a/main/exercise/MultipleAnswerTrueFalseDegreeCertainty.php +++ b/main/exercise/MultipleAnswerTrueFalseDegreeCertainty.php @@ -77,7 +77,7 @@ class MultipleAnswerTrueFalseDegreeCertainty extends Question .''; // show column comment when feedback is enable - if ($objEx->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { + if ($objEx->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { $html .= ''.get_lang('Comment').''; } $html .= ''; @@ -173,7 +173,7 @@ class MultipleAnswerTrueFalseDegreeCertainty extends Question $form->addRule('answer['.$i.']', get_lang('ThisFieldIsRequired'), 'required'); // show comment when feedback is enable - if ($objEx->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { + if ($objEx->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { $form->addElement( 'html_editor', 'comment['.$i.']', @@ -306,19 +306,20 @@ class MultipleAnswerTrueFalseDegreeCertainty extends Question public function return_header(Exercise $exercise, $counter = null, $score = []) { $header = parent::return_header($exercise, $counter, $score); - $header .= '
' - .get_lang('Choice') - .'' - .get_lang('ExpectedChoice') - .'' + $header .= ''; + $header .= ''; + + if ($exercise->showExpectedChoiceColumn()) { + $header .= ''; + } + + $header .='' ; - if ($exercise->feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) { + if ($exercise->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { $header .= ''; } else { $header .= ''; diff --git a/main/exercise/TestCategory.php b/main/exercise/TestCategory.php index 3de809f5d7..3b3a7ec3fb 100644 --- a/main/exercise/TestCategory.php +++ b/main/exercise/TestCategory.php @@ -714,40 +714,6 @@ class TestCategory return $tabResult; } - /** - * return total score for test exe_id for all question in the category $in_cat_id for user - * If no question for this category, return "". - */ - public static function getCatScoreForExeidForUserid($in_cat_id, $in_exe_id, $in_user_id) - { - $tbl_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); - $tbl_question_rel_category = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY); - $in_cat_id = (int) $in_cat_id; - $in_exe_id = (int) $in_exe_id; - $in_user_id = (int) $in_user_id; - - $query = "SELECT DISTINCT - marks, - exe_id, - user_id, - ta.question_id, - category_id - FROM $tbl_track_attempt ta - INNER JOIN $tbl_question_rel_category qrc - ON (ta.question_id = qrc.question_id) - WHERE - qrc.category_id = $in_cat_id AND - exe_id = $in_exe_id AND - user_id = $in_user_id"; - $res = Database::query($query); - $score = ''; - while ($data = Database::fetch_array($res)) { - $score += $data['marks']; - } - - return $score; - } - /** * Return the number max of question in a category * count the number of questions in all categories, and return the max. diff --git a/main/exercise/UniqueAnswerImage.php b/main/exercise/UniqueAnswerImage.php index 849cd8ec8b..7fc0ced2b7 100644 --- a/main/exercise/UniqueAnswerImage.php +++ b/main/exercise/UniqueAnswerImage.php @@ -43,13 +43,18 @@ class UniqueAnswerImage extends UniqueAnswer $numberAnswers += (isset($_POST['lessAnswers']) ? -1 : (isset($_POST['moreAnswers']) ? 1 : 0)); $feedbackTitle = ''; - - if ($objExercise->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) { - //Scenario - $commentTitle = ''; - $feedbackTitle = ''; - } else { - $commentTitle = ''; + switch ($objExercise->getFeedbackType()) { + case EXERCISE_FEEDBACK_TYPE_DIRECT: + // Scenario + $commentTitle = ''; + $feedbackTitle = ''; + break; + case EXERCISE_FEEDBACK_TYPE_POPUP: + $commentTitle = ''; + break; + default: + $commentTitle = ''; + break; } $html = ''); } @@ -378,9 +351,11 @@ class UniqueAnswerImage extends UniqueAnswer if ($exercise->showExpectedChoice()) { $header = '
'.get_lang('Choice').''.get_lang('ExpectedChoice').'' .get_lang('Answer') .'' .get_lang('YourDegreeOfCertainty') .''.get_lang('Comment').' '.get_lang('Comment').''.get_lang('Scenario').''.get_lang('Comment').''.get_lang('Comment').''.get_lang('Scenario').''.get_lang('Comment').''.get_lang('Comment').'{error}
{element}', - 'scenario' - ); - } else { - $form->addHtmlEditor('comment['.$i.']', null, null, false, $editorConfig); + switch ($objExercise->getFeedbackType()) { + case EXERCISE_FEEDBACK_TYPE_DIRECT: + $this->setDirectOptions($i, $form, $renderer, $selectLpId, $selectQuestion); + break; + case EXERCISE_FEEDBACK_TYPE_POPUP: + default: + $form->addHtmlEditor('comment['.$i.']', null, null, false, $editorConfig); + break; } - $form->addText('weighting['.$i.']', null, null, ['class' => "col-md-1", 'value' => '0']); + + $form->addText('weighting['.$i.']', null, null, ['class' => 'col-md-1', 'value' => '0']); $form->addHtml('
- - - '; + '; + if ($exercise->showExpectedChoiceColumn()) { + $header .= ''; + } + $header .= ''; $header .= ''; $header .= ''; $header .= ''; diff --git a/main/exercise/admin.php b/main/exercise/admin.php index 393e9330bc..7a99f35983 100755 --- a/main/exercise/admin.php +++ b/main/exercise/admin.php @@ -453,7 +453,7 @@ if (!$newQuestion && !$modifyQuestion && !$editQuestion && !isset($_GET['hotspot // if we are in question authoring, display warning to user is feedback not shown at the end of the test -ref #6619 // this test to display only message in the question authoring page and not in the question list page too -if ($objExercise->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_EXAM) { +if ($objExercise->getFeedbackType() == EXERCISE_FEEDBACK_TYPE_EXAM) { echo Display::return_message(get_lang('TestFeedbackNotShown'), 'normal'); } diff --git a/main/exercise/calculated_answer.class.php b/main/exercise/calculated_answer.class.php index 4df19a690a..94ea1e7420 100644 --- a/main/exercise/calculated_answer.class.php +++ b/main/exercise/calculated_answer.class.php @@ -252,7 +252,9 @@ class CalculatedAnswer extends Question $header .= ''; if ($exercise->showExpectedChoice()) { $header .= ''; - $header .= ''; + if ($exercise->showExpectedChoiceColumn()) { + $header .= ''; + } $header .= ''; } $header .= ''; diff --git a/main/exercise/exercise.class.php b/main/exercise/exercise.class.php index d85e615b3a..8aaf59c986 100755 --- a/main/exercise/exercise.class.php +++ b/main/exercise/exercise.class.php @@ -1,8 +1,10 @@ globalCategoryId = null; $this->notifications = []; $this->exerciseCategoryId = 0; + $this->pageResultConfiguration; if (!empty($courseId)) { $courseInfo = api_get_course_info_by_id($courseId); @@ -201,6 +205,10 @@ class Exercise $this->notifications = explode(',', $object->notifications); } + if (!empty($object->page_result_configuration)) { + $this->pageResultConfiguration = $object->page_result_configuration; + } + if (isset($object->show_previous_button)) { $this->showPreviousButton = $object->show_previous_button == 1 ? true : false; } @@ -219,7 +227,6 @@ class Exercise } $this->force_edit_exercise_in_lp = api_get_setting('lp.show_invisible_exercise_in_lp_toc') === 'true'; - $this->edit_exercise_in_lp = true; if ($this->exercise_was_added_in_lp) { $this->edit_exercise_in_lp = $this->force_edit_exercise_in_lp == true; @@ -309,14 +316,15 @@ class Exercise return $this->attempts; } - /** returns the number of FeedbackType * - * 0=>Feedback , 1=>DirectFeedback, 2=>NoFeedback. + /** + * Returns the number of FeedbackType + * 0: Feedback , 1: DirectFeedback, 2: NoFeedback. * * @return int - exercise attempts */ - public function selectFeedbackType() + public function getFeedbackType() { - return $this->feedback_type; + return (int) $this->feedback_type; } /** @@ -416,7 +424,7 @@ class Exercise * * @return string html text : the text to display ay the end of the test */ - public function selectTextWhenFinished() + public function getTextWhenFinished() { return $this->text_when_finished; } @@ -644,10 +652,10 @@ class Exercise ON (e.question_id = q.id AND e.c_id = ".$this->course_id." ) WHERE e.exercice_id = '".$this->id."' "; - $orderCondition = "ORDER BY question_order"; + $orderCondition = ' ORDER BY question_order '; if (!empty($sidx) && !empty($sord)) { - if ($sidx == 'question') { + if ($sidx === 'question') { if (in_array(strtolower($sord), ['desc', 'asc'])) { $orderCondition = " ORDER BY q.$sidx $sord"; } @@ -657,8 +665,8 @@ class Exercise $sql .= $orderCondition; $limitCondition = null; if (isset($start) && isset($limit)) { - $start = intval($start); - $limit = intval($limit); + $start = (int) $start; + $limit = (int) $limit; $limitCondition = " LIMIT $start, $limit"; } $sql .= $limitCondition; @@ -677,7 +685,7 @@ class Exercise ); if (empty($category_labels)) { - $category_labels = "-"; + $category_labels = '-'; } // Question type @@ -1088,7 +1096,7 @@ class Exercise /** * @return int */ - public function selectSaveCorrectAnswers() + public function getSaveCorrectAnswers() { return $this->saveCorrectAnswers; } @@ -1257,7 +1265,7 @@ class Exercise */ public function updateSaveCorrectAnswers($value) { - $this->saveCorrectAnswers = $value; + $this->saveCorrectAnswers = (int) $value; } /** @@ -1502,7 +1510,7 @@ class Exercise $random_answers = $this->random_answers; $active = $this->active; $propagate_neg = (int) $this->propagate_neg; - $saveCorrectAnswers = isset($this->saveCorrectAnswers) && $this->saveCorrectAnswers ? 1 : 0; + $saveCorrectAnswers = isset($this->saveCorrectAnswers) ? (int) $this->saveCorrectAnswers : 0; $review_answers = isset($this->review_answers) && $this->review_answers ? 1 : 0; $randomByCat = (int) $this->randomByCat; $text_when_finished = $this->text_when_finished; @@ -1512,7 +1520,7 @@ class Exercise // If direct we do not show results $results_disabled = (int) $this->results_disabled; - if ($feedback_type == EXERCISE_FEEDBACK_TYPE_DIRECT) { + if (in_array($feedback_type, [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP])) { $results_disabled = 0; } $expired_time = (int) $this->expired_time; @@ -1576,6 +1584,10 @@ class Exercise $notifications = implode(',', $notifications); $paramsExtra['notifications'] = $notifications; } + + if (!empty($this->pageResultConfiguration)) { + $paramsExtra['page_result_configuration'] = $this->pageResultConfiguration; + } } $params = array_merge($params, $paramsExtra); @@ -1636,7 +1648,7 @@ class Exercise 'text_when_finished' => $text_when_finished, 'display_category_name' => $display_category_name, 'pass_percentage' => $pass_percentage, - 'save_correct_answers' => (int) $saveCorrectAnswers, + 'save_correct_answers' => $saveCorrectAnswers, 'propagate_neg' => $propagate_neg, 'hide_question_title' => $this->getHideQuestionTitle(), ]; @@ -1661,6 +1673,10 @@ class Exercise } } + if (!empty($this->pageResultConfiguration)) { + $params['page_result_configuration'] = $this->pageResultConfiguration; + } + $this->id = $this->iId = Database::insert($TBL_EXERCISES, $params); if ($this->id) { @@ -1875,14 +1891,13 @@ class Exercise $type = 'full'; } - // form title + // Form title + $form_title = get_lang('NewEx'); if (!empty($_GET['exerciseId'])) { $form_title = get_lang('ModifyExercise'); - } else { - $form_title = get_lang('NewEx'); } - $form->addElement('header', $form_title); + $form->addHeader($form_title); // Title. if (api_get_configuration_value('save_titles_as_html')) { @@ -1929,6 +1944,7 @@ class Exercise 'Width' => '100%', 'Height' => '150', ]; + if (is_array($type)) { $editor_config = array_merge($editor_config, $type); } @@ -1943,56 +1959,9 @@ class Exercise $skillList = []; if ($type === 'full') { - //Can't modify a DirectFeedback question - if ($this->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_DIRECT) { - // feedback type - $radios_feedback = []; - $radios_feedback[] = $form->createElement( - 'radio', - 'exerciseFeedbackType', - null, - get_lang('ExerciseAtTheEndOfTheTest'), - '0', - [ - 'id' => 'exerciseType_0', - 'onclick' => 'check_feedback()', - ] - ); - - 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 - if ($this->selectNbrQuestions() == 0) { - $radios_feedback[] = $form->createElement( - 'radio', - 'exerciseFeedbackType', - null, - get_lang('DirectFeedback'), - '1', - [ - 'id' => 'exerciseType_1', - 'onclick' => 'check_direct_feedback()', - ] - ); - } - } - - $radios_feedback[] = $form->createElement( - 'radio', - 'exerciseFeedbackType', - null, - get_lang('NoFeedback'), - '2', - ['id' => 'exerciseType_2'] - ); - $form->addGroup( - $radios_feedback, - null, - [ - get_lang('FeedbackType'), - get_lang('FeedbackDisplayOptions'), - ] - ); + // Can't modify a DirectFeedback question. + if (!in_array($this->getFeedbackType(), [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP])) { + $this->setResultFeedbackGroup($form); // Type of results display on the final page $this->setResultDisabledGroup($form); @@ -2026,41 +1995,7 @@ class Exercise } else { // if is Direct feedback but has not questions we can allow to modify the question type if ($this->getQuestionCount() === 0) { - // feedback type - $radios_feedback = []; - $radios_feedback[] = $form->createElement( - 'radio', - 'exerciseFeedbackType', - null, - get_lang('ExerciseAtTheEndOfTheTest'), - '0', - ['id' => 'exerciseType_0', 'onclick' => 'check_feedback()'] - ); - - if (api_get_setting('enable_quiz_scenario') == 'true') { - $radios_feedback[] = $form->createElement( - 'radio', - 'exerciseFeedbackType', - null, - get_lang('DirectFeedback'), - '1', - ['id' => 'exerciseType_1', 'onclick' => 'check_direct_feedback()'] - ); - } - $radios_feedback[] = $form->createElement( - 'radio', - 'exerciseFeedbackType', - null, - get_lang('NoFeedback'), - '2', - ['id' => 'exerciseType_2'] - ); - $form->addGroup( - $radios_feedback, - null, - [get_lang('FeedbackType'), get_lang('FeedbackDisplayOptions')] - ); - + $this->setResultFeedbackGroup($form); $this->setResultDisabledGroup($form); // Type of questions disposition on page @@ -2079,7 +2014,7 @@ class Exercise $group->freeze(); // we force the options to the DirectFeedback exercisetype - $form->addElement('hidden', 'exerciseFeedbackType', EXERCISE_FEEDBACK_TYPE_DIRECT); + $form->addElement('hidden', 'exerciseFeedbackType', $this->getFeedbackType()); $form->addElement('hidden', 'exerciseType', ONE_PER_PAGE); // Type of questions disposition on page @@ -2154,6 +2089,30 @@ class Exercise ] ); + + $group = [ + $form->createElement( + 'checkbox', + 'hide_expected_answer', + null, + get_lang('HideExpectedAnswer') + ), + $form->createElement( + 'checkbox', + 'hide_total_score', + null, + get_lang('HideTotalScore') + ), + $form->createElement( + 'checkbox', + 'hide_question_score', + null, + get_lang('HideQuestionScore') + ) + ]; + $form->addGroup($group, null, get_lang('ResultsConfigurationPage')); + + $displayMatrix = 'none'; $displayRandom = 'none'; $selectionType = $this->getQuestionSelectionType(); @@ -2201,13 +2160,6 @@ class Exercise $form->addElement('label', null, $cat_form); $form->addElement('html', ''); - // Category name. - $radio_display_cat_name = [ - $form->createElement('radio', 'display_category_name', null, get_lang('Yes'), '1'), - $form->createElement('radio', 'display_category_name', null, get_lang('No'), '0'), - ]; - $form->addGroup($radio_display_cat_name, null, get_lang('QuestionDisplayCategoryName')); - // Random answers. $radios_random_answers = [ $form->createElement('radio', 'randomAnswers', null, get_lang('Yes'), '1'), @@ -2215,6 +2167,13 @@ class Exercise ]; $form->addGroup($radios_random_answers, null, get_lang('RandomAnswers')); + // Category name. + $radio_display_cat_name = [ + $form->createElement('radio', 'display_category_name', null, get_lang('Yes'), '1'), + $form->createElement('radio', 'display_category_name', null, get_lang('No'), '0'), + ]; + $form->addGroup($radio_display_cat_name, null, get_lang('QuestionDisplayCategoryName')); + // Hide question title. $group = [ $form->createElement('radio', 'hide_question_title', null, get_lang('Yes'), '1'), @@ -2298,11 +2257,19 @@ class Exercise null, get_lang('PropagateNegativeResults') ); - $form->addCheckBox( + + + $options = [ + '' => get_lang('SelectAnOption'), + 1 => get_lang('SaveTheCorrectAnswersForTheNextAttempt'), + 2 => get_lang('SaveAllAnswers'), + ]; + $form->addSelect( 'save_correct_answers', - null, - get_lang('SaveTheCorrectAnswersForTheNextAttempt') - ); + get_lang('SaveAnswers'), + $options + ); + $form->addElement('html', '
 
'); $form->addElement('checkbox', 'review_answers', null, get_lang('ReviewAnswers')); $form->addElement('html', '
'); @@ -2439,24 +2406,19 @@ class Exercise $form->addRule('end_time', get_lang('InvalidDate'), 'datetime'); if ($this->id > 0) { - //if ($this->random > $this->selectNbrQuestions()) { - // $defaults['randomQuestions'] = $this->selectNbrQuestions(); - //} else { $defaults['randomQuestions'] = $this->random; - //} - $defaults['randomAnswers'] = $this->getRandomAnswers(); $defaults['exerciseType'] = $this->selectType(); $defaults['exerciseTitle'] = $this->get_formated_title(); $defaults['exerciseDescription'] = $this->selectDescription(); $defaults['exerciseAttempts'] = $this->selectAttempts(); - $defaults['exerciseFeedbackType'] = $this->selectFeedbackType(); + $defaults['exerciseFeedbackType'] = $this->getFeedbackType(); $defaults['results_disabled'] = $this->selectResultsDisabled(); $defaults['propagate_neg'] = $this->selectPropagateNeg(); - $defaults['save_correct_answers'] = $this->selectSaveCorrectAnswers(); + $defaults['save_correct_answers'] = $this->getSaveCorrectAnswers(); $defaults['review_answers'] = $this->review_answers; $defaults['randomByCat'] = $this->getRandomByCategory(); - $defaults['text_when_finished'] = $this->selectTextWhenFinished(); + $defaults['text_when_finished'] = $this->getTextWhenFinished(); $defaults['display_category_name'] = $this->selectDisplayCategoryName(); $defaults['pass_percentage'] = $this->selectPassPercentage(); $defaults['question_selection_type'] = $this->getQuestionSelectionType(); @@ -2512,6 +2474,8 @@ class Exercise if (api_get_setting('search_enabled') === 'true') { $defaults['index_document'] = 'checked="checked"'; } + + $this->setPageResultConfigurationDefaults($defaults); $form->setDefaults($defaults); // Freeze some elements. @@ -2533,6 +2497,71 @@ class Exercise } } + /** + * @param $form + */ + public function setResultFeedbackGroup(FormValidator $form) + { + // Feedback type. + $feedback = []; + $feedback[] = $form->createElement( + 'radio', + 'exerciseFeedbackType', + null, + get_lang('ExerciseAtTheEndOfTheTest'), + EXERCISE_FEEDBACK_TYPE_END, + [ + 'id' => 'exerciseType_'.EXERCISE_FEEDBACK_TYPE_END, + 'onclick' => 'check_feedback()', + ] + ); + + 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 + if ($this->selectNbrQuestions() == 0) { + $feedback[] = $form->createElement( + 'radio', + 'exerciseFeedbackType', + null, + get_lang('DirectFeedback'), + EXERCISE_FEEDBACK_TYPE_DIRECT, + [ + 'id' => 'exerciseType_'.EXERCISE_FEEDBACK_TYPE_DIRECT, + 'onclick' => 'check_direct_feedback()', + ] + ); + } + } + + $feedback[] = $form->createElement( + 'radio', + 'exerciseFeedbackType', + null, + get_lang('ExerciseDirectPopUp'), + EXERCISE_FEEDBACK_TYPE_POPUP, + ['id' => 'exerciseType_'.EXERCISE_FEEDBACK_TYPE_POPUP, 'onclick' => 'check_direct_feedback()'] + ); + + $feedback[] = $form->createElement( + 'radio', + 'exerciseFeedbackType', + null, + get_lang('NoFeedback'), + EXERCISE_FEEDBACK_TYPE_EXAM, + ['id' => 'exerciseType_'.EXERCISE_FEEDBACK_TYPE_EXAM] + ); + + $form->addGroup( + $feedback, + null, + [ + get_lang('FeedbackType'), + get_lang('FeedbackDisplayOptions'), + ] + ); + } + /** * function which process the creation of exercises. * @@ -2576,6 +2605,7 @@ class Exercise $this->setShowPreviousButton($form->getSubmitValue('show_previous_button')); $this->setNotifications($form->getSubmitValue('notifications')); $this->setExerciseCategoryId($form->getSubmitValue('exercise_category_id')); + $this->setPageResultConfiguration($form->getSubmitValues()); $this->start_time = null; if ($form->getSubmitValue('activate_start_date_check') == 1) { @@ -3082,7 +3112,9 @@ class Exercise $html = $label = ''; $hotspot_get = isset($_POST['hotspot']) ? Security::remove_XSS($_POST['hotspot']) : null; - if ($this->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT && $this->type == ONE_PER_PAGE) { + if (in_array($this->getFeedbackType(), [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP]) && + $this->type == ONE_PER_PAGE + ) { $urlTitle = get_lang('ContinueTest'); if ($questionNum == count($this->questionList)) { $urlTitle = get_lang('EndTest'); @@ -3090,7 +3122,7 @@ class Exercise $html .= Display::url( $urlTitle, - 'exercise_submit_modal.php?'.http_build_query([ + api_get_path(WEB_CODE_PATH).'exercise/exercise_submit_modal.php?'.http_build_query([ 'learnpath_id' => $safe_lp_id, 'learnpath_item_id' => $safe_lp_item_id, 'learnpath_item_view_id' => $safe_lp_item_view_id, @@ -3104,7 +3136,7 @@ class Exercise ]), [ 'class' => 'ajax btn btn-default', - 'data-title' => $urlTitle, + 'data-title' => Security::remove_XSS(get_lang('Comment')), 'data-size' => 'md', ] ); @@ -3158,7 +3190,6 @@ class Exercise $num++; } $prev_question = $num; - //$question_id = $beforeId; } } @@ -3338,7 +3369,7 @@ class Exercise global $learnpath_id, $learnpath_item_id; require_once api_get_path(LIBRARY_PATH).'geometry.lib.php'; $em = Database::getManager(); - $feedback_type = $this->selectFeedbackType(); + $feedback_type = $this->getFeedbackType(); $results_disabled = $this->selectResultsDisabled(); if ($debug) { @@ -4354,10 +4385,12 @@ class Exercise case MATCHING: case MATCHING_DRAGGABLE: echo '
'; - if (!in_array($this->results_disabled, [ - RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER, - //RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING, - ]) + if (!in_array( + $this->results_disabled, + [ + RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER, + ] + ) ) { echo ''; echo ''; @@ -4367,31 +4400,35 @@ class Exercise } if ($this->showExpectedChoice()) { - echo ''; } - echo ''; echo ''; } else { - echo ''; + } } } - echo ''; } echo ''; break; @@ -4699,6 +4736,7 @@ class Exercise ); } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { ExerciseShowFunctions::displayMultipleAnswerTrueFalseDegreeCertainty( + $this, $feedback_type, $studentChoice, $studentChoiceDegree, @@ -4725,6 +4763,7 @@ class Exercise ); } elseif ($answerType == FILL_IN_BLANKS) { ExerciseShowFunctions::display_fill_in_blanks_answer( + $this, $feedback_type, $answer, 0, @@ -4806,8 +4845,12 @@ class Exercise $coords = explode('/', $user_answer); $user_array = ''; foreach ($coords as $coord) { - list($x, $y) = explode(';', $coord); - $user_array .= round($x).';'.round($y).'/'; + if (!empty($coord)) { + $parts = explode(';', $coord); + if (!empty($parts)) { + $user_array .= round($parts[0]).';'.round($parts[1]).'/'; + } + } } $user_array = substr($user_array, 0, -1); @@ -5091,6 +5134,7 @@ class Exercise case MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY: if ($answerId == 1) { ExerciseShowFunctions::displayMultipleAnswerTrueFalseDegreeCertainty( + $this, $feedback_type, $studentChoice, $studentChoiceDegree, @@ -5102,6 +5146,7 @@ class Exercise ); } else { ExerciseShowFunctions::displayMultipleAnswerTrueFalseDegreeCertainty( + $this, $feedback_type, $studentChoice, $studentChoiceDegree, @@ -5115,6 +5160,7 @@ class Exercise break; case FILL_IN_BLANKS: ExerciseShowFunctions::display_fill_in_blanks_answer( + $this, $feedback_type, $answer, $exeId, @@ -7190,7 +7236,10 @@ class Exercise if ($currentQuestion != $i) { continue; } else { - if ($this->feedback_type != EXERCISE_FEEDBACK_TYPE_DIRECT) { + if (!in_array( + $this->getFeedbackType(), + [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP] + )) { // if the user has already answered this question if (isset($exerciseResult[$questionId])) { echo Display::return_message( @@ -7799,12 +7848,13 @@ class Exercise /** * Get the correct answers in all attempts. * - * @param int $learnPathId - * @param int $learnPathItemId + * @param int $learnPathId + * @param int $learnPathItemId + * @param bool $onlyCorrect * * @return array */ - public function getCorrectAnswersInAllAttempts($learnPathId = 0, $learnPathItemId = 0) + public function getAnswersInAllAttempts($learnPathId = 0, $learnPathItemId = 0, $onlyCorrect = true) { $attempts = Event::getExerciseResultsByUser( api_get_user_id(), @@ -7813,43 +7863,63 @@ class Exercise api_get_session_id(), $learnPathId, $learnPathItemId, - 'asc' + 'DESC' ); - $corrects = []; + $list = []; foreach ($attempts as $attempt) { foreach ($attempt['question_list'] as $answers) { foreach ($answers as $answer) { $objAnswer = new Answer($answer['question_id']); - - switch ($objAnswer->getQuestionType()) { - case FILL_IN_BLANKS: - $isCorrect = FillBlanks::isCorrect($answer['answer']); - break; - case MATCHING: - case DRAGGABLE: - case MATCHING_DRAGGABLE: - $isCorrect = Matching::isCorrect( - $answer['position'], - $answer['answer'], - $answer['question_id'] - ); - break; - case ORAL_EXPRESSION: - $isCorrect = false; - break; - default: - $isCorrect = $objAnswer->isCorrectByAutoId($answer['answer']); - } - - if ($isCorrect) { - $corrects[$answer['question_id']][] = $answer; + if ($onlyCorrect) { + switch ($objAnswer->getQuestionType()) { + case FILL_IN_BLANKS: + $isCorrect = FillBlanks::isCorrect($answer['answer']); + break; + case MATCHING: + case DRAGGABLE: + case MATCHING_DRAGGABLE: + $isCorrect = Matching::isCorrect( + $answer['position'], + $answer['answer'], + $answer['question_id'] + ); + break; + case ORAL_EXPRESSION: + $isCorrect = false; + break; + default: + $isCorrect = $objAnswer->isCorrectByAutoId($answer['answer']); + } + if ($isCorrect) { + $list[$answer['question_id']][] = $answer; + } + } else { + $list[$answer['question_id']][] = $answer; } } } + + if ($onlyCorrect === false) { + // Only take latest attempt + break; + } } - return $corrects; + return $list; + } + + /** + * Get the correct answers in all attempts. + * + * @param int $learnPathId + * @param int $learnPathItemId + * + * @return array + */ + public function getCorrectAnswersInAllAttempts($learnPathId = 0, $learnPathItemId = 0) + { + return $this->getAnswersInAllAttempts($learnPathId , $learnPathItemId); } /** @@ -7881,6 +7951,76 @@ class Exercise $this->exerciseCategoryId = (int) $value; } + /** + * @param array $values + * + * @throws \Doctrine\DBAL\DBALException + */ + public function setPageResultConfiguration($values) + { + $pageConfig = api_get_configuration_value('allow_quiz_results_page_config'); + if ($pageConfig) { + $params = [ + 'hide_expected_answer' => isset($values['hide_expected_answer']) ? $values['hide_expected_answer'] : '', + 'hide_question_score' => isset($values['hide_question_score']) ? $values['hide_question_score'] : '', + 'hide_total_score' => isset($values['hide_total_score']) ? $values['hide_total_score'] : '' + ]; + $type = Type::getType('array'); + $platform = Database::getManager()->getConnection()->getDatabasePlatform(); + $this->pageResultConfiguration = $type->convertToDatabaseValue($params, $platform); + } + } + + /** + * @param array $defaults + */ + public function setPageResultConfigurationDefaults(&$defaults) + { + $configuration = $this->getPageResultConfiguration(); + if (!empty($configuration) && !empty($defaults)) { + $defaults = array_merge($defaults, $configuration); + } + } + + /** + * @return array + */ + public function getPageResultConfiguration() + { + $pageConfig = api_get_configuration_value('allow_quiz_results_page_config'); + if ($pageConfig) { + /*$params = [ + 'hide_expected_answer' => isset($values['hide_expected_answer']) ? $values['hide_expected_answer'] : '', + 'hide_question_score' => isset($values['hide_question_score']) ? $values['hide_question_score'] : '', + 'hide_total_score' => isset($values['hide_total_score']) ? $values['hide_total_score'] : '' + ];*/ + $type = Type::getType('array'); + $platform = Database::getManager()->getConnection()->getDatabasePlatform(); + $result = $type->convertToPHPValue($this->pageResultConfiguration, $platform); + + return $result; + } + + return []; + } + + /** + * @param string $attribute + * + * @return mixed|null + */ + public function getPageConfigurationAttribute($attribute) + { + $result = $this->getPageResultConfiguration(); + + if (!empty($result)) { + $value = isset($result[$attribute]) ? $result[$attribute] : null; + return $value; + } + + return null; + } + /** * @param bool $showPreviousButton * @@ -7917,6 +8057,26 @@ class Exercise return api_get_configuration_value('show_exercise_expected_choice'); } + /** + * @return bool + */ + public function showExpectedChoiceColumn() + { + if (!in_array($this->results_disabled, [ + RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER + ]) + ) { + $hide = (int) $this->getPageConfigurationAttribute('hide_expected_answer'); + if ($hide === 1) { + return false; + } + + return true; + } + + return false; + } + /** * @param string $class * @param string $scoreLabel @@ -7927,6 +8087,11 @@ class Exercise */ public function getQuestionRibbon($class, $scoreLabel, $result, $array) { + $hide = (int) $this->getPageConfigurationAttribute('hide_question_score'); + if ($hide === 1) { + return ''; + } + if ($this->showExpectedChoice()) { $html = null; $hideLabel = api_get_configuration_value('exercise_hide_label'); @@ -8072,6 +8237,8 @@ class Exercise $courseId = $courseInfo['real_id']; $sessionId = (int) $sessionId; + $exerciseId = (int) $exerciseId; + $result = $this->read($exerciseId); if (empty($result)) { @@ -8081,7 +8248,7 @@ class Exercise $statusToFilter = empty($sessionId) ? STUDENT : 0; $studentList = CourseManager::get_user_list_from_course_code( - api_get_course_id(), + $courseInfo['code'], $sessionId, null, null, @@ -8164,18 +8331,27 @@ class Exercise $em = Database::getManager(); $links = AbstractLink::getGradebookLinksFromItem( - $this->selectId(), + $this->id, LINK_EXERCISE, - api_get_course_id(), - api_get_session_id() + $courseInfo['code'], + $sessionId ); + if (empty($links)) { + $links = AbstractLink::getGradebookLinksFromItem( + $this->iId, + LINK_EXERCISE, + $courseInfo['code'], + $sessionId + ); + } + if (!empty($links)) { $repo = $em->getRepository('ChamiloCoreBundle:GradebookLink'); foreach ($links as $link) { $linkId = $link['id']; - /** @var \Chamilo\CoreBundle\Entity\GradebookLink $exerciseLink */ + /** @var GradebookLink $exerciseLink */ $exerciseLink = $repo->find($linkId); if ($exerciseLink) { $exerciseLink @@ -9640,7 +9816,7 @@ class Exercise ['id' => 'result_disabled_2', 'onclick' => 'check_results_disabled()'] ); - if ($this->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) { + if (in_array($this->getFeedbackType(), [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP])) { $group = $form->addGroup( $resultDisabledGroup, null, diff --git a/main/exercise/exercise_admin.php b/main/exercise/exercise_admin.php index d1ef916bf5..8b4bd361de 100755 --- a/main/exercise/exercise_admin.php +++ b/main/exercise/exercise_admin.php @@ -185,7 +185,6 @@ if ($form->validate()) { Display::display_header($nameTools, get_lang('Exercise')); echo '
'; - if ($objExercise->id != 0) { echo ''. Display::return_icon('back.png', get_lang('GoBackToQuestionList'), '', ICON_SIZE_MEDIUM).''; @@ -199,7 +198,7 @@ if ($form->validate()) { } $lp_id = (int) $lp_id; echo "". - Display::return_icon('back.png', get_lang("BackTo").' '.get_lang("LearningPaths"), '', ICON_SIZE_MEDIUM).""; + Display::return_icon('back.png', get_lang("BackTo").' '.get_lang('LearningPaths'), '', ICON_SIZE_MEDIUM).""; } else { echo ''. Display::return_icon('back.png', get_lang('BackToExercisesList'), '', ICON_SIZE_MEDIUM). @@ -208,11 +207,11 @@ if ($form->validate()) { } echo '
'; - if ($objExercise->feedback_type == 1) { + if (in_array($objExercise->getFeedbackType(), [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP])) { echo Display::return_message(get_lang('DirectFeedbackCantModifyTypeQuestion')); } - if (api_get_setting('search_enabled') == 'true' && + if (api_get_setting('search_enabled') === 'true' && !extension_loaded('xapian') ) { echo Display::return_message(get_lang('SearchXapianModuleNotInstalled'), 'error'); diff --git a/main/exercise/exercise_result.php b/main/exercise/exercise_result.php index ed3b8a371a..ace839b80a 100755 --- a/main/exercise/exercise_result.php +++ b/main/exercise/exercise_result.php @@ -100,7 +100,7 @@ if (api_is_course_admin() && !in_array($origin, ['learnpath', 'embeddable'])) { echo ''; } -$feedback_type = $objExercise->feedback_type; +$feedback_type = $objExercise->getFeedbackType(); $exercise_stat_info = $objExercise->get_stat_track_exercise_info_by_exe_id($exe_id); if (!empty($exercise_stat_info['data_tracking'])) { @@ -222,7 +222,7 @@ if (!in_array($origin, ['learnpath', 'embeddable'])) { Session::erase('duration_time'); } Display::display_footer(); -} elseif ($origin == 'embeddable') { +} elseif ($origin === 'embeddable') { if (api_is_allowed_to_session_edit()) { Session::erase('objExercise'); Session::erase('exe_id'); @@ -232,14 +232,12 @@ if (!in_array($origin, ['learnpath', 'embeddable'])) { } Session::write('attempt_remaining', $remainingMessage); - showEmbeddableFinishButton(); - Display::display_reduced_footer(); } else { $lp_mode = Session::read('lp_mode'); - $url = '../lp/lp_controller.php?'.api_get_cidreq().'&action=view&lp_id='.$learnpath_id.'&lp_item_id='.$learnpath_item_id.'&exeId='.$exercise_stat_info['exe_id'].'&fb_type='.$objExercise->feedback_type.'#atoc_'.$learnpath_item_id; - $href = $lp_mode == 'fullscreen' ? ' window.opener.location.href="'.$url.'" ' : ' top.location.href="'.$url.'"'; + $url = '../lp/lp_controller.php?'.api_get_cidreq().'&action=view&lp_id='.$learnpath_id.'&lp_item_id='.$learnpath_item_id.'&exeId='.$exercise_stat_info['exe_id'].'&fb_type='.$objExercise->getFeedbackType().'#atoc_'.$learnpath_item_id; + $href = $lp_mode === 'fullscreen' ? ' window.opener.location.href="'.$url.'" ' : ' top.location.href="'.$url.'"'; if (api_is_allowed_to_session_edit()) { Session::erase('objExercise'); diff --git a/main/exercise/exercise_show.php b/main/exercise/exercise_show.php index 061de86dac..b80dec0a6b 100755 --- a/main/exercise/exercise_show.php +++ b/main/exercise/exercise_show.php @@ -127,7 +127,7 @@ if (empty($objExercise)) { $objExercise = new Exercise(); $objExercise->read($exercise_id); } -$feedback_type = $objExercise->feedback_type; +$feedback_type = $objExercise->getFeedbackType(); // Only users can see their own results if (!$is_allowedToEdit) { @@ -358,7 +358,7 @@ if (!empty($track_exercise_info['data_tracking'])) { } // Display the text when finished message if we are on a LP #4227 -$end_of_message = $objExercise->selectTextWhenFinished(); +$end_of_message = $objExercise->getTextWhenFinished(); if (!empty($end_of_message) && ($origin === 'learnpath')) { echo Display::return_message($end_of_message, 'normal', false); echo "
 
"; diff --git a/main/exercise/exercise_submit.php b/main/exercise/exercise_submit.php index d8157d8077..d899e5a9f5 100755 --- a/main/exercise/exercise_submit.php +++ b/main/exercise/exercise_submit.php @@ -109,7 +109,6 @@ $logInfo = [ ]; Event::registerLog($logInfo); -// Error message $error = ''; $exercise_attempt_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); @@ -667,7 +666,7 @@ if ($formSent && isset($_POST)) { // stores the user answer into the array $exerciseResult[$key] = $choice[$key]; //saving each question - if ($objExercise->feedback_type != EXERCISE_FEEDBACK_TYPE_DIRECT) { + if (!in_array($objExercise->getFeedbackType(), [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP])) { $nro_question = $current_question; // - 1; $questionId = $key; // gets the student choice for this question @@ -1395,7 +1394,7 @@ if (!empty($error)) { $i++; continue; } else { - if ($objExercise->feedback_type != EXERCISE_FEEDBACK_TYPE_DIRECT) { + if (!in_array($objExercise->getFeedbackType(), [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP])) { // if the user has already answered this question if (isset($exerciseResult[$questionId])) { // construction of the Question object @@ -1414,11 +1413,23 @@ if (!empty($error)) { $user_choice = null; if (isset($attempt_list[$questionId])) { $user_choice = $attempt_list[$questionId]; - } elseif ($objExercise->saveCorrectAnswers) { - $correctAnswers = $objExercise->getCorrectAnswersInAllAttempts( - $learnpath_id, - $learnpath_item_id - ); + } elseif ($objExercise->getSaveCorrectAnswers()) { + $correctAnswers = []; + switch ($objExercise->getSaveCorrectAnswers()) { + case 1: + $correctAnswers = $objExercise->getCorrectAnswersInAllAttempts( + $learnpath_id, + $learnpath_item_id + ); + break; + case 2: + $correctAnswers = $objExercise->getAnswersInAllAttempts( + $learnpath_id, + $learnpath_item_id, + false + ); + break; + } if (isset($correctAnswers[$questionId])) { $user_choice = $correctAnswers[$questionId]; @@ -1426,8 +1437,7 @@ if (!empty($error)) { } $remind_highlight = ''; - - //Hides questions when reviewing a ALL_ON_ONE_PAGE exercise see #4542 no_remind_highlight class hide with jquery + // Hides questions when reviewing a ALL_ON_ONE_PAGE exercise see #4542 no_remind_highlight class hide with jquery if ($objExercise->type == ALL_ON_ONE_PAGE && isset($_GET['reminder']) && $_GET['reminder'] == 2 ) { diff --git a/main/exercise/exercise_submit_modal.php b/main/exercise/exercise_submit_modal.php index b17cefc179..1cc6825f83 100755 --- a/main/exercise/exercise_submit_modal.php +++ b/main/exercise/exercise_submit_modal.php @@ -9,13 +9,10 @@ use ChamiloSession as Session; * @author Julio Montoya */ require_once __DIR__.'/../inc/global.inc.php'; -api_protect_course_script(false); -require_once api_get_path(LIBRARY_PATH).'geometry.lib.php'; - -//Display::display_reduced_header(); +api_protect_course_script(); -echo '
'; +require_once api_get_path(LIBRARY_PATH).'geometry.lib.php'; $message = null; $dbg_local = 0; @@ -34,23 +31,30 @@ $origin = api_get_origin(); // if origin is learnpath $learnpath_id = 0; if (isset($_REQUEST['learnpath_id'])) { - $learnpath_id = intval($_REQUEST['learnpath_id']); + $learnpath_id = (int) $_REQUEST['learnpath_id']; } $learnpath_item_id = 0; if (isset($_REQUEST['learnpath_item_id'])) { - $learnpath_item_id = intval($_REQUEST['learnpath_item_id']); + $learnpath_item_id = (int) $_REQUEST['learnpath_item_id']; +} + +/** @var Exercise $objExercise */ +$objExercise = Session::read('objExercise'); + +if (empty($objExercise)) { + api_not_allowed(); } $_SESSION['hotspot_coord'] = []; -$newquestionList = Session::read('newquestionList', []); +$newQuestionList = Session::read('newquestionList', []); $questionList = Session::read('questionList'); -$exerciseId = intval($_GET['exerciseId']); -$exerciseType = intval($_GET['exerciseType']); -$questionNum = intval($_GET['num']); -$nbrQuestions = isset($_GET['nbrQuestions']) ? intval($_GET['nbrQuestions']) : null; +$exerciseId = (int) $_GET['exerciseId']; +$exerciseType = (int) $_GET['exerciseType']; +$questionNum = (int) $_GET['num']; +$nbrQuestions = isset($_GET['nbrQuestions']) ? (int) $_GET['nbrQuestions'] : null; -//clean extra session variables +// Clean extra session variables Session::erase('objExerciseExtra'.$exerciseId); Session::erase('exerciseResultExtra'.$exerciseId); Session::erase('questionListExtra'.$exerciseId); @@ -69,13 +73,13 @@ if (isset($_GET['hotspot'])) { } } -$choice_value = ''; $user_array = substr($user_array, 0, -1); - +$choice_value = ''; if (isset($_GET['choice'])) { - $choice_value = intval($_GET['choice']); + $choice_value = (int) $_GET['choice']; } +echo '
'; // Getting the options by js if (empty($choice_value)) { echo "'; -if ($links != '') { - echo '

'.get_lang('Feedback').'

'; +if (!empty($links)) { + //echo '

'.get_lang('Feedback').'

'; if ($answerType == HOT_SPOT_DELINEATION) { if ($organs_at_risk_hit > 0) { - //$message='

'.get_lang('YourDelineation').'

'; - //$message.=$table_resume; $message .= '
'.get_lang('ResultIs').' '.get_lang('Unacceptable').'
'; - //if ($wrong_results) { } $message .= '

'.get_lang('OARHit').'

'; $message .= '

'.$comment.'

'; } else { @@ -595,16 +576,17 @@ if ($links != '') { $message .= '
'.get_lang('ResultIs').' '.$result_comment.'
'; $message .= '

'.$comment.'

'; } + echo '
'; echo $message; } else { echo '

'.$comment.'

'; } - echo '

'.$links.'

'; + echo '
'.$links.'
'; echo '
'; Session::write('hot_spot_result', $message); - $_SESSION['hotspot_delineation_result'][$exerciseId][$questionid] = [$message, $exerciseResult[$questionid]]; - //reseting the exerciseResult variable + $_SESSION['hotspot_delineation_result'][$exerciseId][$questionId] = [$message, $exerciseResult[$questionId]]; + // Resetting the exerciseResult variable Session::write('exerciseResult', $exerciseResult); //save this variables just in case the exercise loads an LP with other exercise @@ -615,10 +597,7 @@ if ($links != '') { $questionNum++; echo ''; } echo '
'; - -//Display::display_footer(); diff --git a/main/exercise/global_multiple_answer.class.php b/main/exercise/global_multiple_answer.class.php index e702b590f2..0aff5c7fb6 100755 --- a/main/exercise/global_multiple_answer.class.php +++ b/main/exercise/global_multiple_answer.class.php @@ -266,13 +266,11 @@ class GlobalMultipleAnswer extends Question $header = parent::return_header($exercise, $counter, $score); $header .= '
'.get_lang('Choice').''.get_lang('ExpectedChoice').''.get_lang('Answer').''.get_lang('Choice').''.get_lang('ExpectedChoice').''.get_lang('Answer').''.get_lang('Status').''.get_lang('Comment').'
'.get_lang('Answer').''.get_lang('YourChoice').''.get_lang('ExpectedChoice').''.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] - ); + if ($this->showExpectedChoiceColumn()) { + echo ''; + 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.''; 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;'] - ); + if ($this->showExpectedChoiceColumn()) { + echo ''; + echo Display::span( + $real_list[$i_answer_correct_answer], + ['style' => 'color: #008000; font-weight: bold;'] + ); + echo '
'; - if (!in_array($exercise->results_disabled, [ - RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER, - //RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING, - ]) - ) { + if (!in_array($exercise->results_disabled, [RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER])) { $header .= ''; - $header .= ''; + if ($exercise->showExpectedChoiceColumn()) { + $header .= ''; + } } $header .= ''; diff --git a/main/exercise/hotspot_admin.inc.php b/main/exercise/hotspot_admin.inc.php index 9db1f7b371..0eaef6034a 100755 --- a/main/exercise/hotspot_admin.inc.php +++ b/main/exercise/hotspot_admin.inc.php @@ -159,9 +159,9 @@ if ($submitAnswers || $buttonBack) { } $questionWeighting = $nbrGoodAnswers = 0; - $select_question = $_POST['select_question']; + $select_question = isset($_POST['select_question']) ? $_POST['select_question'] : null; $try = isset($_POST['try']) ? $_POST['try'] : []; - $url = $_POST['url']; + $url = isset($_POST['url']) ? $_POST['url'] : ''; $destination = []; $threadhold1 = $_POST['threadhold1']; @@ -169,10 +169,6 @@ if ($submitAnswers || $buttonBack) { $threadhold3 = $_POST['threadhold3']; for ($i = 1; $i <= $nbrAnswers; $i++) { - if ($debug > 0) { - echo str_repeat(' ', 4).'$answerType is HOT_SPOT'."
\n"; - } - $reponse[$i] = trim($reponse[$i]); $comment[$i] = trim($comment[$i]); $weighting[$i] = $weighting[$i]; @@ -180,19 +176,19 @@ if ($submitAnswers || $buttonBack) { if (empty($threadhold1[$i])) { $threadhold1_str = 0; } else { - $threadhold1_str = intval($threadhold1[$i]); + $threadhold1_str = (int) $threadhold1[$i]; } if (empty($threadhold2[$i])) { $threadhold2_str = 0; } else { - $threadhold2_str = intval($threadhold2[$i]); + $threadhold2_str = (int) $threadhold2[$i]; } if (empty($threadhold3[$i])) { $threadhold3_str = 0; } else { - $threadhold3_str = intval($threadhold3[$i]); + $threadhold3_str = (int) $threadhold3[$i]; } $threadhold_total = $threadhold1_str.';'.$threadhold2_str.';'.$threadhold3_str; @@ -209,9 +205,8 @@ if ($submitAnswers || $buttonBack) { $lp_str = $lp[$i]; } - if ($url[$i] == '') { - $url_str = ''; - } else { + $url_str = ''; + if (isset($url[$i]) && !empty($url[$i])) { $url_str = $url[$i]; } @@ -245,14 +240,14 @@ if ($submitAnswers || $buttonBack) { $objAnswer->cancel(); break; } - } // end for() + } - //now the noerror section - $selectQuestionNoError = Security::remove_XSS($_POST['select_question_noerror']); - $lp_noerror = Security::remove_XSS($_POST['lp_noerror']); + // now the noerror section + $selectQuestionNoError = isset($_POST['select_question_noerror']) ? Security::remove_XSS($_POST['select_question_noerror']) : null; + $lp_noerror = isset($_POST['lp_noerror']) ? Security::remove_XSS($_POST['lp_noerror']) : ''; $try_noerror = isset($_POST['try_noerror']) ? Security::remove_XSS($_POST['try_noerror']) : null; - $url_noerror = Security::remove_XSS($_POST['url_noerror']); - $comment_noerror = Security::remove_XSS($_POST['comment_noerror']); + $url_noerror = isset($_POST['url_noerror']) ? Security::remove_XSS($_POST['url_noerror']) : null; + $comment_noerror = isset($_POST['comment_noerror']) ? Security::remove_XSS($_POST['comment_noerror']) : null; $threadhold_total = '0;0;0'; if ($try_noerror == 'on') { @@ -385,7 +380,7 @@ if (isset($modifyAnswers)) { for ($i = 1; $i <= $nbrAnswers; $i++) { $reponse[$i] = $objAnswer->selectAnswer($i); - if ($objExercise->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { + if ($objExercise->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { $comment[$i] = $objAnswer->selectComment($i); } @@ -436,7 +431,7 @@ if (isset($modifyAnswers)) { $_SESSION['tmp_answers'] = []; $_SESSION['tmp_answers']['answer'] = $reponse; - if ($objExercise->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { + if ($objExercise->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { $_SESSION['tmp_answers']['comment'] = $comment; } @@ -474,7 +469,7 @@ if (isset($modifyAnswers)) { $nbrAnswers--; // Remove the last answer $tmp = array_pop($_SESSION['tmp_answers']['answer']); - if ($objExercise->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { + if ($objExercise->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { $tmp = array_pop($_SESSION['tmp_answers']['comment']); } $tmp = array_pop($_SESSION['tmp_answers']['weighting']); @@ -494,7 +489,7 @@ if (isset($modifyAnswers)) { // Add a new answer $_SESSION['tmp_answers']['answer'][] = ''; - if ($objExercise->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { + if ($objExercise->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { $_SESSION['tmp_answers']['comment'][] = ''; } $_SESSION['tmp_answers']['weighting'][] = '1'; @@ -615,7 +610,7 @@ if (isset($modifyAnswers)) {
selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) { + if ($objExercise->getFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) { echo ''; if ($answerType == HOT_SPOT_DELINEATION) { echo ''; @@ -736,7 +731,7 @@ if (isset($modifyAnswers)) { - selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) { + getFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) { ?> - selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) { + getFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) { ?>
'.get_lang('Choice').''.get_lang('ExpectedChoice').''.get_lang('ExpectedChoice').''.get_lang('Answer').'  * '.get_lang('Comment').''.get_lang('Scenario').'
@@ -795,7 +790,7 @@ if (isset($modifyAnswers)) { name="comment[]" style="width: 100%">
@@ -850,7 +845,7 @@ if (isset($modifyAnswers)) { - selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) { + getFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) { ?> - selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) { + getFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) { ?> @@ -1049,7 +1044,7 @@ if (isset($modifyAnswers)) { - selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) { + getFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) { ?> '; - $header .= ''; + //if ($exercise->showExpectedChoiceColumn()) { + //$header .= ''; + //} } if ($exercise->showExpectedChoice()) { $header .= ''; } else { - $header .= ''; + if ($exercise->showExpectedChoiceColumn()) { + $header .= ''; + } } $header .= ''; diff --git a/main/exercise/multiple_answer.class.php b/main/exercise/multiple_answer.class.php index 94b6875c3e..98233616e4 100755 --- a/main/exercise/multiple_answer.class.php +++ b/main/exercise/multiple_answer.class.php @@ -235,11 +235,8 @@ class MultipleAnswer extends Question $header .= '
  * ]" value=""/> - selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) { + getFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) { ?>
@@ -1029,7 +1024,7 @@ if (isset($modifyAnswers)) { ?>
diff --git a/main/exercise/matching.class.php b/main/exercise/matching.class.php index 34e4af96f5..cb7c6753c5 100755 --- a/main/exercise/matching.class.php +++ b/main/exercise/matching.class.php @@ -292,13 +292,17 @@ class Matching extends Question ]) ) { $header .= '
'.get_lang('Choice').''.get_lang('ExpectedChoice').''.get_lang('ExpectedChoice').''.get_lang('Status').''.get_lang('CorrespondsTo').''.get_lang('CorrespondsTo').'
'; $header .= ''; - if (!in_array($exercise->results_disabled, [ - RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER, - //RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING, - ]) - ) { + + if ($exercise->showExpectedChoiceColumn()) { $header .= ''; } diff --git a/main/exercise/multiple_answer_combination.class.php b/main/exercise/multiple_answer_combination.class.php index 92be1521fe..52ada36d3f 100755 --- a/main/exercise/multiple_answer_combination.class.php +++ b/main/exercise/multiple_answer_combination.class.php @@ -233,12 +233,13 @@ class MultipleAnswerCombination extends Question $header .= '
'.get_lang('Choice').''.get_lang('ExpectedChoice').'
'; if (!in_array($exercise->results_disabled, [ - RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER, - //RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING, + RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER ]) ) { $header .= ''; - $header .= ''; + if ($exercise->showExpectedChoiceColumn()) { + $header .= ''; + } } $header .= ''; diff --git a/main/exercise/multiple_answer_true_false.class.php b/main/exercise/multiple_answer_true_false.class.php index 0b17b76687..4e37e9eefe 100755 --- a/main/exercise/multiple_answer_true_false.class.php +++ b/main/exercise/multiple_answer_true_false.class.php @@ -52,7 +52,7 @@ class MultipleAnswerTrueFalse extends Question $html .= ''; // show column comment when feedback is enable - if ($obj_ex->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { + if ($obj_ex->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { $html .= ''; } @@ -146,7 +146,7 @@ class MultipleAnswerTrueFalse extends Question ); // show comment when feedback is enable - if ($obj_ex->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { + if ($obj_ex->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { $form->addElement( 'html_editor', 'comment['.$i.']', @@ -314,12 +314,13 @@ class MultipleAnswerTrueFalse extends Question $header .= '
'.get_lang('Choice').''.get_lang('ExpectedChoice').''.get_lang('ExpectedChoice').''.get_lang('Answer').''.get_lang('Answer').''.get_lang('Comment').'
'; if (!in_array($exercise->results_disabled, [ - RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER, - //RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING, + RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER ]) ) { $header .= ''; - $header .= ''; + if ($exercise->showExpectedChoiceColumn()) { + $header .= ''; + } } $header .= ''; @@ -327,7 +328,7 @@ class MultipleAnswerTrueFalse extends Question if ($exercise->showExpectedChoice()) { $header .= ''; } - if ($exercise->feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM || + if ($exercise->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM || in_array( $exercise->results_disabled, [ diff --git a/main/exercise/overview.php b/main/exercise/overview.php index 772bc58223..2a62b3edbf 100755 --- a/main/exercise/overview.php +++ b/main/exercise/overview.php @@ -286,7 +286,7 @@ if (!empty($attempts)) { ] ) || ( $objExercise->results_disabled == RESULT_DISABLE_SHOW_SCORE_ONLY && - $objExercise->feedback_type == EXERCISE_FEEDBACK_TYPE_END + $objExercise->getFeedbackType() == EXERCISE_FEEDBACK_TYPE_END ) ) { if ($blockShowAnswers && @@ -355,7 +355,7 @@ if (!empty($attempts)) { $header_names = [get_lang('Attempt'), get_lang('StartDate'), get_lang('IP')]; break; case RESULT_DISABLE_SHOW_SCORE_ONLY: - if ($objExercise->feedback_type != EXERCISE_FEEDBACK_TYPE_END) { + if ($objExercise->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_END) { $header_names = [get_lang('Attempt'), get_lang('StartDate'), get_lang('IP'), get_lang('Score')]; } else { $header_names = [ diff --git a/main/exercise/question.class.php b/main/exercise/question.class.php index 0b67809977..5fb2de3a1d 100755 --- a/main/exercise/question.class.php +++ b/main/exercise/question.class.php @@ -1816,17 +1816,17 @@ abstract class Question */ public static function displayTypeMenu($objExercise) { - $feedback_type = $objExercise->feedback_type; + $feedbackType = $objExercise->getFeedbackType(); $exerciseId = $objExercise->id; // 1. by default we show all the question types $question_type_custom_list = self::get_question_type_list(); - if (!isset($feedback_type)) { - $feedback_type = 0; + if (!isset($feedbackType)) { + $feedbackType = 0; } - if ($feedback_type == 1) { + if (in_array($feedbackType, [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP])) { //2. but if it is a feedback DIRECT we only show the UNIQUE_ANSWER type that is currently available $question_type_custom_list = [ UNIQUE_ANSWER => self::$questionTypes[UNIQUE_ANSWER], @@ -1875,7 +1875,7 @@ abstract class Question ICON_SIZE_BIG ); } else { - if ($feedback_type == 1) { + if (in_array($feedbackType, [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP])) { echo $url = ""; } else { echo $url = ''; @@ -2403,7 +2403,7 @@ abstract class Question { return in_array($this->type, $this->questionTypeWithFeedback) && - $exercise->feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM; + $exercise->getFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM; } /** diff --git a/main/exercise/question_list_admin.inc.php b/main/exercise/question_list_admin.inc.php index b1460c3ad4..8e48d46f8c 100755 --- a/main/exercise/question_list_admin.inc.php +++ b/main/exercise/question_list_admin.inc.php @@ -43,7 +43,6 @@ $ajax_url = api_get_path(WEB_AJAX_PATH).'exercise.ajax.php?'.api_get_cidreq().'&

- '; diff --git a/main/exercise/question_pool.php b/main/exercise/question_pool.php index 2ea1b0b12e..a566870aec 100755 --- a/main/exercise/question_pool.php +++ b/main/exercise/question_pool.php @@ -478,7 +478,10 @@ $new_question_list = []; $new_question_list['-1'] = get_lang('All'); if (!empty($_course)) { foreach ($question_list as $key => $item) { - if ($objExercise->feedback_type == EXERCISE_FEEDBACK_TYPE_DIRECT) { + if (in_array( + $objExercise->getFeedbackType(), + [EXERCISE_FEEDBACK_TYPE_DIRECT, EXERCISE_FEEDBACK_TYPE_POPUP] + )) { if (!in_array($key, [HOT_SPOT_DELINEATION, UNIQUE_ANSWER])) { continue; } diff --git a/main/exercise/unique_answer.class.php b/main/exercise/unique_answer.class.php index 54021c66c4..6d633bb3dd 100755 --- a/main/exercise/unique_answer.class.php +++ b/main/exercise/unique_answer.class.php @@ -58,12 +58,18 @@ class UniqueAnswer extends Question */ $feedback_title = ''; - if ($obj_ex->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) { - //Scenario - $comment_title = '
'; - $feedback_title = ''; - } else { - $comment_title = ''; + switch ($obj_ex->getFeedbackType()) { + case EXERCISE_FEEDBACK_TYPE_DIRECT: + // Scenario + $comment_title = ''; + $feedback_title = ''; + break; + case EXERCISE_FEEDBACK_TYPE_POPUP: + $comment_title = ''; + break; + default: + $comment_title = ''; + break; } $html = '
'.get_lang('Choice').''.get_lang('ExpectedChoice').''.get_lang('ExpectedChoice').''.get_lang('Answer').''.get_lang('Status').''.get_lang('Comment').''.get_lang('Scenario').''.get_lang('Comment').''.get_lang('Comment').''.get_lang('Scenario').''.get_lang('Comment').''.get_lang('Comment').'
@@ -218,52 +224,14 @@ class UniqueAnswer extends Question 'required' ); - if ($obj_ex->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) { - $form->addHtmlEditor( - 'comment['.$i.']', - null, - null, - false, - $editor_config - ); - // Direct feedback - //Adding extra feedback fields - $group = []; - $group['try'.$i] = $form->createElement( - 'checkbox', - 'try'.$i, - null, - get_lang('TryAgain') - ); - $group['lp'.$i] = $form->createElement( - 'select', - 'lp'.$i, - get_lang('SeeTheory').': ', - $select_lp_id - ); - $group['destination'.$i] = $form->createElement( - 'select', - 'destination'.$i, - get_lang('GoToQuestion').': ', - $select_question - ); - $group['url'.$i] = $form->createElement( - 'text', - 'url'.$i, - get_lang('Other').': ', - [ - 'class' => 'col-md-2', - 'placeholder' => get_lang('Other'), - ] - ); - $form->addGroup($group, 'scenario'); - - $renderer->setElementTemplate( - ''); @@ -314,6 +282,59 @@ class UniqueAnswer extends Question $form->setConstants(['nb_answers' => $nb_answers]); } + public function setDirectOptions($i, FormValidator $form, $renderer, $select_lp_id, $select_question) + { + $editor_config = [ + 'ToolbarSet' => 'TestProposedAnswer', + 'Width' => '100%', + 'Height' => '125', + ]; + + $form->addHtmlEditor( + 'comment['.$i.']', + null, + null, + false, + $editor_config + ); + // Direct feedback + //Adding extra feedback fields + $group = []; + $group['try'.$i] = $form->createElement( + 'checkbox', + 'try'.$i, + null, + get_lang('TryAgain') + ); + $group['lp'.$i] = $form->createElement( + 'select', + 'lp'.$i, + get_lang('SeeTheory').': ', + $select_lp_id + ); + $group['destination'.$i] = $form->createElement( + 'select', + 'destination'.$i, + get_lang('GoToQuestion').': ', + $select_question + ); + $group['url'.$i] = $form->createElement( + 'text', + 'url'.$i, + get_lang('Other').': ', + [ + 'class' => 'col-md-2', + 'placeholder' => get_lang('Other'), + ] + ); + $form->addGroup($group, 'scenario'); + + $renderer->setElementTemplate( + '
{error}
{element}', - 'scenario' - ); - } else { - $form->addHtmlEditor('comment['.$i.']', null, null, false, $editor_config); + switch ($obj_ex->getFeedbackType()) { + case EXERCISE_FEEDBACK_TYPE_DIRECT: + $this->setDirectOptions($i, $form, $renderer, $select_lp_id, $select_question); + break; + case EXERCISE_FEEDBACK_TYPE_POPUP: + default: + $form->addHtmlEditor('comment['.$i.']', null, null, false, $editor_config); + break; } $form->addText('weighting['.$i.']', null, null, ['value' => '0']); $form->addHtml('
{error}
{element}', + 'scenario' + ); + } + /** * {@inheritdoc} */ @@ -414,11 +435,7 @@ class UniqueAnswer extends Question $header .= ''; $header .= ''; - if (!in_array($exercise->results_disabled, [ - RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER, - //RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING, - ]) - ) { + if ($exercise->showExpectedChoiceColumn()) { $header .= ''; } diff --git a/main/exercise/unique_answer_no_option.class.php b/main/exercise/unique_answer_no_option.class.php index 8d8fb56be4..bd5391dd0e 100755 --- a/main/exercise/unique_answer_no_option.class.php +++ b/main/exercise/unique_answer_no_option.class.php @@ -54,7 +54,7 @@ class UniqueAnswerNoOption extends Question */ $feedback_title = ''; - if ($obj_ex->selectFeedbackType() == 1) { + if ($obj_ex->getFeedbackType() == 1) { $editor_config['Width'] = '250'; $editor_config['Height'] = '110'; $comment_title = ''; @@ -405,12 +405,13 @@ class UniqueAnswerNoOption extends Question $header .= '
'.get_lang('Choice').''.get_lang('ExpectedChoice').''.get_lang('Comment').'
'; if (!in_array($exercise->results_disabled, [ - RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER, - //RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING, + RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER ]) ) { $header .= ''; - $header .= ''; + if ($exercise->showExpectedChoiceColumn()) { + $header .= ''; + } } $header .= ''; if ($exercise->showExpectedChoice()) { diff --git a/main/gradebook/gradebook_flatview.php b/main/gradebook/gradebook_flatview.php index 5fcdeb1a0d..203750c326 100755 --- a/main/gradebook/gradebook_flatview.php +++ b/main/gradebook/gradebook_flatview.php @@ -45,19 +45,17 @@ if ($showlink == '0' && $showeval == '0') { $cat = Category::load($categoryId); $userId = isset($_GET['userid']) ? (int) $_GET['userid'] : 0; +$alleval = null; if ($showeval) { $alleval = $cat[0]->get_evaluations($userId, true); -} else { - $alleval = null; } +$alllinks = null; if ($showlink) { $alllinks = $cat[0]->get_links($userId, true); -} else { - $alllinks = null; } -if (isset($export_flatview_form) && !$file_type == 'pdf') { +if (isset($export_flatview_form) && !$file_type === 'pdf') { Display::addFlash( Display::return_message( $export_flatview_form->toHtml(), @@ -76,7 +74,7 @@ $simple_search_form = new UserForm( null, 'simple_search_form', null, - api_get_self().'?selectcat='.$category_id + api_get_self().'?selectcat='.$category_id.'&'.api_get_cidreq() ); $values = $simple_search_form->exportValues(); @@ -91,10 +89,9 @@ if ($simple_search_form->validate() && empty($keyword)) { if (!empty($keyword)) { $users = GradebookUtils::find_students($keyword); } else { + $users = null; if (isset($alleval) && isset($alllinks)) { $users = GradebookUtils::get_all_users($alleval, $alllinks); - } else { - $users = null; } } $offset = isset($_GET['offset']) ? $_GET['offset'] : '0'; @@ -176,7 +173,7 @@ if (isset($_GET['exportpdf'])) { if ($export_pdf_form->validate()) { $params = $export_pdf_form->exportValues(); - Display::set_header(null, false, false); + Display::set_header(); $params['join_firstname_lastname'] = true; $params['show_official_code'] = true; $params['export_pdf'] = true; @@ -214,7 +211,7 @@ if (isset($_GET['print'])) { } if (!empty($_GET['export_report']) && - $_GET['export_report'] == 'export_report' + $_GET['export_report'] === 'export_report' ) { if (api_is_platform_admin() || api_is_course_admin() || api_is_session_general_coach() || $isDrhOfCourse) { $user_id = null; diff --git a/main/gradebook/index.php b/main/gradebook/index.php index 7d70d9b0d6..bfafe4407a 100755 --- a/main/gradebook/index.php +++ b/main/gradebook/index.php @@ -39,11 +39,21 @@ switch ($action) { if (!empty($itemId)) { $link = LinkFactory::create(LINK_EXERCISE); $links = $link::load($itemId); + + $exercise = new Exercise(api_get_course_int_id()); /** @var ExerciseLink $link */ foreach ($links as $link) { - $exercise = new Exercise(api_get_course_int_id()); - $exercise->read($link->get_ref_id()); - $exercise->generateStats($link->get_ref_id(), api_get_course_info(), api_get_session_id()); + $exerciseId = $link->get_ref_id(); + $data = $link->get_exercise_data(); + if (empty($data)) { + continue; + } + + $exerciseId = $data['id']; + $result = $exercise->read($exerciseId); + if ($result) { + $exercise->generateStats($exerciseId, api_get_course_info(), api_get_session_id()); + } } Display::addFlash(Display::return_message(get_lang('Updated'))); } diff --git a/main/gradebook/lib/be/category.class.php b/main/gradebook/lib/be/category.class.php index 0484e40f3a..f79c9c6fe4 100755 --- a/main/gradebook/lib/be/category.class.php +++ b/main/gradebook/lib/be/category.class.php @@ -2525,7 +2525,6 @@ class Category implements GradebookItem Session::write('gradebook_dest', $url); } - /** * @return int */ diff --git a/main/gradebook/lib/be/exerciselink.class.php b/main/gradebook/lib/be/exerciselink.class.php index fd72dfb3da..1c9778fb0b 100755 --- a/main/gradebook/lib/be/exerciselink.class.php +++ b/main/gradebook/lib/be/exerciselink.class.php @@ -240,7 +240,7 @@ class ExerciseLink extends AbstractLink $courseId = $this->getCourseId(); $exerciseData = $this->get_exercise_data(); - $exerciseId = isset($exerciseData['id']) ? $exerciseData['id'] : 0; + $exerciseId = isset($exerciseData['id']) ? (int) $exerciseData['id'] : 0; $stud_id = (int) $stud_id; if (empty($exerciseId)) { @@ -262,7 +262,7 @@ class ExerciseLink extends AbstractLink } $exercise = new Exercise($courseId); - $exercise->read($exerciseData['id']); + $exercise->read($exerciseId); if (!$this->is_hp) { if ($exercise->exercise_was_added_in_lp == false) { @@ -303,7 +303,7 @@ class ExerciseLink extends AbstractLink ON (hp.exe_name = doc.path AND doc.c_id = hp.c_id) WHERE hp.c_id = $courseId AND - doc.id = ".$exerciseId; + doc.id = $exerciseId"; if (!empty($stud_id)) { $sql .= " AND hp.exe_user_id = $stud_id "; @@ -315,7 +315,12 @@ class ExerciseLink extends AbstractLink if (isset($stud_id) && empty($type)) { // for 1 student if ($data = Database::fetch_array($scores)) { - $result = [$data['score'], $data['max_score']]; + $attempts = Database::query($sql); + $counter = 0; + while ($attempt = Database::fetch_array($attempts)) { + $counter++; + } + $result = [$data['score'], $data['max_score'], $data['exe_date'], $counter]; if ($cacheAvailable) { $cacheDriver->save($key, $result); } @@ -357,11 +362,11 @@ class ExerciseLink extends AbstractLink if ($data['max_score'] != 0) { $students[$data['exe_user_id']] = $data['score']; $student_count++; - if ($data['score'] > $bestResult) { - $bestResult = $data['score']; + if ($data['exe_result'] > $bestResult) { + $bestResult = $data['exe_result']; } $sum += $data['score'] / $data['max_score']; - $sumResult += $data['score']; + $sumResult += $data['exe_result']; $weight = $data['max_score']; } } @@ -500,9 +505,9 @@ class ExerciseLink extends AbstractLink { if ($this->is_hp == 1) { return 'HotPotatoes'; - } else { - return get_lang('Quiz'); } + + return get_lang('Quiz'); } public function needs_name_and_description() @@ -550,58 +555,45 @@ class ExerciseLink extends AbstractLink { switch ($type) { case 'best': - break; } } - /** - * Lazy load function to get the database table of the exercise. - */ - private function get_exercise_table() - { - $this->exercise_table = Database::get_course_table(TABLE_QUIZ_TEST); - - return $this->exercise_table; - } - /** * Lazy load function to get the database contents of this exercise. */ - private function get_exercise_data() + public function get_exercise_data() { $tableItemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY); if ($this->is_hp == 1) { $table = Database::get_course_table(TABLE_DOCUMENT); } else { - $table = $this->get_exercise_table(); + $table = Database::get_course_table(TABLE_QUIZ_TEST); } $exerciseId = $this->get_ref_id(); - if ($table == '') { - return false; - } elseif (empty($this->exercise_data)) { + if (empty($this->exercise_data)) { if ($this->is_hp == 1) { $sql = "SELECT * FROM $table ex - INNER JOIN $tableItemProperty ip - ON (ip.ref = ex.id AND ip.c_id = ex.c_id) - WHERE - ip.c_id = $this->course_id AND - ex.c_id = $this->course_id AND - ip.ref = $exerciseId AND - ip.tool = '".TOOL_DOCUMENT."' AND - ex.path LIKE '%htm%' AND - ex.path LIKE '%HotPotatoes_files%' AND - ip.visibility = 1"; + INNER JOIN $tableItemProperty ip + ON (ip.ref = ex.id AND ip.c_id = ex.c_id) + WHERE + ip.c_id = $this->course_id AND + ex.c_id = $this->course_id AND + ip.ref = $exerciseId AND + ip.tool = '".TOOL_DOCUMENT."' AND + ex.path LIKE '%htm%' AND + ex.path LIKE '%HotPotatoes_files%' AND + ip.visibility = 1"; $result = Database::query($sql); $this->exercise_data = Database::fetch_array($result); } else { // Try with iid $sql = 'SELECT * FROM '.$table.' - WHERE - c_id = '.$this->course_id.' AND - iid = '.$exerciseId; + WHERE + c_id = '.$this->course_id.' AND + iid = '.$exerciseId; $result = Database::query($sql); $rows = Database::num_rows($result); @@ -610,15 +602,29 @@ class ExerciseLink extends AbstractLink } else { // Try wit id $sql = 'SELECT * FROM '.$table.' - WHERE - c_id = '.$this->course_id.' AND - id = '.$exerciseId; + WHERE + c_id = '.$this->course_id.' AND + id = '.$exerciseId; $result = Database::query($sql); $this->exercise_data = Database::fetch_array($result); } } } + if (empty($this->exercise_data)) { + return false; + } + return $this->exercise_data; } + + /** + * Lazy load function to get the database table of the exercise. + */ + private function get_exercise_table() + { + $this->exercise_table = Database::get_course_table(TABLE_QUIZ_TEST); + + return $this->exercise_table; + } } diff --git a/main/gradebook/lib/be/studentpublicationlink.class.php b/main/gradebook/lib/be/studentpublicationlink.class.php index e519a4e998..45883543d7 100755 --- a/main/gradebook/lib/be/studentpublicationlink.class.php +++ b/main/gradebook/lib/be/studentpublicationlink.class.php @@ -34,17 +34,18 @@ class StudentPublicationLink extends AbstractLink // with the same title as the evaluation name $eval = $this->get_evaluation(); - $stud_id = intval($stud_id); + $stud_id = (int) $stud_id; $itemProperty = $this->get_itemprop_table(); $workTable = $this->get_studpub_table(); $courseId = $this->course_id; $sql = "SELECT pub.url - FROM $itemProperty prop INNER JOIN $workTable pub + FROM $itemProperty prop + INNER JOIN $workTable pub ON (prop.c_id = pub.c_id AND prop.ref = pub.id) WHERE - prop.c_id = ".$courseId." AND - pub.c_id = ".$courseId." AND + prop.c_id = $courseId AND + pub.c_id = $courseId AND prop.tool = 'work' AND prop.insert_user_id = $stud_id AND pub.title = '".Database::escape_string($eval->get_name())."' AND @@ -82,7 +83,8 @@ class StudentPublicationLink extends AbstractLink return []; } $em = Database::getManager(); - $session = $em->find('ChamiloCoreBundle:Session', api_get_session_id()); + $sessionId = $this->get_session_id(); + $session = $em->find('ChamiloCoreBundle:Session', $sessionId); /* if (empty($session_id)) { $session_condition = api_get_session_condition(0, true); @@ -128,7 +130,7 @@ class StudentPublicationLink extends AbstractLink $id = $data['id']; $em = Database::getManager(); - $session = $em->find('ChamiloCoreBundle:Session', api_get_session_id()); + $session = $em->find('ChamiloCoreBundle:Session', $this->get_session_id()); $results = $em ->getRepository('ChamiloCourseBundle:CStudentPublication') ->findBy([ @@ -155,7 +157,7 @@ class StudentPublicationLink extends AbstractLink return []; } $id = $data['id']; - $session = $em->find('ChamiloCoreBundle:Session', api_get_session_id()); + $session = api_get_session_entity($this->get_session_id()); $assignment = $em ->getRepository('ChamiloCourseBundle:CStudentPublication') @@ -225,7 +227,7 @@ class StudentPublicationLink extends AbstractLink // for 1 student if (!empty($stud_id)) { if (!count($scores)) { - return ''; + return [null, null]; } $data = $scores[0]; @@ -233,6 +235,8 @@ class StudentPublicationLink extends AbstractLink return [ $data->getQualification(), $assignment->getQualification(), + api_get_local_time($assignment->getDateOfQualification()), + 1, ]; } @@ -261,7 +265,7 @@ class StudentPublicationLink extends AbstractLink } if ($rescount == 0) { - return null; + return [null, null]; } switch ($type) { @@ -302,8 +306,8 @@ class StudentPublicationLink extends AbstractLink public function get_link() { - $session_id = api_get_session_id(); - $url = api_get_path(WEB_PATH).'main/work/work.php?'.api_get_cidreq_params($this->get_course_code(), $session_id).'&id='.$this->exercise_data['id'].'&gradebook=view'; + $sessionId = $this->get_session_id(); + $url = api_get_path(WEB_PATH).'main/work/work.php?'.api_get_cidreq_params($this->get_course_code(), $sessionId).'&id='.$this->exercise_data['id'].'&gradebook=view'; return $url; } @@ -329,7 +333,7 @@ class StudentPublicationLink extends AbstractLink $sql = 'SELECT count(id) FROM '.$this->get_studpub_table().' WHERE c_id = "'.$this->course_id.'" AND - id = '.$id.''; + id = '.$id; $result = Database::query($sql); $number = Database::fetch_row($result); diff --git a/main/gradebook/lib/fe/exportgradebook.php b/main/gradebook/lib/fe/exportgradebook.php index 249f8aa5d7..316afd0ff9 100755 --- a/main/gradebook/lib/fe/exportgradebook.php +++ b/main/gradebook/lib/fe/exportgradebook.php @@ -90,141 +90,6 @@ a:active {text-decoration: none; font-weight : bold; color : black;} return $printdata; } -/** - * This function get a content html for export inside a pdf file. - * - * @param array table headers - * @param array table body - * @param array pdf headers - * @param array pdf footers - */ -function export_pdf_attendance($headers_table, $data_table, $headers_pdf, $footers_pdf, $title_pdf) -{ - $mpdf = new mPDF('UTF-8', 'A4-L', '', '', 15, 10, 35, 20, 4, 2, 'L'); - $mpdf->useOnlyCoreFonts = true; - $mpdf->mirrorMargins = 0; - - // Use different Odd/Even headers and footers and mirror margins - if (is_array($headers_pdf)) { - // preparing headers pdf - $header = ' -
'.get_lang('Choice').''.get_lang('ExpectedChoice').''.get_lang('ExpectedChoice').''.get_lang('Answer').'
- - - - - - - - - - - - - - - - - - - -
- - -

'.$title_pdf.'

-
'.$headers_pdf[0][0].' '.$headers_pdf[0][1].''.$headers_pdf[1][0].' '.$headers_pdf[1][1].'
'.$headers_pdf[2][0].' '.$headers_pdf[2][1].''.$headers_pdf[3][0].' '.$headers_pdf[3][1].'
'.$headers_pdf[4][0].' '.$headers_pdf[4][1].''.$headers_pdf[5][0].' '.$headers_pdf[5][1].'
'; - } - - // preparing footer pdf - $footer = ''; - if (is_array($footers_pdf)) { - $footer .= ''; - foreach ($footers_pdf as $foot_pdf) { - $footer .= ''; - } - $footer .= ''; - } - $footer .= '
'.$foot_pdf.'
'; - $footer .= '
{PAGENO}/{nb}
'; - - // preparing content pdf - $css_file = api_get_path(SYS_CSS_PATH).'themes/'.api_get_setting('stylesheets').'/print.css'; - - if (file_exists($css_file)) { - $css = @file_get_contents($css_file); - } else { - $css = ''; - } - - if (count($data_table) > 30) { - $items_per_page = (count($data_table) / 2); - } else { - $items_per_page = count($data_table); - } - - $count_pages = ceil(count($data_table) / $items_per_page); - $content_table = ''; - for ($x = 0; $x < $count_pages; $x++) { - $content_table .= ''; - // header table - $content_table .= ''; - $i = 0; - if (is_array($headers_table)) { - foreach ($headers_table as $head_table) { - if (!empty($head_table[0])) { - $width = (!empty($head_table[1]) ? $head_table[1].'%' : ''); - $content_table .= ''; - $i++; - } - } - } - $content_table .= ''; - // body table - if (is_array($data_table) && count($data_table) > 0) { - $offset = $x * $items_per_page; - $data_table = array_slice($data_table, $offset, count($data_table)); - $i = 1; - $item = $offset + 1; - foreach ($data_table as $data) { - $content_table .= ''; - $content_table .= ''; - foreach ($data as $key => $content) { - if (isset($content)) { - $key == 1 ? $align = 'align="left"' : $align = 'align="center"'; - $content_table .= ''; - } - } - $content_table .= ''; - $i++; - $item++; - if ($i > $items_per_page) { - break; - } - } - } else { - $content_table .= ''; - } - $content_table .= '
'.$head_table[0].'
'.($item < 10 ? '0'.$item : $item).''.$content.'
'.get_lang('Empty').'
'; - if ($x < ($count_pages - 1)) { - $content_table .= ''; - } - } - $html = $content_table; - - // set attributes for pdf - $mpdf->SetHTMLHeader($header); - $mpdf->SetHTMLFooter($footer); - if (!empty($css)) { - $mpdf->WriteHTML($css, 1); - $mpdf->WriteHTML($html, 2); - } else { - $mpdf->WriteHTML($html); - } - $mpdf->Output(api_replace_dangerous_char($title_pdf.'.pdf'), 'D'); - - exit; -} - /** * This function get a content html for export inside a pdf file. * diff --git a/main/gradebook/lib/fe/gradebooktable.class.php b/main/gradebook/lib/fe/gradebooktable.class.php index 81267c59d5..f85699aefe 100755 --- a/main/gradebook/lib/fe/gradebooktable.class.php +++ b/main/gradebook/lib/fe/gradebooktable.class.php @@ -483,7 +483,6 @@ class GradebookTable extends SortableTable } // Students get the results and certificates columns - $value_data = isset($data[4]) ? $data[4] : null; $best = isset($data['best']) ? $data['best'] : null; $average = isset($data['average']) ? $data['average'] : null; @@ -497,15 +496,17 @@ class GradebookTable extends SortableTable $totalUserResult[0] += $totalResult[0] / ($totalResult[1] ?: 1) * $data[3]; $totalUserResult[1] += $data[3]; - $totalBest = [ - $scoredisplay->format_score($totalBest[0] + $data['best_score'][0]), - $scoredisplay->format_score($totalBest[1] + $data['best_score'][1]), - ]; - - $totalAverage = [ - $data['average_score'][0], - $data['average_score'][1], - ]; + if (empty($model)) { + $totalBest = [ + $scoredisplay->format_score($totalBest[0] + $data['best_score'][0]), + $scoredisplay->format_score($totalBest[1] + $data['best_score'][1]), + ]; + + $totalAverage = [ + $data['average_score'][0], + $data['average_score'][1], + ]; + } // Student result if (empty($model)) { diff --git a/main/gradebook/lib/flatview_data_generator.class.php b/main/gradebook/lib/flatview_data_generator.class.php index e987c02a06..82a20caab9 100755 --- a/main/gradebook/lib/flatview_data_generator.class.php +++ b/main/gradebook/lib/flatview_data_generator.class.php @@ -460,8 +460,6 @@ class FlatViewDataGenerator if (api_get_setting('gradebook_detailed_admin_view') === 'true') { $links = $sub_cat->get_links(); - $evaluations = $sub_cat->get_evaluations(); - /** @var ExerciseLink $link */ $linkScoreList = []; foreach ($links as $link) { @@ -472,7 +470,9 @@ class FlatViewDataGenerator ); } + $evaluations = $sub_cat->get_evaluations(); $evalScoreList = []; + /** @var Evaluation $evaluation */ foreach ($evaluations as $evaluation) { $evalScore = $evaluation->calc_score($user_id); $evalScoreList[] = $scoreDisplay->display_score( diff --git a/main/inc/lib/template.lib.php b/main/inc/lib/template.lib.php index 0acee40f53..b6c403302d 100755 --- a/main/inc/lib/template.lib.php +++ b/main/inc/lib/template.lib.php @@ -1501,8 +1501,6 @@ class Template $this->assign('footer_extra_content', $extra_footer); } } - - // Tutor name } /**