Browse Source

Minor - Merge from 1.11.x

jmontoyaa 7 years ago
parent
commit
f7d182105e
72 changed files with 1053 additions and 718 deletions
  1. 0 1
      main/attendance/attendance_calendar.php
  2. 19 4
      main/attendance/attendance_controller.php
  3. 4 1
      main/attendance/attendance_edit.php
  4. 2 2
      main/attendance/attendance_list.php
  5. 26 5
      main/attendance/index.php
  6. 25 25
      main/auth/courses_categories.php
  7. 1 1
      main/badge/assign.php
  8. 10 2
      main/course_info/infocours.php
  9. 20 6
      main/course_progress/index.php
  10. 30 10
      main/course_progress/thematic.php
  11. 2 2
      main/course_progress/thematic_advance.php
  12. 2 5
      main/course_progress/thematic_controller.php
  13. 21 3
      main/coursecopy/copy_course.php
  14. 16 15
      main/document/add_link.php
  15. 1 3
      main/document/create_document.php
  16. 6 6
      main/document/document.php
  17. 2 2
      main/document/document_quota.php
  18. 2 3
      main/document/document_slideshow.inc.php
  19. 1 1
      main/document/remote.php
  20. 7 5
      main/document/show_content.php
  21. 9 10
      main/document/upload.php
  22. 0 1
      main/exercise/Annotation.php
  23. 10 5
      main/exercise/Draggable.php
  24. 13 6
      main/exercise/MatchingDraggable.php
  25. 0 1
      main/exercise/ReadingComprehension.php
  26. 30 24
      main/exercise/TestCategory.php
  27. 27 1
      main/exercise/UniqueAnswerImage.php
  28. 3 37
      main/exercise/admin.php
  29. 15 13
      main/exercise/answer.class.php
  30. 18 17
      main/exercise/calculated_answer.class.php
  31. 1 0
      main/exercise/evalmathnotation.php
  32. 374 213
      main/exercise/exercise.class.php
  33. 3 2
      main/exercise/exercise.php
  34. 3 2
      main/exercise/exercise_report.php
  35. 2 2
      main/exercise/exercise_result.php
  36. 71 54
      main/exercise/exercise_show.php
  37. 5 2
      main/exercise/exercise_submit.php
  38. 4 14
      main/exercise/exercise_submit_modal.php
  39. 30 21
      main/exercise/fill_blanks.class.php
  40. 1 1
      main/exercise/freeanswer.class.php
  41. 9 6
      main/exercise/global_multiple_answer.class.php
  42. 6 2
      main/exercise/hotpotatoes.lib.php
  43. 1 1
      main/exercise/hotspot.class.php
  44. 11 5
      main/exercise/matching.class.php
  45. 10 7
      main/exercise/multiple_answer.class.php
  46. 9 7
      main/exercise/multiple_answer_combination.class.php
  47. 11 11
      main/exercise/multiple_answer_true_false.class.php
  48. 3 1
      main/exercise/oral_expression.class.php
  49. 1 5
      main/exercise/overview.php
  50. 11 9
      main/exercise/question.class.php
  51. 0 2
      main/exercise/question_admin.inc.php
  52. 1 1
      main/exercise/question_list_admin.inc.php
  53. 0 1
      main/exercise/question_pool.php
  54. 8 8
      main/exercise/unique_answer.class.php
  55. 12 19
      main/exercise/unique_answer_no_option.class.php
  56. 8 7
      main/forum/editpost.php
  57. 11 2
      main/forum/forumfunction.inc.php
  58. 8 5
      main/forum/reply.php
  59. 6 4
      main/forum/viewforumcategory.php
  60. 3 4
      main/forum/viewpost.php
  61. 6 7
      main/forum/viewthread_flat.inc.php
  62. 2 1
      main/forum/viewthread_threaded.inc.php
  63. 32 12
      main/glossary/index.php
  64. 8 10
      main/gradebook/gradebook_display_summary.php
  65. 4 2
      main/gradebook/lib/GradebookUtils.php
  66. 2 2
      main/gradebook/lib/be/category.class.php
  67. 31 34
      main/gradebook/lib/fe/scoredisplayform.class.php
  68. 8 3
      main/gradebook/lib/fe/userform.class.php
  69. 6 6
      main/gradebook/lib/fe/usertable.class.php
  70. 2 1
      main/gradebook/lib/gradebook_data_generator.class.php
  71. 6 4
      main/gradebook/lib/scoredisplay.class.php
  72. 1 1
      main/group/example.csv

+ 0 - 1
main/attendance/attendance_calendar.php

@@ -31,7 +31,6 @@ if (!$is_locked_attendance || api_is_platform_admin()) {
 }
 
 $message_information = get_lang('AttendanceCalendarDescription');
-
 if (!empty($message_information)) {
     $message = '<strong>'.get_lang('Information').'</strong><br />';
     $message .= $message_information;

+ 19 - 4
main/attendance/attendance_controller.php

@@ -48,7 +48,7 @@ class AttendanceController
         if (strtoupper($_SERVER['REQUEST_METHOD']) == 'POST') {
             if (!empty($_POST['title'])) {
                 $check = Security::check_token();
-                $last_id = 0;
+                $attendanceId = 0;
                 if ($check) {
                     $attendance->set_name($_POST['title']);
                     $attendance->set_description($_POST['description']);
@@ -375,13 +375,28 @@ class AttendanceController
                 $my_calendar_id,
                 $groupId
             );
-            $data['attendant_calendar_all'] = $attendance->get_attendance_calendar($attendance_id, 'all', null, $groupId);
+            $data['attendant_calendar_all'] = $attendance->get_attendance_calendar(
+                $attendance_id,
+                'all',
+                null,
+                $groupId
+            );
             $data['users_presence'] = $attendance->get_users_attendance_sheet($attendance_id, 0, $groupId);
             $data['next_attendance_calendar_id'] = $attendance->get_next_attendance_calendar_id($attendance_id);
             $data['next_attendance_calendar_datetime'] = $attendance->getNextAttendanceCalendarDatetime($attendance_id);
         } else {
-            $data['attendant_calendar_all'] = $attendance->get_attendance_calendar($attendance_id, 'all', null, $groupId);
-            $data['attendant_calendar'] = $attendance->get_attendance_calendar($attendance_id, $filter_type, null, $groupId);
+            $data['attendant_calendar_all'] = $attendance->get_attendance_calendar(
+                $attendance_id,
+                'all',
+                null,
+                $groupId
+            );
+            $data['attendant_calendar'] = $attendance->get_attendance_calendar(
+                $attendance_id,
+                $filter_type,
+                null,
+                $groupId
+            );
         }
 
         $data['edit_table'] = intval($edit);

+ 4 - 1
main/attendance/attendance_edit.php

@@ -57,7 +57,10 @@ if (Gradebook::is_active()) {
             'attendance_qualify_gradebook',
             '',
             get_lang('QualifyAttendanceGradebook'),
-            ['checked' => 'true', 'onclick' => 'javascript: if(this.checked){document.getElementById(\'options_field\').style.display = \'block\';}else{document.getElementById(\'options_field\').style.display = \'none\';}']
+            [
+                'checked' => 'true',
+                'onclick' => 'javascript: if(this.checked){document.getElementById(\'options_field\').style.display = \'block\';}else{document.getElementById(\'options_field\').style.display = \'none\';}',
+            ]
         );
         $form->addElement('html', '<div id="options_field" style="display:block">');
     } else {

+ 2 - 2
main/attendance/attendance_list.php

@@ -19,7 +19,7 @@ if (api_is_allowed_to_edit(null, true)) {
     echo '</div>';
 }
 $attendance = new Attendance();
-if ($attendance->get_number_of_attendances() == 0) {
+if ($attendance->getNumberOfAttendances() == 0) {
     $attendance->set_name(get_lang('Attendances'));
     $attendance->set_description(get_lang('Attendances'));
     $attendance->attendance_add();
@@ -28,7 +28,7 @@ $default_column = isset($default_column) ? $default_column : null;
 $parameters = isset($parameters) ? $parameters : null;
 $table = new SortableTable(
     'attendance_list',
-    ['Attendance', 'get_number_of_attendances'],
+    ['Attendance', 'getNumberOfAttendances'],
     ['Attendance', 'get_attendance_data'],
     $default_column
 );

+ 26 - 5
main/attendance/index.php

@@ -101,8 +101,15 @@ $(function() {
             //lock
             $(".checkbox_head_"+calendar_id).attr("disabled", true);
 
-            $(".row_odd  td.checkboxes_col_"+calendar_id).css({"opacity":"1","background-color":"#F9F9F9",   "border-left":"none","border-right":"none"});
-            $(".row_even td.checkboxes_col_"+calendar_id).css({"opacity":"1","background-color":"#FFF",      "border-left":"none","border-right":"none"});
+            $(".row_odd  td.checkboxes_col_"+calendar_id).css({
+                "opacity":"1",
+                "background-color":"#F9F9F9",   
+                "border-left":"none",
+                "border-right":"none"
+            });
+            $(".row_even td.checkboxes_col_"+calendar_id).css({
+                "opacity":"1","background-color":"#FFF",      "border-left":"none","border-right":"none"
+            });
             $(".checkboxes_col_"+calendar_id+" input:checkbox").attr("disabled",true);
             $(this).attr("src","'.Display::returnIconPath('lock-closed.png').'");
             $(this).attr("title","'.get_lang('DateUnLock').'");
@@ -116,8 +123,20 @@ $(function() {
             $(".checkbox_head_"+calendar_id).attr("disabled", false);
             $(".checkbox_head_"+calendar_id).removeAttr("disabled");
 
-            $(".row_odd  td.checkboxes_col_"+calendar_id).css({"opacity":"1","background-color":"#dcdcdc", "border-left":"1px #bbb solid", "border-right":"1px #bbb solid", "z-index":"1" });
-            $(".row_even td.checkboxes_col_"+calendar_id).css({"opacity":"1","background-color":"#eee", "border-left":"1px #bbb solid", "border-right":"1px #bbb solid", "z-index":"1" });
+            $(".row_odd  td.checkboxes_col_"+calendar_id).css({
+                "opacity":"1",
+                "background-color":"#dcdcdc", 
+                "border-left":"1px #bbb solid", 
+                "border-right":"1px #bbb solid", 
+                "z-index":"1"
+            });
+            $(".row_even td.checkboxes_col_"+calendar_id).css({
+                "opacity":"1",
+                "background-color":"#eee", 
+                "border-left":"1px #bbb solid", 
+                "border-right":"1px #bbb solid", 
+                "z-index":"1"
+            });
 
             $(".checkboxes_col_"+calendar_id).mouseover(function() {
                 //$(".checkbox_head_"+calendar_id).removeAttr("opacity");
@@ -196,7 +215,9 @@ if ($action == 'attendance_edit') {
 if ($action == 'attendance_sheet_list' || $action == 'attendance_sheet_add') {
     $interbreadcrumb[] = ['url' => '#', 'name' => $attendance_data['name']];
 }
-if ($action == 'calendar_list' || $action == 'calendar_edit' || $action == 'calendar_delete' || $action == 'calendar_all_delete') {
+if ($action == 'calendar_list' || $action == 'calendar_edit' || $action == 'calendar_delete' ||
+    $action == 'calendar_all_delete'
+) {
     $interbreadcrumb[] = [
         'url' => 'index.php?'.api_get_cidreq().'&action=attendance_sheet_list&attendance_id='.$attendance_id,
         'name' => $attendance_data['name'],

+ 25 - 25
main/auth/courses_categories.php

@@ -71,7 +71,7 @@ $code = isset($code) ? $code : null;
         <h2 class="title-courses"><?php echo get_lang('CourseManagement'); ?></h2>
         <div class="search-courses">
             <div class="row">
-                <?php if ($showCourses) {
+<?php if ($showCourses) {
         ?>
                     <div class="col-md-<?php echo $showSessions ? '4' : '6'; ?>">
                         <?php if (!isset($_GET['hidden_links']) || intval($_GET['hidden_links']) != 1) {
@@ -97,8 +97,8 @@ $code = isset($code) ? $code : null;
         } ?>
                     </div>
                     <div class="col-md-<?php echo $showSessions ? '4' : '6'; ?>">
-                        <?php
-                        $webAction = api_get_path(WEB_CODE_PATH).'auth/courses.php';
+<?php
+    $webAction = api_get_path(WEB_CODE_PATH).'auth/courses.php';
         $form = '<form action="'.$webAction.'" method="GET">';
         $form .= '<input type="hidden" name="action" value="'.$action.'">';
         $form .= '<input type="hidden" name="pageCurrent" value="'.$pageCurrent.'">';
@@ -113,40 +113,40 @@ $code = isset($code) ? $code : null;
                 continue;
             }
             $form .= '<option '.($categoryCode == $codeType ? 'selected="selected" ' : '')
-                                .' value="'.$category['code'].'">'.$category['name'].' ('.$countCourse.') </option>';
+                            .' value="'.$category['code'].'">'.$category['name'].' ('.$countCourse.') </option>';
             if (!empty($browse_course_categories[$categoryCode])) {
                 foreach ($browse_course_categories[$categoryCode] as $subCategory) {
                     if (empty($subCategory['count_courses'])) {
                         continue;
                     }
                     $subCategoryCode = $subCategory['code'];
-                    $form .= '<option '
-                                        .($subCategoryCode == $codeType
-                                            ? 'selected="selected" '
-                                            : '')
-                                        .' value="'.$subCategory['code'].'">---'.$subCategory['name'].' ('.$subCategory['count_courses'].')</option>';
+                    $form .= '<option '.($subCategoryCode == $codeType
+                                        ? 'selected="selected" '
+                                        : '')
+                                    .' value="'.$subCategory['code'].'">---';
+                    echo $subCategory['name'].' ('.$subCategory['count_courses'].')</option>';
                 }
             }
         }
         $form .= '</select>';
         $form .= '</div>';
         $form .= '</form>';
-        echo $form; ?>
-                    </div>
-                <?php
-    } ?>
-                <?php if ($showSessions) {
-        ?>
-                    <div class="col-md-4">
-                        <div class="return-catalog">
-                            <a class="btn btn-default btn-lg btn-block"
-                               href="<?php echo CourseCategory::getCourseCategoryUrl(1, $pageLength, null, 0, 'display_sessions'); ?>">
-                                <em class="fa fa-arrow-right"></em> <?php echo get_lang('SessionList'); ?>
-                            </a>
-                        </div>
-                    </div>
-                <?php
-    } ?>
+        echo $form;
+        echo '</div>';
+    }
+
+if ($showSessions) {
+    ?>
+    <div class="col-md-4">
+        <div class="return-catalog">
+            <a class="btn btn-default btn-lg btn-block"
+               href="<?php echo CourseCategory::getCourseCategoryUrl(1, $pageLength, null, 0, 'display_sessions'); ?>">
+                <em class="fa fa-arrow-right"></em> <?php echo get_lang('SessionList'); ?>
+            </a>
+        </div>
+    </div>
+<?php
+} ?>
             </div>
         </div>
     </div>

+ 1 - 1
main/badge/assign.php

@@ -9,7 +9,7 @@ use Skill as SkillManager;
 /**
  * Page for assign skills to a user.
  *
- * @autor: Jose Loguercio <jose.loguercio@beeznest.com>
+ * @author: Jose Loguercio <jose.loguercio@beeznest.com>
  *
  * @package chamilo.badge
  */

+ 10 - 2
main/course_info/infocours.php

@@ -149,9 +149,17 @@ if (api_get_setting('pdf_export_watermark_by_course') == 'true') {
     $form->addElement('file', 'pdf_export_watermark_path', get_lang('AddWaterMark'));
     if ($url != false) {
         $delete_url = '<a href="?delete_watermark">'.Display::return_icon('delete.png', get_lang('DelImage')).'</a>';
-        $form->addElement('html', '<div class="row"><div class="formw"><a href="'.$url.'">'.$url.' '.$delete_url.'</a></div></div>');
+        $form->addElement(
+            'html',
+            '<div class="row"><div class="formw"><a href="'.$url.'">'.$url.' '.$delete_url.'</a></div></div>'
+        );
     }
-    $form->addRule('pdf_export_watermark_path', get_lang('OnlyImagesAllowed').' ('.implode(',', $allowed_picture_types).')', 'filetype', $allowed_picture_types);
+    $form->addRule(
+        'pdf_export_watermark_path',
+        get_lang('OnlyImagesAllowed').' ('.implode(',', $allowed_picture_types).')',
+        'filetype',
+        $allowed_picture_types
+    );
 }
 
 if (api_get_setting('allow_course_theme') == 'true') {

+ 20 - 6
main/course_progress/index.php

@@ -114,7 +114,6 @@ $(document).ready(function() {
 </script>';
 
 $htmlHeadXtra[] = '<script>
-
 function datetime_by_attendance(attendance_id, thematic_advance_id) {
 	$.ajax({
 		contentType: "application/x-www-form-urlencoded",
@@ -215,16 +214,31 @@ if ($action == 'thematic_plan_list' || $action == 'thematic_plan_delete') {
     }
 }
 if ($action == 'thematic_plan_add' || $action == 'thematic_plan_edit') {
-    $interbreadcrumb[] = ['url' => 'index.php?'.api_get_cidreq().'&action='.$thematicControl, 'name' => get_lang('ThematicControl')];
-    $interbreadcrumb[] = ['url' => 'index.php?'.api_get_cidreq().'&action=thematic_plan_list&thematic_id='.$thematic_id, 'name' => get_lang('ThematicPlan').' ('.$cleanThematicTitle.')'];
+    $interbreadcrumb[] = [
+        'url' => 'index.php?'.api_get_cidreq().'&action='.$thematicControl,
+        'name' => get_lang('ThematicControl'),
+    ];
+    $interbreadcrumb[] = [
+        'url' => 'index.php?'.api_get_cidreq().'&action=thematic_plan_list&thematic_id='.$thematic_id,
+        'name' => get_lang('ThematicPlan').' ('.$cleanThematicTitle.')',
+    ];
 }
 if ($action == 'thematic_advance_list' || $action == 'thematic_advance_delete') {
-    $interbreadcrumb[] = ['url' => 'index.php?'.api_get_cidreq().'&action='.$thematicControl, 'name' => get_lang('ThematicControl')];
+    $interbreadcrumb[] = [
+        'url' => 'index.php?'.api_get_cidreq().'&action='.$thematicControl,
+        'name' => get_lang('ThematicControl'),
+    ];
     $interbreadcrumb[] = ['url' => '#', 'name' => get_lang('ThematicAdvance').' ('.$cleanThematicTitle.')'];
 }
 if ($action == 'thematic_advance_add' || $action == 'thematic_advance_edit') {
-    $interbreadcrumb[] = ['url' => 'index.php?'.api_get_cidreq().'&action='.$thematicControl, 'name' => get_lang('ThematicControl')];
-    $interbreadcrumb[] = ['url' => 'index.php?'.api_get_cidreq().'&action=thematic_advance_list&thematic_id='.$thematic_id, 'name' => get_lang('ThematicAdvance').' ('.$cleanThematicTitle.')'];
+    $interbreadcrumb[] = [
+        'url' => 'index.php?'.api_get_cidreq().'&action='.$thematicControl,
+        'name' => get_lang('ThematicControl'),
+    ];
+    $interbreadcrumb[] = [
+        'url' => 'index.php?'.api_get_cidreq().'&action=thematic_advance_list&thematic_id='.$thematic_id,
+        'name' => get_lang('ThematicAdvance').' ('.$cleanThematicTitle.')',
+    ];
     $interbreadcrumb[] = ['url' => '#', 'name' => get_lang('NewThematicAdvance')];
 }
 

+ 30 - 10
main/course_progress/thematic.php

@@ -25,8 +25,14 @@ if (api_is_allowed_to_edit(null, true)) {
     switch ($action) {
         case 'thematic_add':
         case 'thematic_import_select':
-            $actionLeft = '<a href="index.php?'.api_get_cidreq().'">'.
-                Display::return_icon('back.png', get_lang('BackTo').' '.get_lang('ThematicDetails'), '', ICON_SIZE_MEDIUM).'</a>';
+            $actionLeft = '<a href="index.php?'.api_get_cidreq().'">';
+            $actionLeft .= Display::return_icon(
+                'back.png',
+                get_lang('BackTo').' '.get_lang('ThematicDetails'),
+                '',
+                ICON_SIZE_MEDIUM
+            );
+            $actionLeft .= '</a>';
             break;
         case 'thematic_list':
             $actionLeft = '<a href="index.php?'.api_get_cidreq().'&action=thematic_add'.$url_token.'">'.
@@ -151,14 +157,18 @@ if ($action == 'thematic_list') {
                 );
                 if (api_get_session_id() == 0) {
                     if ($thematic['display_order'] > 1) {
-                        $toolbarThematic .= ' <a class="btn btn-default" href="'.api_get_self().'?action=moveup&'.api_get_cidreq().'&thematic_id='.$my_thematic_id.$params.$url_token.'">'.Display::return_icon('up.png', get_lang('Up'), '', ICON_SIZE_TINY).'</a>';
+                        $toolbarThematic .= ' <a class="btn btn-default" href="'.api_get_self().'?action=moveup&'.api_get_cidreq().'&thematic_id='.$my_thematic_id.$params.$url_token.'">'.
+                            Display::return_icon('up.png', get_lang('Up'), '', ICON_SIZE_TINY).'</a>';
                     } else {
-                        $toolbarThematic .= '<div class="btn btn-default">'.Display::return_icon('up_na.png', '&nbsp;', '', ICON_SIZE_TINY).'</div>';
+                        $toolbarThematic .= '<div class="btn btn-default">'.
+                            Display::return_icon('up_na.png', '&nbsp;', '', ICON_SIZE_TINY).'</div>';
                     }
                     if (isset($thematic['max_thematic_item']) && $thematic['display_order'] < $thematic['max_thematic_item']) {
-                        $toolbarThematic .= ' <a class="btn btn-default" href="'.api_get_self().'?action=movedown&a'.api_get_cidreq().'&thematic_id='.$my_thematic_id.$params.$url_token.'">'.Display::return_icon('down.png', get_lang('Down'), '', ICON_SIZE_TINY).'</a>';
+                        $toolbarThematic .= ' <a class="btn btn-default" href="'.api_get_self().'?action=movedown&a'.api_get_cidreq().'&thematic_id='.$my_thematic_id.$params.$url_token.'">'.
+                            Display::return_icon('down.png', get_lang('Down'), '', ICON_SIZE_TINY).'</a>';
                     } else {
-                        $toolbarThematic .= '<div class="btn btn-default">'.Display::return_icon('down_na.png', '&nbsp;', '', ICON_SIZE_TINY).'</div>';
+                        $toolbarThematic .= '<div class="btn btn-default">'.
+                            Display::return_icon('down_na.png', '&nbsp;', '', ICON_SIZE_TINY).'</div>';
                     }
                 }
                 if (api_get_session_id() == $thematic['session_id']) {
@@ -171,9 +181,15 @@ if ($action == 'thematic_list') {
                         ['class' => 'btn btn-default']
                     );
                     $toolbarThematic .= Display::url(
-                        Display::return_icon('export_to_documents.png', get_lang('ExportToDocArea'), [], ICON_SIZE_TINY),
-                        api_get_self().'?'.api_get_cidreq().$url_token.'&'
-                            .http_build_query(['action' => 'export_single_documents', 'thematic_id' => $my_thematic_id]),
+                        Display::return_icon(
+                            'export_to_documents.png',
+                            get_lang('ExportToDocArea'),
+                            [],
+                            ICON_SIZE_TINY
+                        ),
+                        api_get_self().'?'.api_get_cidreq().$url_token.'&'.http_build_query(
+                            ['action' => 'export_single_documents', 'thematic_id' => $my_thematic_id]
+                        ),
                         ['class' => 'btn btn-default']
                     );
                     $toolbarThematic .= '<a class="btn btn-default" href="index.php?'.api_get_cidreq().'&action=thematic_edit&thematic_id='
@@ -260,7 +276,11 @@ if ($action == 'thematic_list') {
     }
 } elseif ($action == 'thematic_import_select') {
     // Create form to upload csv file.
-    $form = new FormValidator('thematic_import', 'POST', 'index.php?action=thematic_import&'.api_get_cidreq().$url_token);
+    $form = new FormValidator(
+        'thematic_import',
+        'POST',
+        'index.php?action=thematic_import&'.api_get_cidreq().$url_token
+    );
     $form->addElement('header', get_lang('ImportThematic'));
     $form->addElement('file', 'file');
     $form->addElement('checkbox', 'replace', null, get_lang('DeleteAllThematic'));

+ 2 - 2
main/course_progress/thematic_advance.php

@@ -229,10 +229,10 @@ if ($action === 'thematic_advance_add' || $action === 'thematic_advance_edit') {
 } elseif ($action == 'thematic_advance_list') {
     // thematic advance list
     echo '<div class="actions">';
-    echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;action=thematic_details">'.
+    echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=thematic_details">'.
             Display::return_icon('back.png', get_lang("BackTo"), '', ICON_SIZE_MEDIUM).'</a>';
     if (api_is_allowed_to_edit(false, true)) {
-        echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;action=thematic_advance_add&amp;thematic_id='.$thematic_id.'"> '.
+        echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=thematic_advance_add&thematic_id='.$thematic_id.'"> '.
             Display::return_icon('add.png', get_lang('NewThematicAdvance'), '', ICON_SIZE_MEDIUM).'</a>';
     }
     echo '</div>';

+ 2 - 5
main/course_progress/thematic_controller.php

@@ -462,7 +462,6 @@ class ThematicController
                     $data['next_description_type'] = $thematic->get_next_description_type($_POST['thematic_id']);
 
                     // render to the view
-
                     $this->view->set_data($data);
                     $this->view->set_layout('layout');
                     $this->view->set_template('thematic_plan');
@@ -472,7 +471,6 @@ class ThematicController
         }
 
         $thematic_id = intval($_GET['thematic_id']);
-
         if ($action == 'thematic_plan_list') {
             $data['thematic_plan_data'] = $thematic->get_thematic_plan_data($thematic_id);
         }
@@ -525,7 +523,7 @@ class ThematicController
         $thematic = new Thematic();
         $attendance = new Attendance();
         $data = [];
-        $displayHeader = (!empty($_REQUEST['display']) && $_REQUEST['display'] === 'no_header') ? false : true;
+        $displayHeader = !empty($_REQUEST['display']) && $_REQUEST['display'] === 'no_header' ? false : true;
 
         // get data for attendance input select
         $attendance_list = $attendance->get_attendances_list();
@@ -536,9 +534,8 @@ class ThematicController
         }
 
         $thematic_id = intval($_REQUEST['thematic_id']);
-        $thematic_advance_id = isset($_REQUEST['thematic_advance_id']) ? intval($_REQUEST['thematic_advance_id']) : null;
+        $thematic_advance_id = isset($_REQUEST['thematic_advance_id']) ? (int) $_REQUEST['thematic_advance_id'] : null;
         $thematic_advance_data = [];
-
         switch ($action) {
             case 'thematic_advance_delete':
                 if (!empty($thematic_advance_id)) {

+ 21 - 3
main/coursecopy/copy_course.php

@@ -118,9 +118,27 @@ if (Security::check_token('post') && (
         $form->addGroup($group, '', get_lang('SelectOptionForBackup'));
 
         $group = [];
-        $group[] = $form->createElement('radio', 'same_file_name_option', null, get_lang('SameFilenameSkip'), FILE_SKIP);
-        $group[] = $form->createElement('radio', 'same_file_name_option', null, get_lang('SameFilenameRename'), FILE_RENAME);
-        $group[] = $form->createElement('radio', 'same_file_name_option', null, get_lang('SameFilenameOverwrite'), FILE_OVERWRITE);
+        $group[] = $form->createElement(
+            'radio',
+            'same_file_name_option',
+            null,
+            get_lang('SameFilenameSkip'),
+            FILE_SKIP
+        );
+        $group[] = $form->createElement(
+            'radio',
+            'same_file_name_option',
+            null,
+            get_lang('SameFilenameRename'),
+            FILE_RENAME
+        );
+        $group[] = $form->createElement(
+            'radio',
+            'same_file_name_option',
+            null,
+            get_lang('SameFilenameOverwrite'),
+            FILE_OVERWRITE
+        );
         $form->addGroup($group, '', get_lang('SameFilename'));
         $form->addProgress();
         $form->addButtonSave(get_lang('CopyCourse'));

+ 16 - 15
main/document/add_link.php

@@ -1,5 +1,6 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
  * This script allows to add cloud file links to the document structure.
  *
@@ -7,21 +8,22 @@
  */
 require_once __DIR__.'/../inc/global.inc.php';
 
-api_protect_course_script();
-
 $fileLinkEnabled = api_get_configuration_value('enable_add_file_link');
-
 if (!$fileLinkEnabled) {
     api_not_allowed(true);
 }
 
+api_protect_course_script();
+
 $courseInfo = api_get_course_info();
 
 if (empty($courseInfo)) {
     api_not_allowed(true);
 }
+
+$documentId = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0;
 $dir = '/';
-$document_data = DocumentManager::get_document_data_by_id($_REQUEST['id'], api_get_course_id(), true);
+$document_data = DocumentManager::get_document_data_by_id($documentId, api_get_course_id(), true);
 if (empty($document_data)) {
     $document_id = $parent_id = 0;
     $path = '/';
@@ -35,7 +37,6 @@ if (empty($document_data)) {
 }
 
 $is_certificate_mode = DocumentManager::is_certificate_mode($dir);
-
 if ($is_certificate_mode) {
     api_not_allowed(true);
 }
@@ -47,7 +48,7 @@ if (api_get_group_id()) {
     // If the group id is set, check if the user has the right to be here
     // Get group info
     $group_properties = GroupManager::get_group_properties(api_get_group_id());
-    if ($is_allowed_to_edit || GroupManager::is_user_in_group($_user['user_id'], api_get_group_id())) {
+    if ($is_allowed_to_edit || GroupManager::is_user_in_group(api_get_user_id(), $group_properties)) {
         // Only courseadmin or group members allowed
         $groupIid = $group_properties['iid'];
         $interbreadcrumb[] = [
@@ -173,15 +174,15 @@ echo DocumentManager::build_directory_selector(
 );
 
 // Add tooltip and correctly parse its inner HTML
-echo '<script>
-$(document).ready(function() {
-    $("[data-toggle=\'tooltip\']").tooltip({
-        content: 
-            function() {
-                return $(this).attr("title");
-            }
-    });
-});
+echo '<script>
+$(document).ready(function() {
+    $("[data-toggle=\'tooltip\']").tooltip({
+        content: 
+            function() {
+                return $(this).attr("title");
+            }
+    });
+});
 </script>';
 
 echo $form->returnForm();

+ 1 - 3
main/document/create_document.php

@@ -66,7 +66,7 @@ if ($is_certificate_mode) {
     $nameTools = get_lang('CreateDocument');
 }
 
-/*	Constants and variables */
+/* Constants and variables */
 $doc_table = Database::get_course_table(TABLE_DOCUMENT);
 $course_id = api_get_course_int_id();
 $courseCode = api_get_course_id();
@@ -115,8 +115,6 @@ if (empty($document_data)) {
     $dir = $document_data['path'];
 }
 
-/*	MAIN CODE */
-
 // Please, do not modify this dirname formatting
 if (strstr($dir, '..')) {
     $dir = '/';

+ 6 - 6
main/document/document.php

@@ -869,7 +869,7 @@ $htmlHeadXtra[] = '<script type="text/javascript" src="'.$js_path
     .'jquery-jplayer/jplayer/jquery.jplayer.min.js"></script>';
 $mediaplayer_path = api_get_path(WEB_LIBRARY_PATH).'mediaplayer/player.swf';
 
-$documentAndFolders = DocumentManager::get_all_document_data(
+$documentAndFolders = DocumentManager::getAllDocumentData(
     $courseInfo,
     $curdirpath,
     $groupIid,
@@ -1543,7 +1543,7 @@ if (isset($_GET['curdirpath']) &&
 
 /* GET ALL DOCUMENT DATA FOR CURDIRPATH */
 if (isset($_GET['keyword']) && !empty($_GET['keyword'])) {
-    $documentAndFolders = DocumentManager::get_all_document_data(
+    $documentAndFolders = DocumentManager::getAllDocumentData(
         $courseInfo,
         $curdirpath,
         $groupIid,
@@ -1552,7 +1552,7 @@ if (isset($_GET['keyword']) && !empty($_GET['keyword'])) {
         true
     );
 } else {
-    $documentAndFolders = DocumentManager::get_all_document_data(
+    $documentAndFolders = DocumentManager::getAllDocumentData(
         $courseInfo,
         $curdirpath,
         $groupIid,
@@ -1783,7 +1783,7 @@ $userIsSubscribed = CourseManager::is_user_subscribed_in_course(
 );
 
 $getSizeURL = api_get_path(WEB_AJAX_PATH).'document.ajax.php?a=get_dir_size&'.api_get_cidreq();
-if (isset($documentAndFolders) && is_array($documentAndFolders)) {
+if (!empty($documentAndFolders)) {
     if ($groupId == 0 || $userAccess) {
         $count = 1;
         $countedPaths = [];
@@ -1950,11 +1950,11 @@ if (isset($documentAndFolders) && is_array($documentAndFolders)) {
         }
     }
 } else {
-    $sortable_data = '';
+    $sortable_data = [];
     $table_footer = get_lang('NoDocsInFolder');
 }
 
-if (!is_null($documentAndFolders)) {
+if (!empty($documentAndFolders)) {
     // Show download zipped folder icon
     if (!$is_certificate_mode && $total_size != 0
         && (

+ 2 - 2
main/document/document_quota.php

@@ -79,8 +79,8 @@ if (!empty($group_list)) {
     }
 }
 // Showing weight of documents uploaded by user
-$document_list = DocumentManager::get_all_document_data($_course);
-if (is_array($document_list)) {
+$document_list = DocumentManager::getAllDocumentData($_course);
+if (!empty($document_list)) {
     foreach ($document_list as $document_data) {
         if ($document_data['insert_user_id'] == api_get_user_id() && $document_data['filetype'] == 'file') {
             $quota_bytes += $document_data['size'];

+ 2 - 3
main/document/document_slideshow.inc.php

@@ -38,12 +38,11 @@ if (isset($_GET['action']) && $_GET['action'] == 'exit_slideshow') {
 
 // We check if there are images in this folder by searching the extensions for .jpg, .gif, .png
 // grabbing the list of all the documents of this folder
-//$all_files = $fileList['name'];
 $array_to_search = !empty($documentAndFolders) && is_array($documentAndFolders) ? $documentAndFolders : [];
 
 if (count($array_to_search) > 0) {
-    while (list($key) = each($array_to_search)) {
-        $all_files[] = basename($array_to_search[$key]['path']);
+    foreach ($array_to_search as $file) {
+        $all_files[] = basename($file['path']);
     }
 }
 

+ 1 - 1
main/document/remote.php

@@ -66,7 +66,7 @@ if ($action == 'list') {
     }
 
     // get files list
-    $files = DocumentManager::get_all_document_data($_course, $cwd, 0, null, false);
+    $files = DocumentManager::getAllDocumentData($_course, $cwd, 0, null, false);
 
     // adding download link to files
     foreach ($files as $k => $f) {

+ 7 - 5
main/document/show_content.php

@@ -86,16 +86,18 @@ if (!api_is_allowed_to_edit() && !$is_visible) {
 }
 
 //TODO:clean all code
-/* Main section */
+
+/*	Main section */
 header('Expires: Wed, 01 Jan 1990 00:00:00 GMT');
 //header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
 header('Last-Modified: Wed, 01 Jan 2100 00:00:00 GMT');
 header('Cache-Control: no-cache, must-revalidate');
 header('Pragma: no-cache');
-$url = api_get_path(WEB_COURSE_PATH).$_course['path'].'/document'.$header_file.'?'.api_get_cidreq();
-$pathInfo = pathinfo($header_file);
+$browser_display_title = 'Documents - '.Security::remove_XSS($_GET['cidReq']).' - '.$file;
+$file_url_web = api_get_path(WEB_COURSE_PATH).$_course['path'].'/document'.$header_file.'?'.api_get_cidreq();
+$pathinfo = pathinfo($header_file);
 
-if ($pathInfo['extension'] == 'swf') {
+if ($pathinfo['extension'] == 'swf') {
     $width = '83%';
     $height = '83%';
 } else {
@@ -103,4 +105,4 @@ if ($pathInfo['extension'] == 'swf') {
     $height = '100%';
 }
 
-echo '<iframe border="0" frameborder="0" scrolling="no" style="width:'.$width.'; height:'.$height.';background-color:#ffffff;" id="mainFrame" name="mainFrame" src="'.$url.'?'.api_get_cidreq().'&amp;rand='.mt_rand(1, 1000).'"></iframe>';
+echo '<iframe border="0" frameborder="0" scrolling="no" style="width:'.$width.'; height:'.$height.';background-color:#ffffff;" id="mainFrame" name="mainFrame" src="'.$file_url_web.'?'.api_get_cidreq().'&amp;rand='.mt_rand(1, 1000).'"></iframe>';

+ 9 - 10
main/document/upload.php

@@ -88,13 +88,13 @@ $htmlHeadXtra[] = '<script>
 
 function check_unzip() {
     if (document.upload.unzip.checked){
-        document.upload.if_exists[0].disabled=true;
+        //document.upload.if_exists[0].disabled=true;
         document.upload.if_exists[1].checked=true;
-        document.upload.if_exists[2].disabled=true;
+        //document.upload.if_exists[2].disabled=true;
     } else {
-        document.upload.if_exists[0].checked=true;
-        document.upload.if_exists[0].disabled=false;
-        document.upload.if_exists[2].disabled=false;
+        document.upload.if_exists[2].checked=true;
+        //document.upload.if_exists[0].disabled=false;
+        //document.upload.if_exists[2].disabled=false;
     }
 }
 
@@ -205,7 +205,6 @@ if (!empty($_FILES)) {
     );
 
     $redirectUrl = api_get_self().'?'.api_get_cidreq().$certificateLink;
-
     if ($document_data) {
         $redirectUrl .= '&'.http_build_query(
             [
@@ -261,10 +260,10 @@ $form = new FormValidator(
 $form->addElement('hidden', 'id', $document_id);
 $form->addElement('hidden', 'curdirpath', $path);
 
-$course_quota = format_file_size(DocumentManager::get_course_quota() - DocumentManager::documents_total_space());
+$courseQuota = format_file_size(DocumentManager::get_course_quota() - DocumentManager::documents_total_space());
 $label =
     get_lang('MaxFileSize').': '.ini_get('upload_max_filesize').'<br/>'.
-    get_lang('DocumentQuota').': '.$course_quota;
+    get_lang('DocumentQuota').': '.$courseQuota;
 
 $form->addElement('file', 'file', [get_lang('File'), $label], 'style="width: 250px" id="user_upload"');
 $form->addElement('text', 'title', get_lang('Title'), ['id' => 'title_file']);
@@ -285,12 +284,12 @@ $form->addElement(
 
 if (api_get_setting('search_enabled') === 'true') {
     //TODO: include language file
-    $supported_formats = get_lang('SupportedFormatsForIndex').': HTML, PDF, TXT, PDF, Postscript, MS Word, RTF, MS Power Point';
+    $supportedFormats = get_lang('SupportedFormatsForIndex').': HTML, PDF, TXT, PDF, Postscript, MS Word, RTF, MS Power Point';
     $form->addElement(
         'checkbox',
         'index_document',
         '',
-        get_lang('SearchFeatureDoIndexDocument').'<div style="font-size: 80%" >'.$supported_formats.'</div>'
+        get_lang('SearchFeatureDoIndexDocument').'<div style="font-size: 80%" >'.$supportedFormats.'</div>'
     );
     $form->addElement('html', '<br /><div class="sub-form">');
     $form->addElement('html', '<div class="label">'.get_lang('SearchFeatureDocumentLanguage').'</div>');

+ 0 - 1
main/exercise/Annotation.php

@@ -112,7 +112,6 @@ class Annotation extends Question
      */
     public function createAnswersForm($form)
     {
-        // nothing
     }
 
     /**

+ 10 - 5
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 .= '<table class="'.$this->question_table_class.'">
-            <tr>
-                <th>'.get_lang('ElementList').'</th>
-                <th>'.get_lang('Status').'</th>
-            </tr>';
+        $header .= '<table class="'.$this->question_table_class.'"><tr>';
+
+        if ($exercise->showExpectedChoice()) {
+            $header .= '<th>'.get_lang('YourChoice').'</th>';
+            $header .= '<th>'.get_lang('ExpectedChoice').'</th>';
+        } else {
+            $header .= '<th>'.get_lang('ElementList').'</th>';
+        }
+        $header .= '<th>'.get_lang('Status').'</th>';
+        $header .= '</tr>';
 
         return $header;
     }

+ 13 - 6
main/exercise/MatchingDraggable.php

@@ -35,7 +35,7 @@ class MatchingDraggable extends Question
             $answer = new Answer($this->id);
             $answer->read();
 
-            if (count($answer->nbrAnswers) > 0) {
+            if (!empty($answer->nbrAnswers) && count($answer->nbrAnswers) > 0) {
                 for ($i = 1; $i <= $answer->nbrAnswers; $i++) {
                     $correct = $answer->isCorrect($i);
                     if (empty($correct)) {
@@ -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 .= '<table class="'.$this->question_table_class.'">
-                <tr>
-                    <th>'.get_lang('ElementList').'</th>
-                    <th>'.get_lang('CorrespondsTo').'</th>
-                </tr>';
+        $header .= '<table class="matching '.$this->question_table_class.'"><tr>';
+
+        $header .= '<th>'.get_lang('ElementList').'</th>';
+        if ($exercise->showExpectedChoice()) {
+            $header .= '<th>'.get_lang('YourChoice').'</th>';
+            $header .= '<th>'.get_lang('ExpectedChoice').'</th>';
+            $header .= '<th>'.get_lang('Status').'</th>';
+        } else {
+            $header .= '<th>'.get_lang('ElementList').'</th>';
+            $header .= '<th>'.get_lang('CorrespondsTo').'</th>';
+        }
+        $header .= '</tr>';
 
         return $header;
     }

+ 0 - 1
main/exercise/ReadingComprehension.php

@@ -150,7 +150,6 @@ class ReadingComprehension extends UniqueAnswer
         $my_id = isset($_REQUEST['myid']) ? intval($_REQUEST['myid']) : null;
         $form->addElement('hidden', 'myid', $my_id);
         $form->addRule('questionName', get_lang('GiveQuestion'), 'required');
-
         $isContent = isset($_REQUEST['isContent']) ? intval($_REQUEST['isContent']) : null;
 
         // default values

+ 30 - 24
main/exercise/TestCategory.php

@@ -641,37 +641,36 @@ 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 = (bool) $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 .= '<div class="page-header">';
+            $content .= '<h4>'.get_lang('Category').": ".self::getCategoryNameForQuestion($questionId).'</h4>';
+            $content .= "</div>";
         }
 
-        return Display::page_header(
-            get_lang('Category').': '.$categoryName,
-            null,
-            'h4'
-        );
+        return $content;
     }
 
     /**
@@ -1054,7 +1053,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)) {
@@ -1090,7 +1089,6 @@ class TestCategory
                 $cat_id = $category['iid'];
                 $return .= '<tr>';
                 $return .= '<td>';
-                //$return .= Display::div(isset($category['parent_path']) ? $category['parent_path'] : '');
                 $return .= Display::div($category['name']);
                 $return .= '</td>';
                 $return .= '<td>';
@@ -1279,13 +1277,21 @@ 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;
     }
 }

+ 27 - 1
main/exercise/UniqueAnswerImage.php

@@ -52,7 +52,8 @@ class UniqueAnswerImage extends UniqueAnswer
             $commentTitle = '<th >'.get_lang('Comment').'</th>';
         }
 
-        $html = '<div class="alert alert-success" role="alert">'.get_lang('UniqueAnswerImagePreferredSize200x150').'</div>';
+        $html = '<div class="alert alert-success" role="alert">'.
+                get_lang('UniqueAnswerImagePreferredSize200x150').'</div>';
         $html .= '<table class="table table-striped table-hover">
             <thead>
                 <tr style="text-align: center;">
@@ -368,4 +369,29 @@ 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 = '<table class="'.$this->question_table_class.'">
+			<tr>
+				<th>'.get_lang('Choice').'</th>
+				<th>'.get_lang('ExpectedChoice').'</th>
+				<th>'.get_lang('Answer').'</th>';
+            $header .= '<th>'.get_lang('Status').'</th>';
+            $header .= '<th>'.get_lang('Comment').'</th>';
+            $header .= '</tr>';
+        } else {
+            $header = parent::return_header($exercise, $counter, $score);
+        }
+
+        return $header;
+    }
 }

+ 3 - 37
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);
@@ -290,7 +279,7 @@ if (api_is_in_gradebook()) {
     ];
 }
 
-$interbreadcrumb[] = ["url" => "exercise.php?".api_get_cidreq(), "name" => get_lang('Exercises')];
+$interbreadcrumb[] = ["url" => "exercise.php?".api_get_cidreq(), 'name' => get_lang('Exercises')];
 if (isset($_GET['newQuestion']) || isset($_GET['editQuestion'])) {
     $interbreadcrumb[] = [
         "url" => "admin.php?exerciseId=".$objExercise->id.'&'.api_get_cidreq(),
@@ -317,25 +306,6 @@ if ($modifyIn == 'thisExercise') {
         $modifyIn = 'allExercises';
     }
 }
-$htmlHeadXtra[] = '<script>
-function multiple_answer_true_false_onchange(variable) {
-    var result = variable.checked;
-    var id = variable.id;
-    var weight_id = "weighting_" + id;
-    var array_result=new Array();
-    array_result[1]="1";
-    array_result[0]= "-0.50";
-    array_result[-1]= "0";
-    if (result) {
-        result = 1;
-    } else {
-        result = 0;
-    }
-    document.getElementById(weight_id).value = array_result[result];
-}
-
-</script>';
-
 $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 '</div>';
-
     if ($objExercise->added_in_lp()) {
         echo Display::return_message(get_lang('AddedToLPCannotBeAccessed'), 'warning');
     }
-
     echo '<div class="alert alert-info">';
     echo sprintf(
         get_lang('XQuestionsWithTotalScoreY'),
@@ -404,8 +372,7 @@ if ($inATest) {
     );
 
     if ($objExercise->random > 0) {
-        echo '<br />'.
-            sprintf(get_lang('OnlyXQuestionsPickedRandomly'), $objExercise->random);
+        echo '<br />'.sprintf(get_lang('OnlyXQuestionsPickedRandomly'), $objExercise->random);
     }
     echo '</div>';
 } elseif (isset($_GET['newQuestion'])) {
@@ -474,7 +441,6 @@ 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 (is_object($objQuestion) && $objExercise->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_EXAM && ($newQuestion || $modifyQuestion || $editQuestion)) {
 if ($objExercise->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_EXAM) {
     echo Display::return_message(get_lang('TestFeedbackNotShown'), 'normal');
 }

+ 15 - 13
main/exercise/answer.class.php

@@ -116,10 +116,10 @@ class Answer
      */
     public function read()
     {
-        $TBL_ANSWER = Database::get_course_table(TABLE_QUIZ_ANSWER);
+        $table = Database::get_course_table(TABLE_QUIZ_ANSWER);
         $questionId = $this->questionId;
 
-        $sql = "SELECT * FROM $TBL_ANSWER
+        $sql = "SELECT * FROM $table
                 WHERE
                     c_id = {$this->course_id} AND
                     question_id ='".$questionId."'
@@ -177,11 +177,11 @@ class Answer
      */
     public function selectAnswerId()
     {
-        $TBL_ANSWER = Database::get_course_table(TABLE_QUIZ_ANSWER);
+        $table = Database::get_course_table(TABLE_QUIZ_ANSWER);
         $questionId = $this->questionId;
 
         $sql = "SELECT id FROM
-              $TBL_ANSWER
+              $table
               WHERE c_id = {$this->course_id} AND question_id ='".$questionId."'";
 
         $result = Database::query($sql);
@@ -363,10 +363,9 @@ class Answer
      */
     public function selectAnswerByAutoId($auto_id)
     {
-        $TBL_ANSWER = Database::get_course_table(TABLE_QUIZ_ANSWER);
-
+        $table = Database::get_course_table(TABLE_QUIZ_ANSWER);
         $auto_id = intval($auto_id);
-        $sql = "SELECT id, answer, id_auto FROM $TBL_ANSWER
+        $sql = "SELECT id, answer, id_auto FROM $table
                 WHERE c_id = {$this->course_id} AND id_auto='$auto_id'";
         $rs = Database::query($sql);
 
@@ -474,8 +473,8 @@ class Answer
      */
     public function getQuestionType()
     {
-        $TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
-        $sql = "SELECT type FROM $TBL_QUESTIONS
+        $table = Database::get_course_table(TABLE_QUIZ_QUESTION);
+        $sql = "SELECT type FROM $table
                 WHERE c_id = {$this->course_id} AND id = '".$this->questionId."'";
         $res = Database::query($sql);
         if (Database::num_rows($res) <= 0) {
@@ -682,10 +681,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();
@@ -715,7 +712,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);
@@ -898,7 +900,7 @@ class Answer
                     $allAnswers[$this->id[$i]] = $this->answer[$i];
                 }
 
-                foreach ($temp as $index => $answer) {
+                foreach ($temp as $answer) {
                     if ($this->course['id'] != $course_info['id']) {
                         // check resources inside html from ckeditor tool and copy correct urls into recipient course
                         $answer['answer'] = DocumentManager::replaceUrlWithNewCourseCode(

+ 18 - 17
main/exercise/calculated_answer.class.php

@@ -32,18 +32,17 @@ class CalculatedAnswer extends Question
     public function createAnswersForm($form)
     {
         $defaults = [];
+        $defaults['answer'] = get_lang('DefaultTextInBlanks');
         if (!empty($this->id)) {
             $objAnswer = new Answer($this->id);
             $preArray = explode('@@', $objAnswer->selectAnswer(1));
             $defaults['formula'] = array_pop($preArray);
             $defaults['answer'] = array_shift($preArray);
-            $defaults['answer'] = preg_replace("/\[.*\]/", "", $defaults['answer']);
+            $defaults['answer'] = preg_replace("/\[.*\]/", '', $defaults['answer']);
             $defaults['weighting'] = $this->weighting;
-        } else {
-            $defaults['answer'] = get_lang('DefaultTextInBlanks');
         }
-        $lowestValue = "1.00";
-        $highestValue = "20.00";
+        $lowestValue = '1.00';
+        $highestValue = '20.00';
 
         // javascript //
         echo '<script>
@@ -79,7 +78,6 @@ class CalculatedAnswer extends Question
             });
 
             var firstTime = true;
-
             function updateBlanks(e) {
                 if (firstTime) {
                     field = document.getElementById("answer");
@@ -213,25 +211,24 @@ class CalculatedAnswer extends Question
                 if ($nb > 0) {
                     for ($i = 0; $i < $nb; ++$i) {
                         $blankItem = $blanks[0][$i];
-                        $replace = ["[", "]"];
-                        $newBlankItem = str_replace($replace, "", $blankItem);
-                        $newBlankItem = "[".trim($newBlankItem)."]";
+
                         // take random float values when one or both edge values have a decimal point
                         $randomValue =
                             (strpos($lowestValues[$i], '.') !== false ||
                             strpos($highestValues[$i], '.') !== false) ?
                             mt_rand($lowestValues[$i] * 100, $highestValues[$i] * 100) / 100 : mt_rand($lowestValues[$i], $highestValues[$i]);
+
                         $auxAnswer = str_replace($blankItem, $randomValue, $auxAnswer);
                         $auxFormula = str_replace($blankItem, $randomValue, $auxFormula);
                     }
                     $math = new EvalMath();
                     $result = $math->evaluate($auxFormula);
-                    $result = number_format($result, 2, ".", "");
+                    $result = number_format($result, 2, '.', '');
                     // Remove decimal trailing zeros
-                    $result = rtrim($result, "0");
+                    $result = rtrim($result, '0');
                     // If it is an integer (ends in .00) remove the decimal point
-                    if (mb_substr($result, -1) === ".") {
-                        $result = str_replace(".", "", $result);
+                    if (mb_substr($result, -1) === '.') {
+                        $result = str_replace('.', '', $result);
                     }
                     // Attach formula
                     $auxAnswer .= " [".$result."]@@".$formula;
@@ -251,10 +248,14 @@ class CalculatedAnswer extends Question
     public function return_header($exercise, $counter = null, $score = null)
     {
         $header = parent::return_header($exercise, $counter, $score);
-        $header .= '<table class="'.$this->question_table_class.'">
-            <tr>
-                <th>'.get_lang("Answer").'</th>
-            </tr>';
+        $header .= '<table class="'.$this->question_table_class.'"><tr>';
+        $header .= '<th>'.get_lang('Answer').'</th>';
+        if ($exercise->showExpectedChoice()) {
+            $header .= '<th>'.get_lang('YourChoice').'</th>';
+            $header .= '<th>'.get_lang('ExpectedChoice').'</th>';
+            $header .= '<th>'.get_lang('Status').'</th>';
+        }
+        $header .= '</tr>';
 
         return $header;
     }

+ 1 - 0
main/exercise/evalmathnotation.php

@@ -1,5 +1,6 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 require_once "../inc/global.inc.php";
 
 echo "<pre>".

File diff suppressed because it is too large
+ 374 - 213
main/exercise/exercise.class.php


+ 3 - 2
main/exercise/exercise.php

@@ -29,7 +29,7 @@ $this_section = SECTION_COURSES;
 api_protect_course_script(true);
 require_once 'hotpotatoes.lib.php';
 
-/* 	Constants and variables */
+/*  Constants and variables */
 $is_allowedToEdit = api_is_allowed_to_edit(null, true);
 $is_tutor = api_is_allowed_to_edit(true);
 $is_tutor_course = api_is_course_tutor();
@@ -72,6 +72,7 @@ Session::erase('objAnswer');
 Session::erase('questionList');
 Session::erase('exerciseResult');
 Session::erase('firstTime');
+Session::erase('calculatedAnswerId');
 
 //General POST/GET/SESSION/COOKIES parameters recovery
 $origin = api_get_origin();
@@ -298,7 +299,7 @@ if ($is_allowedToEdit) {
                         }
                         break;
                     case 'copy_exercise': //copy an exercise
-                        $objExerciseTmp->copy_exercise();
+                        $objExerciseTmp->copyExercise();
                         echo Display::return_message(
                             get_lang('ExerciseCopied'),
                             'confirmation'

+ 3 - 2
main/exercise/exercise_report.php

@@ -41,8 +41,9 @@ $documentPath = api_get_path(SYS_COURSE_PATH).$_course['path']."/document";
 $origin = api_get_origin();
 $path = isset($_GET['path']) ? Security::remove_XSS($_GET['path']) : null;
 
-/* 	Constants and variables */
-$is_allowedToEdit = api_is_allowed_to_edit(null, true) || api_is_drh() || api_is_student_boss();
+/* Constants and variables */
+
+$is_allowedToEdit = api_is_allowed_to_edit(null, true) || api_is_drh() || api_is_student_boss() || api_is_session_admin();
 $is_tutor = api_is_allowed_to_edit(true);
 
 $TBL_TRACK_EXERCISES = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);

+ 2 - 2
main/exercise/exercise_result.php

@@ -84,8 +84,6 @@ if ($origin != 'learnpath') {
     Display::display_reduced_header();
 }
 
-/* DISPLAY AND MAIN PROCESS */
-
 // I'm in a preview mode as course admin. Display the action menu.
 if (api_is_course_admin() && $origin != 'learnpath') {
     echo '<div class="actions">';
@@ -203,6 +201,7 @@ if ($origin != 'learnpath') {
     if (api_is_allowed_to_session_edit()) {
         Session::erase('objExercise');
         Session::erase('exe_id');
+        Session::erase('calculatedAnswerId');
     }
     Display::display_footer();
 } else {
@@ -213,6 +212,7 @@ if ($origin != 'learnpath') {
     if (api_is_allowed_to_session_edit()) {
         Session::erase('objExercise');
         Session::erase('exe_id');
+        Session::erase('calculatedAnswerId');
     }
 
     Session::write('attempt_remaining', $remainingMessage);

+ 71 - 54
main/exercise/exercise_show.php

@@ -88,8 +88,11 @@ $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : null;
 
 $courseInfo = api_get_course_info();
 $sessionId = api_get_session_id();
-$is_allowedToEdit = api_is_allowed_to_edit(null, true) || api_is_course_tutor() || api_is_session_admin()
-    || api_is_drh() || api_is_student_boss();
+$is_allowedToEdit = api_is_allowed_to_edit(null, true) ||
+    api_is_course_tutor() ||
+    api_is_session_admin() ||
+    api_is_drh() ||
+    api_is_student_boss();
 
 if (!empty($sessionId) && !$is_allowedToEdit) {
     if (api_is_course_session_coach(
@@ -149,7 +152,6 @@ $interbreadcrumb[] = [
 $interbreadcrumb[] = ['url' => '#', 'name' => get_lang('Result')];
 
 $this_section = SECTION_COURSES;
-
 $htmlHeadXtra[] = '<link rel="stylesheet" href="'.api_get_path(WEB_LIBRARY_JS_PATH).'hotspot/css/hotspot.css">';
 $htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_JS_PATH).'hotspot/js/hotspot.js"></script>';
 $htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_JS_PATH).'annotation/js/annotation.js"></script>';
@@ -234,44 +236,42 @@ if (!empty($track_exercise_info)) {
     // if the results_disabled of the Quiz is 1 when block the script
     $result_disabled = $track_exercise_info['results_disabled'];
 
-    if (true) {
-        if ($result_disabled == RESULT_DISABLE_NO_SCORE_AND_EXPECTED_ANSWERS) {
-            $show_results = false;
-        } elseif ($result_disabled == RESULT_DISABLE_SHOW_SCORE_ONLY) {
-            $show_results = false;
-            $show_only_total_score = true;
-            if ($origin != 'learnpath') {
-                if ($currentUserId == $student_id) {
-                    echo Display::return_message(
-                        get_lang('ThankYouForPassingTheTest'),
-                        'warning',
-                        false
-                    );
-                }
-            }
-        } elseif ($result_disabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
-            $attempts = Event::getExerciseResultsByUser(
-                $currentUserId,
-                $objExercise->id,
-                api_get_course_int_id(),
-                api_get_session_id(),
-                $track_exercise_info['orig_lp_id'],
-                $track_exercise_info['orig_lp_item_id'],
-                'desc'
-            );
-            $numberAttempts = count($attempts);
-            if ($numberAttempts >= $track_exercise_info['max_attempt']) {
-                $show_results = true;
-                $show_only_total_score = true;
-                // Attempt reach max so show score/feedback now
-                $showTotalScoreAndUserChoicesInLastAttempt = true;
-            } else {
-                $show_results = true;
-                $show_only_total_score = true;
-                // Last attempt not reach don't show score/feedback
-                $showTotalScoreAndUserChoicesInLastAttempt = false;
+    if ($result_disabled == RESULT_DISABLE_NO_SCORE_AND_EXPECTED_ANSWERS) {
+        $show_results = false;
+    } elseif ($result_disabled == RESULT_DISABLE_SHOW_SCORE_ONLY) {
+        $show_results = false;
+        $show_only_total_score = true;
+        if ($origin != 'learnpath') {
+            if ($currentUserId == $student_id) {
+                echo Display::return_message(
+                    get_lang('ThankYouForPassingTheTest'),
+                    'warning',
+                    false
+                );
             }
         }
+    } elseif ($result_disabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
+        $attempts = Event::getExerciseResultsByUser(
+            $currentUserId,
+            $objExercise->id,
+            api_get_course_int_id(),
+            api_get_session_id(),
+            $track_exercise_info['orig_lp_id'],
+            $track_exercise_info['orig_lp_item_id'],
+            'desc'
+        );
+        $numberAttempts = count($attempts);
+        if ($numberAttempts >= $track_exercise_info['max_attempt']) {
+            $show_results = true;
+            $show_only_total_score = true;
+            // Attempt reach max so show score/feedback now
+            $showTotalScoreAndUserChoicesInLastAttempt = true;
+        } else {
+            $show_results = true;
+            $show_only_total_score = true;
+            // Last attempt not reach don't show score/feedback
+            $showTotalScoreAndUserChoicesInLastAttempt = false;
+        }
     }
 } else {
     echo Display::return_message(get_lang('CantViewResults'), 'warning');
@@ -327,15 +327,15 @@ $sql = "SELECT attempts.question_id, answer
             attempts.exe_id = ".intval($id)." $user_restriction
 		GROUP BY quizz_rel_questions.question_order, attempts.question_id";
 $result = Database::query($sql);
-$question_list_from_database = [];
+$questionListFromDatabase = [];
 $exerciseResult = [];
 
 while ($row = Database::fetch_array($result)) {
-    $question_list_from_database[] = $row['question_id'];
+    $questionListFromDatabase[] = $row['question_id'];
     $exerciseResult[$row['question_id']] = $row['answer'];
 }
 
-//Fixing #2073 Fixing order of questions
+// Fixing #2073 Fixing order of questions
 if (!empty($track_exercise_info['data_tracking'])) {
     $temp_question_list = explode(',', $track_exercise_info['data_tracking']);
 
@@ -345,16 +345,16 @@ if (!empty($track_exercise_info['data_tracking'])) {
     }
     // If for some reason data_tracking is empty we select the question list from db
     if (empty($questionList)) {
-        $questionList = $question_list_from_database;
+        $questionList = $questionListFromDatabase;
     }
 } else {
-    $questionList = $question_list_from_database;
+    $questionList = $questionListFromDatabase;
 }
 
 // Display the text when finished message if we are on a LP #4227
-$end_of_message = $objExercise->selectTextWhenFinished();
-if (!empty($end_of_message) && ($origin == 'learnpath')) {
-    echo Display::return_message($end_of_message, 'normal', false);
+$endOfMessage = $objExercise->selectTextWhenFinished();
+if (!empty($endOfMessage) && ($origin == 'learnpath')) {
+    echo Display::return_message($endOfMessage, 'normal', false);
     echo "<div class='clear'>&nbsp;</div>";
 }
 
@@ -362,14 +362,15 @@ if (!empty($end_of_message) && ($origin == 'learnpath')) {
 $total_weighting = 0;
 foreach ($questionList as $questionId) {
     $objQuestionTmp = Question::read($questionId);
-    $total_weighting += $objQuestionTmp->selectWeighting();
+    if ($objQuestionTmp) {
+        $total_weighting += $objQuestionTmp->selectWeighting();
+    }
 }
 
 $counter = 1;
 $exercise_content = '';
 $category_list = [];
 $useAdvancedEditor = true;
-
 if (!empty($maxEditors) && count($questionList) > $maxEditors) {
     $useAdvancedEditor = false;
 }
@@ -381,9 +382,14 @@ foreach ($questionList as $questionId) {
     $choice = isset($exerciseResult[$questionId]) ? $exerciseResult[$questionId] : '';
     // destruction of the Question object
     unset($objQuestionTmp);
-
-    // creates a temporary Question object
+    $questionWeighting = 0;
+    $answerType = 0;
+    $questionScore = 0;
+    // Creates a temporary Question object
     $objQuestionTmp = Question::read($questionId);
+    if (empty($objQuestionTmp)) {
+        continue;
+    }
     $questionWeighting = $objQuestionTmp->selectWeighting();
     $answerType = $objQuestionTmp->selectType();
 
@@ -614,7 +620,7 @@ foreach ($questionList as $questionId) {
 
                 //showing the score
                 $queryfree = "SELECT marks from ".$TBL_TRACK_ATTEMPT." 
-                              WHERE exe_id = ".intval($id)." AND question_id= ".intval($questionId)."";
+                              WHERE exe_id = ".intval($id)." AND question_id= ".intval($questionId);
                 $resfree = Database::query($queryfree);
                 $questionScore = Database::result($resfree, 0, "marks");
                 $totalScore += $questionScore;
@@ -755,7 +761,6 @@ foreach ($questionList as $questionId) {
             }
             $feedback_form->setDefaults($default);
             $feedback_form->display();
-
             echo '</div>';
 
             if ($allowRecordAudio && $allowTeacherCommentAudio) {
@@ -907,7 +912,7 @@ foreach ($questionList as $questionId) {
 
     $contents = ob_get_clean();
     $question_content = '<div class="question_row">';
-    if ($show_results) {
+    if ($show_results && $objQuestionTmp) {
         $objQuestionTmp->export = $action == 'export';
         // Shows question title an description
         $question_content .= $objQuestionTmp->return_header(
@@ -1055,6 +1060,15 @@ if ($isFeedbackAllowed && $origin != 'learnpath' && $origin != 'student_progress
             .'&id_session='.api_get_session_id();
     }
 
+    Skill::addSkillsToUserForm(
+        $emailForm,
+        ITEM_TYPE_EXERCISE,
+        $exercise_id,
+        $student_id,
+        $track_exercise_info['exe_id'],
+        true
+    );
+
     $content = ExerciseLib::getEmailNotification(
         $currentUserId,
         api_get_course_info(),
@@ -1062,6 +1076,7 @@ if ($isFeedbackAllowed && $origin != 'learnpath' && $origin != 'student_progress
         $url
     );
     $emailForm->setDefaults(['notification_content' => $content]);
+
     $emailForm->addButtonSend(
         get_lang('CorrectTest'),
         'submit',
@@ -1124,3 +1139,5 @@ unset($questionList);
 
 Session::erase('exerciseResult');
 unset($exerciseResult);
+
+Session::erase('calculatedAnswerId');

+ 5 - 2
main/exercise/exercise_submit.php

@@ -1368,10 +1368,13 @@ if (!empty($error)) {
             false,
             $origin,
             $i,
-            true,
+            $objExercise->getHideQuestionTitle() ? false : true,
             false,
             $user_choice,
-            false
+            false,
+            null,
+            false,
+            true
         );
 
         // Button save and continue

+ 4 - 14
main/exercise/exercise_submit_modal.php

@@ -82,7 +82,6 @@ if (empty($choice_value)) {
         // this works for only radio buttons
         var f = self.parent.window.document.frm_exercise;
         var choice_js='';
-
         var hotspot = new Array();
         var hotspotcoord = new Array();
         var counter=0;
@@ -147,16 +146,6 @@ if (is_array($choice)) {
 Session::write('exerciseResult', $exerciseResult);
 Session::write('exerciseResultCoordinates', $exerciseResultCoordinates);
 
-/*
-// if it is the last question (only for a sequential exercise)
-if($questionNum >= $nbrQuestions)
-{
-    if($debug>0){echo str_repeat('&nbsp;',0).'Redirecting to exercise_result.php - Remove debug option to let this happen'."<br />\n";}
-    // goes to the script that will show the result of the exercise
-    // header("Location: exercise_result.php?origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id");
-    // echo 'location result';
-}*/
-
 // creates a temporary Question object
 if (in_array($questionid, $questionList)) {
     $objQuestionTmp = Question:: read($questionid);
@@ -224,7 +213,6 @@ if (!empty($choice_value)) {
         }
 
         if ($answerType == UNIQUE_ANSWER || $answerType == MULTIPLE_ANSWER) {
-            //display_unique_or_multiple_answer($answerType, $studentChoice, $answer, $answerComment, $answerCorrect);
             if ($studentChoice) {
                 $destination = $answerDestination;
                 $comment = $answerComment;
@@ -363,7 +351,7 @@ if (!empty($choice_value)) {
                     if (empty($_GET['hotspot'])) { //no user response
                         $overlap = false;
                     } else {
-                        //	poly_compile really works tested with gnuplot
+                        // poly_compile really works tested with gnuplot
                         $poly_user_compiled = poly_compile(
                             $poly_user,
                             $max_coord,
@@ -564,7 +552,9 @@ if ($destinationid == -1) {
                 'quiz.png',
                 '',
                 ['style' => 'padding-left:0px;padding-right:5px;']
-        ).'<a onclick="SendEx('.$num_value_array[0].');" href="#">'.get_lang('GoToQuestion').' '.$num_value_array[0].'</a><br /><br />';
+        );
+        $links .= '<a onclick="SendEx('.$num_value_array[0].');" href="#">'.
+            get_lang('GoToQuestion').' '.$num_value_array[0].'</a><br /><br />';
     }
 }
 

+ 30 - 21
main/exercise/fill_blanks.class.php

@@ -539,8 +539,6 @@ class FillBlanks extends Question
                     $resultOptions[sha1($item)] = $item;
                 }
 
-                //var_dump($resultOptions, $correctItem);
-
                 foreach ($resultOptions as $key => $value) {
                     if ($correctItem == $value) {
                         $selected = $key;
@@ -548,12 +546,19 @@ class FillBlanks extends Question
                         break;
                     }
                 }
+                $width = '';
+                if (!empty($attributes['style'])) {
+                    $width = str_replace('width:', '', $attributes['style']);
+                }
 
                 $result = Display::select(
                     "choice[$questionId][]",
                     $resultOptions,
                     $selected,
-                    ['class' => 'selectpicker'],
+                    [
+                        'class' => 'selectpicker',
+                        'data-width' => $width,
+                    ],
                     false
                 );
                 break;
@@ -677,7 +682,6 @@ class FillBlanks extends Question
                 $correctAnswer = api_html_entity_decode($correctAnswer);
                 $studentAnswer = htmlspecialchars($studentAnswer);
                 $result = $studentAnswer == self::trimOption($correctAnswer);
-
                 break;
         }
         //var_dump($result);
@@ -954,10 +958,10 @@ class FillBlanks extends Question
     {
         $outRes = 0;
         // for each student in group
-        foreach ($resultList as $userId => $tabValue) {
+        foreach ($resultList as $list) {
             $found = false;
             // for each bracket, if student has at least one answer ( choice > -2) then he pass the question
-            foreach ($tabValue as $i => $choice) {
+            foreach ($list as $choice) {
                 if ($choice > -2 && !$found) {
                     $outRes++;
                     $found = true;
@@ -1178,10 +1182,9 @@ class FillBlanks extends Question
         $listStudentAnswerInfo = self::getAnswerInfo($answer, true);
 
         if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
+            $resultsDisabled = true;
             if ($showTotalScoreAndUserChoices) {
                 $resultsDisabled = false;
-            } else {
-                $resultsDisabled = true;
             }
         }
 
@@ -1240,26 +1243,29 @@ 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 .= "<span style='color: green'>".$listPossibleAnswers[0]."</span>";
                 $correctAnswerHtml .= " <span style='font-weight:normal'>(";
@@ -1272,25 +1278,27 @@ class FillBlanks extends Question
                 $correctAnswerHtml .= ")</span>";
                 break;
             case self::FILL_THE_BLANK_SEVERAL_ANSWER:
-                $listCorrects = explode("||", $correct);
+                $listCorrects = explode('||', $correct);
                 $firstCorrect = $correct;
                 if (count($listCorrects) > 0) {
                     $firstCorrect = $listCorrects[0];
                 }
-                $correctAnswerHtml = "<span style='color: green'>".$firstCorrect."</span>";
+                $correctAnswerHtml = "<span class='feedback-green'>".$firstCorrect."</span>";
                 break;
             case self::FILL_THE_BLANK_STANDARD:
             default:
-                $correctAnswerHtml = "<span style='color: green'>".$correct."</span>";
+                $correctAnswerHtml = "<span class='feedback-green'>".$correct."</span>";
         }
 
         if ($hideExpectedAnswer) {
-            $correctAnswerHtml = "<span title='".get_lang("ExerciseWithFeedbackWithoutCorrectionComment")."'> - </span>";
+            $correctAnswerHtml = "<span 
+                class='feedback-green' 
+                title='".get_lang('ExerciseWithFeedbackWithoutCorrectionComment')."'> &#8212; </span>";
         }
 
-        $result = "<span style='border:1px solid black; border-radius:5px; padding:2px; font-weight:bold;'>";
-        $result .= "<span style='$style'>".$answer."</span>";
-        $result .= "&nbsp;<span style='font-size:120%;'>/</span>&nbsp;";
+        $result = "<span class='feedback-question'>";
+        $result .= $iconAnswer."<span class='$style'>".$answer."</span>";
+        $result .= "<span class='feedback-separator'> / </span>";
         $result .= $correctAnswerHtml;
         $result .= "</span>";
 
@@ -1332,6 +1340,7 @@ class FillBlanks extends Question
      * @param string $correct
      * @param string $feedbackType
      * @param bool   $resultsDisabled
+     * @param bool   $showTotalScoreAndUserChoices
      *
      * @return string
      */

+ 1 - 1
main/exercise/freeanswer.class.php

@@ -31,7 +31,7 @@ class FreeAnswer extends Question
     public function createAnswersForm($form)
     {
         $form->addElement('text', 'weighting', get_lang('Weighting'));
-        global $text, $class;
+        global $text;
         // setting the save button here and not in the question class.php
         $form->addButtonSave($text, 'submitQuestion');
         if (!empty($this->id)) {

+ 9 - 6
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 .= '<table class="'.$this->question_table_class.'">
-        <tr>
-            <th>'.get_lang("Choice").'</th>
-            <th>'.get_lang("ExpectedChoice").'</th>
-            <th>'.get_lang("Answer").'</th>';
-        $header .= '<th>'.get_lang("Comment").'</th>';
+        $header .= '<table class="'.$this->question_table_class.'"><tr>';
+
+        $header .= '<th>'.get_lang('Choice').'</th>';
+        $header .= '<th>'.get_lang('ExpectedChoice').'</th>';
+        $header .= '<th>'.get_lang('Answer').'</th>';
+        if ($exercise->showExpectedChoice()) {
+            $header .= '<th>'.get_lang('Status').'</th>';
+        }
+        $header .= '<th>'.get_lang('Comment').'</th>';
         $header .= '</tr>';
 
         return $header;

+ 6 - 2
main/exercise/hotpotatoes.lib.php

@@ -165,7 +165,10 @@ function WriteFileCont($full_file_path, $content)
 {
     // Check if this is not an attack, trying to get into other directories or something like that.
     $_course = api_get_course_info();
-    if (Security::check_abs_path(dirname($full_file_path).'/', api_get_path(SYS_COURSE_PATH).$_course['path'].'/')) {
+    if (Security::check_abs_path(
+        dirname($full_file_path).'/',
+        api_get_path(SYS_COURSE_PATH).$_course['path'].'/'
+    )) {
         // Check if this is not an attack, trying to upload a php file or something like that.
         if (basename($full_file_path) != Security::filter_filename(basename($full_file_path))) {
             return false;
@@ -497,7 +500,8 @@ function HotPotGCt($folder, $flag, $user_id)
         }
         closedir($dir);
     }
-    while (list(, $val) = each($filelist)) {
+
+    foreach ($filelist as $val) {
         if (stristr($val, $user_id.'.t.html')) {
             if ($flag == 1) {
                 my_delete($folder.'/'.$val);

+ 1 - 1
main/exercise/hotspot.class.php

@@ -68,7 +68,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');
         }
     }
 

+ 11 - 5
main/exercise/matching.class.php

@@ -42,7 +42,7 @@ class Matching extends Question
         if (isset($this->id)) {
             $answer = new Answer($this->id);
             $answer->read();
-            if (count($answer->nbrAnswers) > 0) {
+            if (!empty($answer->nbrAnswers) && count($answer->nbrAnswers) > 0) {
                 for ($i = 1; $i <= $answer->nbrAnswers; $i++) {
                     $correct = $answer->isCorrect($i);
                     if (empty($correct)) {
@@ -284,10 +284,16 @@ class Matching extends Question
     {
         $header = parent::return_header($exercise, $counter, $score);
         $header .= '<table class="'.$this->question_table_class.'">';
-        $header .= '<tr>
-                <th>'.get_lang('ElementList').'</th>
-                <th>'.get_lang('CorrespondsTo').'</th>
-              </tr>';
+        $header .= '<tr>';
+        $header .= '<th>'.get_lang('ElementList').'</th>';
+        if ($exercise->showExpectedChoice()) {
+            $header .= '<th>'.get_lang('YourChoice').'</th>';
+            $header .= '<th>'.get_lang('ExpectedChoice').'</th>';
+            $header .= '<th>'.get_lang('Status').'</th>';
+        } else {
+            $header .= '<th>'.get_lang('CorrespondsTo').'</th>';
+        }
+        $header .= '</tr>';
 
         return $header;
     }

+ 10 - 7
main/exercise/multiple_answer.class.php

@@ -39,7 +39,8 @@ class MultipleAnswer extends Question
             'Height' => '125',
         ];
 
-        $nb_answers = isset($_POST['nb_answers']) ? $_POST['nb_answers'] : 4; // The previous default value was 2. See task #1759.
+        // The previous default value was 2. See task #1759.
+        $nb_answers = isset($_POST['nb_answers']) ? $_POST['nb_answers'] : 4;
         $nb_answers += (isset($_POST['lessAnswers']) ? -1 : (isset($_POST['moreAnswers']) ? 1 : 0));
 
         $obj_ex = Session::read('objExercise');
@@ -229,12 +230,14 @@ class MultipleAnswer extends Question
     public function return_header($exercise, $counter = null, $score = null)
     {
         $header = parent::return_header($exercise, $counter, $score);
-        $header .= '<table class="'.$this->question_table_class.'">
-            <tr>
-                <th>'.get_lang("Choice").'</th>
-                <th>'.get_lang("ExpectedChoice").'</th>
-                <th>'.get_lang("Answer").'</th>';
-        $header .= '<th>'.get_lang("Comment").'</th>';
+        $header .= '<table class="'.$this->question_table_class.'"><tr>';
+        $header .= '<th>'.get_lang('Choice').'</th>';
+        $header .= '<th>'.get_lang('ExpectedChoice').'</th>';
+        $header .= '<th>'.get_lang('Answer').'</th>';
+        if ($exercise->showExpectedChoice()) {
+            $header .= '<th>'.get_lang('Status').'</th>';
+        }
+        $header .= '<th>'.get_lang('Comment').'</th>';
         $header .= '</tr>';
 
         return $header;

+ 9 - 7
main/exercise/multiple_answer_combination.class.php

@@ -199,8 +199,8 @@ class MultipleAnswerCombination extends Question
             if ($goodAnswer) {
                 $weighting = abs($weighting);
             } else {
+                // $weighting = -$weighting;
                 $weighting = abs($weighting);
-                //	$weighting = -$weighting;
             }
             if ($weighting > 0) {
                 $questionWeighting += $weighting;
@@ -228,12 +228,14 @@ class MultipleAnswerCombination extends Question
     public function return_header($exercise, $counter = null, $score = null)
     {
         $header = parent::return_header($exercise, $counter, $score);
-        $header .= '<table class="'.$this->question_table_class.'">
-            <tr>
-                <th>'.get_lang("Choice").'</th>
-                <th>'.get_lang("ExpectedChoice").'</th>
-                <th>'.get_lang("Answer").'</i></th>';
-        $header .= '<th>'.get_lang("Comment").'</th>';
+        $header .= '<table class="'.$this->question_table_class.'"><tr>
+                <th>'.get_lang('Choice').'</th>
+                <th>'.get_lang('ExpectedChoice').'</th>
+                <th>'.get_lang('Answer').'</i></th>';
+        if ($exercise->showExpectedChoice()) {
+            $header .= '<th>'.get_lang('Status').'</th>';
+        }
+        $header .= '<th>'.get_lang('Comment').'</th>';
         $header .= '</tr>';
 
         return $header;

+ 11 - 11
main/exercise/multiple_answer_true_false.class.php

@@ -63,7 +63,6 @@ class MultipleAnswerTrueFalse extends Question
         $form->addHeader(get_lang('Answers'));
         $form->addHtml($html);
 
-        $correct = 0;
         $answer = null;
 
         if (!empty($this->id)) {
@@ -268,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
@@ -292,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);
@@ -311,13 +309,15 @@ class MultipleAnswerTrueFalse extends Question
     public function return_header($exercise, $counter = null, $score = null)
     {
         $header = parent::return_header($exercise, $counter, $score);
-        $header .= '<table class="'.$this->question_table_class.'">
-        <tr>
-            <th>'.get_lang("Choice").'</th>
-            <th>'.get_lang("ExpectedChoice").'</th>
-            <th>'.get_lang("Answer").'</th>';
+        $header .= '<table class="'.$this->question_table_class.'"><tr>';
+        $header .= '<th>'.get_lang('Choice').'</th>
+            <th>'.get_lang('ExpectedChoice').'</th>
+            <th>'.get_lang('Answer').'</th>';
+        if ($exercise->showExpectedChoice()) {
+            $header .= '<th>'.get_lang('Status').'</th>';
+        }
         if ($exercise->feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
-            $header .= '<th>'.get_lang("Comment").'</th>';
+            $header .= '<th>'.get_lang('Comment').'</th>';
         } else {
             $header .= '<th>&nbsp;</th>';
         }

+ 3 - 1
main/exercise/oral_expression.class.php

@@ -262,7 +262,9 @@ class OralExpression extends Question
             mkdir($this->storePath.$this->sessionId.'/'.$this->exerciseId.'/'.$this->id);
         }
 
-        if (!empty($this->userId) && !is_dir($this->storePath.$this->sessionId.'/'.$this->exerciseId.'/'.$this->id.'/'.$this->userId)) {
+        if (!empty($this->userId) &&
+            !is_dir($this->storePath.$this->sessionId.'/'.$this->exerciseId.'/'.$this->id.'/'.$this->userId)
+        ) {
             mkdir($this->storePath.$this->sessionId.'/'.$this->exerciseId.'/'.$this->id.'/'.$this->userId);
         }
 

+ 1 - 5
main/exercise/overview.php

@@ -16,6 +16,7 @@ $current_course_tool = TOOL_QUIZ;
 
 // Clear the exercise session just in case
 Session::erase('objExercise');
+Session::erase('calculatedAnswerId');
 
 $this_section = SECTION_COURSES;
 
@@ -110,11 +111,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'])) {

+ 11 - 9
main/exercise/question.class.php

@@ -1654,7 +1654,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);
@@ -1781,8 +1780,8 @@ abstract class Question
 
         echo '<div class="well">';
         echo '<ul class="question_menu">';
-
         foreach ($question_type_custom_list as $i => $a_type) {
+            // @todo remove require_once classes are already loaded using composer
             // include the class of the type
             require_once $a_type[0];
             // get the picture of the type and the langvar which describes it
@@ -1934,9 +1933,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';
@@ -1972,13 +1971,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(
@@ -2295,7 +2297,7 @@ abstract class Question
      */
     public function returnFormatFeedback()
     {
-        return Display::return_message($this->feedback, 'normal', false);
+        return '<br />'.Display::return_message($this->feedback, 'normal', false);
     }
 
     /**

+ 0 - 2
main/exercise/question_admin.inc.php

@@ -54,9 +54,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

+ 1 - 1
main/exercise/question_list_admin.inc.php

@@ -144,7 +144,7 @@ $ajax_url = api_get_path(WEB_AJAX_PATH)."exercise.ajax.php?".api_get_cidreq()."&
 <?php
 
 //we filter the type of questions we can add
-Question:: display_type_menu($objExercise);
+Question::display_type_menu($objExercise);
 // Re sets the question list
 $objExercise->setQuestionList();
 

+ 0 - 1
main/exercise/question_pool.php

@@ -300,7 +300,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();

+ 8 - 8
main/exercise/unique_answer.class.php

@@ -58,7 +58,6 @@ class UniqueAnswer extends Question
          */
 
         $feedback_title = '';
-
         if ($obj_ex->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
             //Scenario
             $comment_title = '<th width="20%">'.get_lang('Comment').'</th>';
@@ -144,7 +143,6 @@ class UniqueAnswer extends Question
                 if (isset($answer->destination[$i])) {
                     $item_list = explode('@@', $answer->destination[$i]);
                 }
-
                 $try = isset($item_list[0]) ? $item_list[0] : '';
                 $lp = isset($item_list[1]) ? $item_list[1] : '';
                 $list_dest = isset($item_list[2]) ? $item_list[2] : '';
@@ -417,12 +415,14 @@ class UniqueAnswer extends Question
         $score = null
     ) {
         $header = parent::return_header($exercise, $counter, $score);
-        $header .= '<table class="'.$this->question_table_class.'">
-			<tr>
-				<th>'.get_lang("Choice").'</th>
-				<th>'.get_lang("ExpectedChoice").'</th>
-				<th>'.get_lang("Answer").'</th>';
-        $header .= '<th>'.get_lang("Comment").'</th>';
+        $header .= '<table class="'.$this->question_table_class.'"><tr>';
+        $header .= '<th>'.get_lang('Choice').'</th>';
+        $header .= '<th>'.get_lang('ExpectedChoice').'</th>';
+        $header .= '<th>'.get_lang('Answer').'</th>';
+        if ($exercise->showExpectedChoice()) {
+            $header .= '<th>'.get_lang('Status').'</th>';
+        }
+        $header .= '<th>'.get_lang('Comment').'</th>';
         $header .= '</tr>';
 
         return $header;

+ 12 - 19
main/exercise/unique_answer_no_option.class.php

@@ -41,8 +41,9 @@ class UniqueAnswerNoOption extends Question
             'Width' => '100%',
             'Height' => '125',
         ];
-        //this line define how many question by default appear when creating a choice question
-        $nb_answers = isset($_POST['nb_answers']) ? (int) $_POST['nb_answers'] : 3; // The previous default value was 2. See task #1759.
+        // This line define how many question by default appear when creating a choice question
+        // The previous default value was 2. See task #1759.
+        $nb_answers = isset($_POST['nb_answers']) ? (int) $_POST['nb_answers'] : 3;
         $nb_answers += (isset($_POST['lessAnswers']) ? -1 : (isset($_POST['moreAnswers']) ? 1 : 0));
 
         /*
@@ -53,7 +54,6 @@ class UniqueAnswerNoOption extends Question
          */
 
         $feedback_title = '';
-        $comment_title = '';
         if ($obj_ex->selectFeedbackType() == 1) {
             $editor_config['Width'] = '250';
             $editor_config['Height'] = '110';
@@ -117,8 +117,6 @@ class UniqueAnswerNoOption extends Question
             }
         }
 
-        $i = 1;
-        //for ($k = 1 ; $k <= $real_nb_answers; $k++) {
         foreach ($new_list as $key) {
             $i = $key;
             $form->addElement('html', '<tr>');
@@ -242,18 +240,12 @@ class UniqueAnswerNoOption extends Question
             ->freeze();
 
         $form->addElement('hidden', 'position['.$i.']', '666');
-
         $form->addElement('radio', 'correct', null, null, $i, ['class' => 'checkbox', 'disabled' => true]);
         $form->addElement('html_editor', 'answer['.$i.']', null, [], $editor_config);
 
         $form->addRule('answer['.$i.']', get_lang('ThisFieldIsRequired'), 'required');
         $form->addElement('html_editor', 'comment['.$i.']', null, [], $editor_config);
-
-        //$form->addElement('select', 'destination'.$i, get_lang('SelectQuestion').' : ',$select_question,'multiple');
-
-        $form
-            ->addElement('text', "weighting[$i]", null)
-            ->freeze();
+        $form->addElement('text', "weighting[$i]", null)->freeze();
 
         $form->addHTml('</tr>');
         $form->addHtml('</tbody></table>');
@@ -335,7 +327,6 @@ class UniqueAnswerNoOption extends Question
             {
                 $destination_str.=$destination_id.';';
             }*/
-
             $goodAnswer = ($correct == $i) ? true : false;
 
             if ($goodAnswer) {
@@ -409,12 +400,14 @@ class UniqueAnswerNoOption extends Question
     public function return_header($exercise, $counter = null, $score = null)
     {
         $header = parent::return_header($exercise, $counter, $score);
-        $header .= '<table class="'.$this->question_table_class.'">
-            <tr>
-                <th>'.get_lang("Choice").'</th>
-                <th>'.get_lang("ExpectedChoice").'</th>
-                <th>'.get_lang("Answer").'</th>';
-        $header .= '<th>'.get_lang("Comment").'</th>';
+        $header .= '<table class="'.$this->question_table_class.'"><tr>';
+        $header .= '<th>'.get_lang('Choice').'</th>';
+        $header .= '<th>'.get_lang('ExpectedChoice').'</th>';
+        $header .= '<th>'.get_lang('Answer').'</th>';
+        if ($exercise->showExpectedChoice()) {
+            $header .= '<th>'.get_lang('Status').'</th>';
+        }
+        $header .= '<th>'.get_lang('Comment').'</th>';
         $header .= '</tr>';
 
         return $header;

+ 8 - 7
main/forum/editpost.php

@@ -47,9 +47,10 @@ $origin = api_get_origin();
 
 // We are getting all the information about the current forum and forum category.
 // Note pcool: I tried to use only one sql statement (and function) for this,
-// but the problem is that the visibility of the forum AND forum cateogory are stored in the item_property table.
-$current_thread = get_thread_information($_GET['forum'], $_GET['thread']);
-$current_forum = get_forum_information($_GET['forum']);
+// but the problem is that the visibility of the forum AND forum category are stored in the item_property table.
+$forumId = isset($_GET['forum']) ? (int) $_GET['forum'] : 0;
+$current_thread = get_thread_information($forumId, $_GET['thread']);
+$current_forum = get_forum_information($forumId);
 $current_forum_category = get_forumcategory_information($current_forum['forum_category']);
 $current_post = get_post_information($_GET['post']);
 if (empty($current_post)) {
@@ -82,7 +83,7 @@ if ($origin == 'group') {
         'name' => get_lang('GroupSpace').' '.$group_properties['name'],
     ];
     $interbreadcrumb[] = [
-        'url' => api_get_path(WEB_CODE_PATH).'forum/viewforum.php?'.api_get_cidreq().'&forum='.intval($_GET['forum']),
+        'url' => api_get_path(WEB_CODE_PATH).'forum/viewforum.php?'.api_get_cidreq().'&forum='.$forumId,
         'name' => prepare4display($current_forum['forum_title']),
     ];
     $interbreadcrumb[] = ['url' => 'javascript: void (0);', 'name' => get_lang('EditPost')];
@@ -96,11 +97,11 @@ if ($origin == 'group') {
         'name' => prepare4display($current_forum_category['cat_title']),
     ];
     $interbreadcrumb[] = [
-        'url' => api_get_path(WEB_CODE_PATH).'forum/viewforum.php?forum='.intval($_GET['forum']).'&'.api_get_cidreq(),
+        'url' => api_get_path(WEB_CODE_PATH).'forum/viewforum.php?forum='.$forumId.'&'.api_get_cidreq(),
         'name' => prepare4display($current_forum['forum_title']),
     ];
     $interbreadcrumb[] = [
-        'url' => api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.api_get_cidreq().'&forum='.intval($_GET['forum']).'&thread='.intval($_GET['thread']),
+        'url' => api_get_path(WEB_CODE_PATH).'forum/viewthread.php?'.api_get_cidreq().'&forum='.$forumId.'&thread='.intval($_GET['thread']),
         'name' => prepare4display($current_thread['thread_title']),
     ];
     $interbreadcrumb[] = ['url' => 'javascript: void (0);', 'name' => get_lang('EditPost')];
@@ -196,7 +197,7 @@ if ($origin != 'learnpath') {
             ).
             '</a>';
     }
-    echo '<a href="viewforum.php?forum='.intval($_GET['forum']).'&'.api_get_cidreq().'">'.
+    echo '<a href="viewforum.php?forum='.$forumId.'&'.api_get_cidreq().'">'.
         Display::return_icon(
             'forum.png',
             get_lang('BackToForum'),

+ 11 - 2
main/forum/forumfunction.inc.php

@@ -53,6 +53,7 @@ $htmlHeadXtra[] = api_get_jquery_libraries_js(['jquery-ui', 'jquery-upload']);
 $threadId = isset($_REQUEST['thread']) ? intval($_REQUEST['thread']) : 0;
 $forumId = isset($_REQUEST['forum']) ? intval($_REQUEST['forum']) : 0;
 
+$ajaxUrl = api_get_path(WEB_AJAX_PATH).'forum.ajax.php?'.api_get_cidreq();
 // The next javascript script is to delete file by ajax
 $htmlHeadXtra[] = '<script>
 $(function () {
@@ -65,7 +66,7 @@ $(function () {
         if (confirm("'.get_lang('AreYouSureToDeleteJS').'", filename)) {
             $.ajax({
                 type: "POST",
-                url: "'.api_get_path(WEB_AJAX_PATH).'forum.ajax.php?'.api_get_cidreq().'&a=delete_file&attachId=" + id +"&thread='.$threadId.'&forum='.$forumId.'",
+                url: "'.$ajaxUrl.'&a=delete_file&attachId=" + id +"&thread='.$threadId.'&forum='.$forumId.'",
                 dataType: "json",
                 success: function(data) {
                     if (data.error == false) {
@@ -389,6 +390,10 @@ function show_add_forum_form($inputvalues = [], $lp_id)
         'filetype',
         ['jpg', 'jpeg', 'png', 'gif']
     );
+
+    //$forumId = isset($_GET['id']) ? (int) $_GET['id'] : 0;
+    //$skillList = Skill::addSkillsToForm($form, ITEM_TYPE_FORUM, $forumId);
+
     $form->addElement('html', '</div>');
 
     // The OK button
@@ -435,6 +440,9 @@ function show_add_forum_form($inputvalues = [], $lp_id)
         $defaults['public_private_group_forum_group']['public_private_group_forum'] = isset($inputvalues['forum_group_public_private']) ? $inputvalues['forum_group_public_private'] : null;
         $defaults['group_forum'] = isset($inputvalues['forum_of_group']) ? $inputvalues['forum_of_group'] : null;
     }
+
+    // $defaults['skills'] = array_keys($skillList);
+
     $form->setDefaults($defaults);
     // Validation or display
     if ($form->validate()) {
@@ -6169,7 +6177,7 @@ function clearAttachedFiles($postId = null, $courseId = null)
  *
  * @return array
  */
-function getAttachmentIdsByPostId($postId, $courseId = null)
+function getAttachmentIdsByPostId($postId, $courseId = 0)
 {
     $array = [];
     $courseId = intval($courseId);
@@ -6250,6 +6258,7 @@ function getForumCategoryByTitle($title, $courseId, $sessionId = 0)
 /**
  * @param array $current_forum
  * @param array $row
+ * @param bool  $addWrapper
  *
  * @return string
  */

+ 8 - 5
main/forum/reply.php

@@ -39,10 +39,12 @@ $threadId = isset($_GET['thread']) ? (int) $_GET['thread'] : 0;
 /* Retrieving forum and forum categorie information */
 // We are getting all the information about the current forum and forum category.
 // Note pcool: I tried to use only one sql statement (and function) for this,
-// but the problem is that the visibility of the forum AND forum cateogory are stored in the item_property table.
-$current_thread = get_thread_information($forumId, $threadId); // Note: This has to be validated that it is an existing thread.
-$current_forum = get_forum_information($current_thread['forum_id']); // Note: This has to be validated that it is an existing forum.
-$current_forum_category = get_forumcategory_information(Security::remove_XSS($current_forum['forum_category']));
+// but the problem is that the visibility of the forum AND forum category are stored in the item_property table.
+// Note: This has to be validated that it is an existing thread.
+$current_thread = get_thread_information($forumId, $threadId);
+// Note: This has to be validated that it is an existing forum.
+$current_forum = get_forum_information($current_thread['forum_id']);
+$current_forum_category = get_forumcategory_information($current_forum['forum_category']);
 
 /* Is the user allowed here? */
 // The user is not allowed here if
@@ -57,7 +59,8 @@ if (!api_is_allowed_to_edit(false, true) &&
     api_not_allowed(true);
 }
 if (!api_is_allowed_to_edit(false, true) &&
-    (($current_forum_category && $current_forum_category['locked'] != 0) || $current_forum['locked'] != 0 || $current_thread['locked'] != 0)
+    (($current_forum_category && $current_forum_category['locked'] != 0) ||
+        $current_forum['locked'] != 0 || $current_thread['locked'] != 0)
 ) {
     api_not_allowed(true);
 }

+ 6 - 4
main/forum/viewforumcategory.php

@@ -256,8 +256,8 @@ if ($action != 'add') {
                 // 1.v it is a not a group forum (teacher and student)
                 // 2.v it is a group forum and it is public (teacher and student)
                 // 3. it is a group forum and it is private (always for teachers only if the user is member of the forum
-                // if the forum is private and it is a group forum and the user is not a member of the group forum then it cannot be displayed
-                //if (!($forum['forum_group_public_private']=='private' AND !is_null($forum['forum_of_group']) AND !in_array($forum['forum_of_group'], $groups_of_user))) {
+                // if the forum is private and it is a group forum and the user
+                // is not a member of the group forum then it cannot be displayed
                 $show_forum = false;
                 // SHOULD WE SHOW THIS PARTICULAR FORUM
                 // you are teacher => show forum
@@ -268,7 +268,8 @@ if ($action != 'add') {
                 } else {
                     // you are not a teacher
                     //echo 'student';
-                    // it is not a group forum => show forum (invisible forums are already left out see get_forums function)
+                    // it is not a group forum => show forum
+                    // (invisible forums are already left out see get_forums function)
                     if ($forum['forum_of_group'] == '0') {
                         //echo '-gewoon forum';
                         $show_forum = true;
@@ -344,7 +345,8 @@ if ($action != 'add') {
                     $html .= '<div class="row">';
                     $html .= '<div class="col-md-6">';
                     $html .= '<div class="col-md-3">';
-                    $html .= '<div class="number-post">'.$forum_image.'<p>'.$my_number_threads.' '.get_lang('ForumThreads').'</p></div>';
+                    $html .= '<div class="number-post">'.$forum_image.
+                        '<p>'.$my_number_threads.' '.get_lang('ForumThreads').'</p></div>';
                     $html .= '</div>';
 
                     $html .= '<div class="col-md-9">';

+ 3 - 4
main/forum/viewpost.php

@@ -36,8 +36,8 @@ $origin = api_get_origin();
 // We are getting all the information about the current forum and forum category.
 // Note pcool: I tried to use only one sql statement (and function) for this,
 // but the problem is that the visibility of the forum AND forum category are stored in the item_property table.
-$current_thread = get_thread_information($_GET['forum'], $_GET['thread']); // Note: This has to be validated that it is an existing thread.
-$current_forum = get_forum_information($current_thread['forum_id']); // Note: This has to be validated that it is an existing forum.
+$current_thread = get_thread_information($_GET['forum'], $_GET['thread']);
+$current_forum = get_forum_information($current_thread['forum_id']);
 $current_forum_category = get_forumcategory_information($current_forum['forum_category']);
 $whatsnew_post_info = $_SESSION['whatsnew_post_info'];
 
@@ -133,6 +133,7 @@ if ($message != 'PostDeletedSpecial') {
             ) {
                 if ($current_forum['locked'] != 1 && $current_forum['locked'] != 1) {
                     echo '&nbsp;&nbsp;';
+                /*echo '<a href="newthread.php?'.api_get_cidreq().'&forum='.Security::remove_XSS($_GET['forum']).$origin_string.'">'.Display::return_icon('new_thread.png','','',ICON_SIZE_MEDIUM).'</a>';*/
                 } else {
                     echo get_lang('ForumLocked');
                 }
@@ -141,9 +142,7 @@ if ($message != 'PostDeletedSpecial') {
     }
     // Note: This is to prevent that some browsers display the links over the table (FF does it but Opera doesn't).
     echo '&nbsp;';
-
     /* Display Forum Category and the Forum information */
-
     if (!$_SESSION['view']) {
         $viewmode = $current_forum['default_view'];
     } else {

+ 6 - 7
main/forum/viewthread_flat.inc.php

@@ -64,9 +64,7 @@ if (isset($current_thread['thread_id'])) {
                 $current_thread['locked'] == 0 ||
                 api_is_allowed_to_edit(false, true)
             ) {
-                if ($_user['user_id'] ||
-                    ($current_forum['allow_anonymous'] == 1 && !$_user['user_id'])
-                ) {
+                if ($userId || ($current_forum['allow_anonymous'] == 1 && !$userId)) {
                     if ((api_is_anonymous() && $current_forum['allow_anonymous'] == 1) ||
                         (!api_is_anonymous() && api_is_allowed_to_session_edit(false, true))
                     ) {
@@ -175,7 +173,7 @@ if (isset($current_thread['thread_id'])) {
             // The course admin him/herself can do this off course always
             $groupInfo = GroupManager::get_group_properties($groupId);
             if ((isset($groupInfo['iid']) && GroupManager::is_tutor_of_group($userId, $groupInfo)) ||
-                ($current_forum['allow_edit'] == 1 && $row['user_id'] == $_user['user_id']) ||
+                ($current_forum['allow_edit'] == 1 && $posterId == $userId) ||
                 (
                 api_is_allowed_to_edit(false, true) &&
                 !(api_is_session_general_coach() && $current_forum['session_id'] != $sessionId)
@@ -317,7 +315,7 @@ if (isset($current_thread['thread_id'])) {
                 $post_image = Display::return_icon('forumpost.gif');
             }
 
-            if ($row['post_notification'] == '1' && $row['poster_id'] == $_user['user_id']) {
+            if ($row['post_notification'] == '1' && $row['poster_id'] == $userId) {
                 $post_image .= Display::return_icon('forumnotification.gif', get_lang('YouWillBeNotified'));
             }
             // The post title
@@ -330,8 +328,9 @@ if (isset($current_thread['thread_id'])) {
                     $html .= Display::return_icon('attachment.gif', get_lang('Attachment'));
                     $html .= '<a href="download.php?file='.$realname.'"> '.$user_filename.' </a>';
 
-                    if (($current_forum['allow_edit'] == 1 && $row['user_id'] == $_user['user_id']) ||
-                        (api_is_allowed_to_edit(false, true) && !(api_is_session_general_coach() && $current_forum['session_id'] != $sessionId))
+                    if (($current_forum['allow_edit'] == 1 && $posterId == $userId) ||
+                        (api_is_allowed_to_edit(false, true) &&
+                        !(api_is_session_general_coach() && $current_forum['session_id'] != $sessionId))
                     ) {
                         $html .= '&nbsp;&nbsp;<a href="'.api_get_self().'?'.api_get_cidreq().'&action=delete_attach&id_attach='
                             .$attachment['iid'].'&forum='.$clean_forum_id.'&thread='.$clean_thread_id

+ 2 - 1
main/forum/viewthread_threaded.inc.php

@@ -419,7 +419,8 @@ if (!empty($attachment_list) && is_array($attachment_list)) {
             Security::remove_XSS($attachment['comment'], STUDENT).'</span>';
 
         if (($current_forum['allow_edit'] == 1 && $rows[$display_post_id]['user_id'] == $_user['user_id']) ||
-            (api_is_allowed_to_edit(false, true) && !(api_is_session_general_coach() && $current_forum['session_id'] != $sessionId))
+            (api_is_allowed_to_edit(false, true) &&
+            !(api_is_session_general_coach() && $current_forum['session_id'] != $sessionId))
         ) {
             echo '&nbsp;&nbsp;<a href="'.api_get_self().'?'.
                 api_get_cidreq().'&action=delete_attach&id_attach='.$attachment['id'].'&forum='.$forumId.

+ 32 - 12
main/glossary/index.php

@@ -43,7 +43,7 @@ function sorter($item1, $item2)
 }
 
 // Displaying the header
-$action = isset($_GET['action']) ? $_GET['action'] : '';
+$action = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : '';
 $currentUrl = api_get_self().'?'.api_get_cidreq();
 $interbreadcrumb[] = ['url' => 'index.php?'.api_get_cidreq(), 'name' => get_lang('Glossary')];
 
@@ -58,7 +58,7 @@ switch ($action) {
         $form = new FormValidator(
             'glossary',
             'post',
-            api_get_self().'?action='.Security::remove_XSS($_GET['action']).'&'.api_get_cidreq()
+            api_get_self().'?action=addglossary&'.api_get_cidreq()
         );
         // Setting the form elements
         $form->addElement('header', get_lang('TermAddNew'));
@@ -98,7 +98,16 @@ switch ($action) {
             $token = Security::get_token();
             $form->addElement('hidden', 'sec_token');
             $form->setConstants(['sec_token' => $token]);
-            $content = $form->returnForm();
+            $content = Display::toolbarAction(
+                'add_glossary',
+                [
+                    Display::url(
+                        Display::return_icon('back.png', get_lang('Back'), [], ICON_SIZE_MEDIUM),
+                        api_get_self().'?'.api_get_cidreq()
+                    ),
+                ]
+            );
+            $content .= $form->returnForm();
         }
         break;
     case 'edit_glossary':
@@ -106,12 +115,13 @@ switch ($action) {
             api_not_allowed(true);
         }
         $tool_name = get_lang('Edit');
-        if (is_numeric($_GET['glossary_id'])) {
+        $glossaryId = isset($_GET['glossary_id']) ? (int) $_GET['glossary_id'] : 0;
+        if (!empty($glossaryId)) {
             // initiate the object
             $form = new FormValidator(
                 'glossary',
                 'post',
-                api_get_self().'?action='.Security::remove_XSS($_GET['action']).'&glossary_id='.intval($_GET['glossary_id']).'&'.api_get_cidreq()
+                api_get_self().'?action=edit_glossary&glossary_id='.$glossaryId.'&'.api_get_cidreq()
             );
             // Setting the form elements
             $form->addElement('header', get_lang('TermEdit'));
@@ -137,7 +147,7 @@ switch ($action) {
             );
 
             // setting the defaults
-            $glossary_data = GlossaryManager::get_glossary_information($_GET['glossary_id']);
+            $glossary_data = GlossaryManager::get_glossary_information($glossaryId);
 
             // Date treatment for timezones
             if (!empty($glossary_data['insert_date'])) {
@@ -175,7 +185,16 @@ switch ($action) {
                 $token = Security::get_token();
                 $form->addElement('hidden', 'sec_token');
                 $form->setConstants(['sec_token' => $token]);
-                $content = $form->returnForm();
+                $content = Display::toolbarAction(
+                    'edit_glossary',
+                    [
+                        Display::url(
+                            Display::return_icon('back.png', get_lang('Back'), [], ICON_SIZE_MEDIUM),
+                            api_get_self().'?'.api_get_cidreq()
+                        ),
+                    ]
+                );
+                $content .= $form->returnForm();
             }
         }
         break;
@@ -206,7 +225,7 @@ switch ($action) {
             'post',
             api_get_self().'?action=import&'.api_get_cidreq()
         );
-        $form->addElement('header', '', get_lang('ImportGlossary'));
+        $form->addHeader('header', get_lang('ImportGlossary'));
         $form->addElement('file', 'file', get_lang('ImportCSVFileLocation'));
         $form->addElement('checkbox', 'replace', null, get_lang('DeleteAllGlossaryTerms'));
         $form->addElement('checkbox', 'update', null, get_lang('UpdateExistingGlossaryTerms'));
@@ -222,13 +241,12 @@ switch ($action) {
 
         if ($form->validate()) {
             $termsDeleted = [];
-
             //this is a bad idea //jm
             if (isset($_POST['replace']) && $_POST['replace']) {
                 foreach (GlossaryManager::get_glossary_terms() as $term) {
                     if (!GlossaryManager::delete_glossary($term['id'], false)) {
                         Display::addFlash(
-                            Display::return_message(get_lang("CannotDeleteGlossary").':'.$term['id'], 'error')
+                            Display::return_message(get_lang('CannotDeleteGlossary').':'.$term['id'], 'error')
                         );
                     } else {
                         $termsDeleted[] = $term['name'];
@@ -237,8 +255,7 @@ switch ($action) {
             }
 
             $updateTerms = isset($_POST['update']) && $_POST['update'] ? true : false;
-
-            $data = Import::csv_reader($_FILES['file']['tmp_name']);
+            $data = Import::csvToArray($_FILES['file']['tmp_name']);
             $goodList = [];
             $updatedList = [];
             $addedList = [];
@@ -250,6 +267,9 @@ switch ($action) {
             if ($data) {
                 $termsToAdd = [];
                 foreach ($data as $item) {
+                    if (!isset($item['term'])) {
+                        continue;
+                    }
                     $items = [
                         'name' => $item['term'],
                         'description' => $item['definition'],

+ 8 - 10
main/gradebook/gradebook_display_summary.php

@@ -21,9 +21,15 @@ GradebookUtils::block_students();
 $cat_id = isset($_GET['selectcat']) ? (int) $_GET['selectcat'] : null;
 $action = isset($_GET['action']) && $_GET['action'] ? $_GET['action'] : null;
 
+$sessionId = api_get_session_id();
+$statusToFilter = empty($sessionId) ? STUDENT : 0;
+
 $userList = CourseManager::get_user_list_from_course_code(
     api_get_course_id(),
-    api_get_session_id()
+    $sessionId,
+    null,
+    null,
+    $statusFilter
 );
 
 switch ($action) {
@@ -33,17 +39,9 @@ switch ($action) {
 
         $pdfList = [];
         $cats = Category::load($cat_id, null, null, null, null, null, false);
-
-        $session_id = api_get_session_id();
-        if (empty($session_id)) {
-            $statusToFilter = STUDENT;
-        } else {
-            $statusToFilter = 0;
-        }
-
         $studentList = CourseManager::get_user_list_from_course_code(
             api_get_course_id(),
-            $session_id,
+            $sessionId,
             null,
             null,
             $statusToFilter

+ 4 - 2
main/gradebook/lib/GradebookUtils.php

@@ -257,13 +257,15 @@ class GradebookUtils
                             $modify_icons .= '&nbsp;<a onclick="javascript:if (!confirm(\''.addslashes(get_lang('ConfirmToUnlockElement')).'\')) return false;" href="'.api_get_self().'?'.api_get_cidreq().'&category_id='.$cat->get_id().'&action=unlock">'.
                                 Display::return_icon('lock.png', get_lang('UnLockEvaluation'), '', ICON_SIZE_SMALL).'</a>';
                         } else {
-                            $modify_icons .= '&nbsp;<a href="#">'.Display::return_icon('lock_na.png', get_lang('GradebookLockedAlert'), '', ICON_SIZE_SMALL).'</a>';
+                            $modify_icons .= '&nbsp;<a href="#">'.
+                                Display::return_icon('lock_na.png', get_lang('GradebookLockedAlert'), '', ICON_SIZE_SMALL).'</a>';
                         }
                         $modify_icons .= '&nbsp;<a href="gradebook_flatview.php?export_pdf=category&selectcat='.$cat->get_id().'" >'.Display::return_icon('pdf.png', get_lang('ExportToPDF'), '', ICON_SIZE_SMALL).'</a>';
                     } else {
                         $modify_icons .= '&nbsp;<a onclick="javascript:if (!confirm(\''.addslashes(get_lang('ConfirmToLockElement')).'\')) return false;" href="'.api_get_self().'?'.api_get_cidreq().'&category_id='.$cat->get_id().'&action=lock">'.
                             Display::return_icon('unlock.png', get_lang('LockEvaluation'), '', ICON_SIZE_SMALL).'</a>';
-                        $modify_icons .= '&nbsp;<a href="#" >'.Display::return_icon('pdf_na.png', get_lang('ExportToPDF'), '', ICON_SIZE_SMALL).'</a>';
+                        $modify_icons .= '&nbsp;<a href="#" >'.
+                            Display::return_icon('pdf_na.png', get_lang('ExportToPDF'), '', ICON_SIZE_SMALL).'</a>';
                     }
                 }
 

+ 2 - 2
main/gradebook/lib/be/category.class.php

@@ -789,9 +789,9 @@ class Category implements GradebookItem
      */
     public function show_message_resource_delete($course_id)
     {
-        $tbl_grade_categories = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
+        $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
         $sql = 'SELECT count(*) AS num 
-                FROM '.$tbl_grade_categories.'
+                FROM '.$table.'
                 WHERE
                     c_id = "'.Database::escape_string($course_id).'" AND
                     visible = 3';

+ 31 - 34
main/gradebook/lib/fe/scoredisplayform.class.php

@@ -23,28 +23,29 @@ class ScoreDisplayForm extends FormValidator
         $customdisplays = $displayscore->get_custom_score_display_settings();
 
         $nr_items = (count($customdisplays) != '0') ? count($customdisplays) : '1';
-        $this->setDefaults([
-            'scorecolpercent' => $displayscore->get_color_split_value(),
-        ]);
+        $this->setDefaults(
+            [
+                'scorecolpercent' => $displayscore->get_color_split_value(),
+            ]
+        );
 
         $this->addElement('hidden', 'maxvalue', '100');
         $this->addElement('hidden', 'minvalue', '0');
         $counter = 1;
 
-        //setting the default values
-
+        // Setting the default values
         if (is_array($customdisplays)) {
             foreach ($customdisplays as $customdisplay) {
-                $this->setDefaults([
-                    'endscore['.$counter.']' => $customdisplay['score'],
-                    'displaytext['.$counter.']' => $customdisplay['display'],
-                ]);
+                $this->setDefaults(
+                    [
+                        'endscore['.$counter.']' => $customdisplay['score'],
+                        'displaytext['.$counter.']' => $customdisplay['display'],
+                    ]
+                );
                 $counter++;
             }
         }
-        $scorecol = [];
-
-        //settings for the colored score
+        // Settings for the colored score
         $this->addElement('header', get_lang('ScoreEdit'));
 
         if ($displayscore->is_coloring_enabled()) {
@@ -69,8 +70,7 @@ class ScoreDisplayForm extends FormValidator
             $this->addRule(['scorecolpercent', 'minvalue'], get_lang('UnderMin'), 'compare', '>');
         }
 
-        //Settings for the scoring system
-
+        // Settings for the scoring system
         if ($displayscore->is_custom()) {
             $this->addElement('html', '<br /><b>'.get_lang('ScoringSystem').'</b>');
             $this->addElement('static', null, null, get_lang('ScoreInfo'));
@@ -87,30 +87,23 @@ class ScoreDisplayForm extends FormValidator
             for ($counter = 1; $counter <= 20; $counter++) {
                 $renderer = &$this->defaultRenderer();
                 $elementTemplateTwoLabel =
-                '<div id='.$counter.' style="display: '.(($counter <= $nr_items) ? 'inline' : 'none').';">
-    
-                <!-- BEGIN required --><span class="form_required">*</span> <!-- END required -->
-    
+                '<div id='.$counter.' style="display: '.(($counter <= $nr_items) ? 'inline' : 'none').';">    
+                <!-- BEGIN required --><span class="form_required">*</span> <!-- END required -->    
                 <label class="control-label">{label}</label>
                 <div class="form-group">
                 <label class="col-sm-2 control-label">
-                </label>
-    
+                </label>    
                 <div class="col-sm-1">
                 <!-- BEGIN error --><span class="form_error">{error}</span><br />
                 <!-- END error -->&nbsp<b>'.get_lang('And').'</b>
                 </div>
-    
+                    
                 <div class="col-sm-2">
                 {element}
-                </div>
-    
+                </div>    
                 <div class="col-sm-1">
                 =
-                </div>
-    
-    
-                ';
+                </div>';
 
                 $elementTemplateTwoLabel2 = '
                 <div class="col-sm-2">
@@ -127,13 +120,17 @@ class ScoreDisplayForm extends FormValidator
                 </div>
                 </div>';
 
-                $scorebetw = [];
-                $this->addElement('text', 'endscore['.$counter.']', null, [
-                    'size' => 5,
-                    'maxlength' => 5,
-                    'id' => 'txta-'.$counter,
-                    'input-size' => 2,
-                ]);
+                $this->addElement(
+                    'text',
+                    'endscore['.$counter.']',
+                    null,
+                    [
+                        'size' => 5,
+                        'maxlength' => 5,
+                        'id' => 'txta-'.$counter,
+                        'input-size' => 2,
+                    ]
+                );
 
                 $this->addElement(
                     'text',

+ 8 - 3
main/gradebook/lib/fe/userform.class.php

@@ -20,8 +20,8 @@ class UserForm extends FormValidator
      * @param int form_type 1 = user_info
      * @param user array
      * @param string form name
-     * @param method
-     * @param action
+     * @param string $method
+     * @param string $action
      */
     public function __construct($form_type, $user, $form_name, $method = 'post', $action = null)
     {
@@ -74,7 +74,12 @@ class UserForm extends FormValidator
             $this->addElement('static', 'fname', get_lang('FirstName'), $this->user_info['firstname']);
         }
         $this->addElement('static', 'uname', get_lang('UserName'), $this->user_info['username']);
-        $this->addElement('static', 'email', get_lang('Email'), '<a href="mailto:'.$this->user_info['email'].'">'.$this->user_info['email'].'</a>');
+        $this->addElement(
+            'static',
+            'email',
+            get_lang('Email'),
+            '<a href="mailto:'.$this->user_info['email'].'">'.$this->user_info['email'].'</a>'
+        );
         $this->addElement('static', 'ofcode', get_lang('OfficialCode'), $this->user_info['official_code']);
         $this->addElement('static', 'phone', get_lang('Phone'), $this->user_info['phone']);
         $this->addButtonSave(get_lang('Back'), 'submit');

+ 6 - 6
main/gradebook/lib/fe/usertable.class.php

@@ -128,15 +128,15 @@ class UserTable extends SortableTable
             // evaluation
             case 'E':
                 return '&nbsp;'
-                .'<a href="gradebook_view_result.php?selecteval='.$item->get_id().'&'.api_get_cidreq().'">'
-                .$item->get_name()
-                .'</a>';
+                    .'<a href="gradebook_view_result.php?selecteval='.$item->get_id().'&'.api_get_cidreq().'">'
+                    .$item->get_name()
+                    .'</a>';
             // link
             case 'L':
                 return '&nbsp;<a href="'.$item->get_link().'">'
-                .$item->get_name()
-                .'</a>'
-                .'&nbsp;['.$item->get_type_name().']';
+                    .$item->get_name()
+                    .'</a>'
+                    .'&nbsp;['.$item->get_type_name().']';
         }
     }
 }

+ 2 - 1
main/gradebook/lib/gradebook_data_generator.class.php

@@ -118,7 +118,8 @@ class GradebookDataGenerator
             $row = [];
             $row[] = $item;
             $row[] = $item->get_name();
-            // display the 2 first line of description, and all description on mouseover (https://support.chamilo.org/issues/6588)
+            // display the 2 first line of description and all description
+            // on mouseover (https://support.chamilo.org/issues/6588)
             $row[] = '<span title="'.api_remove_tags_with_space($item->get_description()).'">'.
                 api_get_short_text_from_html($item->get_description(), 160).'</span>';
             $totalWeight += $item->get_weight();

+ 6 - 4
main/gradebook/lib/scoredisplay.class.php

@@ -263,19 +263,21 @@ class ScoreDisplay
     /**
      * Formats a number depending of the number of decimals.
      *
-     * @param float $score
-     * @param bool  $ignoreDecimals
+     * @param float  $score
+     * @param bool   $ignoreDecimals
+     * @param string $decimalSeparator
+     * @param string $thousandSeparator
      *
      * @return float the score formatted
      */
-    public function format_score($score, $ignoreDecimals = false)
+    public function format_score($score, $ignoreDecimals = false, $decimalSeparator = '.', $thousandSeparator = ',')
     {
         $decimals = $this->get_number_decimals();
         if ($ignoreDecimals) {
             $decimals = 0;
         }
 
-        return api_number_format($score, $decimals);
+        return api_number_format($score, $decimals, $decimalSeparator, $thousandSeparator);
     }
 
     /**

+ 1 - 1
main/group/example.csv

@@ -1,4 +1,4 @@
-"category";"group";"description";"announcements_state";"calendar_state";"chat_state";"doc_state";"forum_state";"work_state";"wiki_state";"max_student";"self_reg_allowed";"self_unreg_allowed";"groups_per_user";"students";"tutors"
+"category";"group";"description";"announcements_state";"calendar_state";"chat_state";"doc_state";"forum_state";"work_state";"wiki_state";"max_student";"self_reg_allowed";"self_unreg_allowed";"groups_per_user";"students";"tutors"
 "Category 1";"";"This is a category";"2";"2";"2";"2";"2";"2";"2";"0";"0";"0";"0";
 "";"Group 1";"This is a group with no category";"2";"2";"2";"2";"2";"2";"2";"0";"0";"0";"";"username1,username2";"username3,username4"
 "Category 1";"Group 2";"This is a group in a category 1";"2";"2";"2";"2";"2";"2";"2";"0";"0";"0";"";"username1,username2";"username3,username4"

Some files were not shown because too many files changed in this diff