Browse Source

Minor - update from 1.11.x

Julio Montoya 6 years ago
parent
commit
1a8a38b41a
45 changed files with 483 additions and 241 deletions
  1. 1 1
      main/admin/dashboard_add_users_to_user.php
  2. 2 0
      main/admin/email_tester.php
  3. 18 5
      main/admin/index.php
  4. 4 4
      main/admin/languages.php
  5. 1 0
      main/admin/promotions.php
  6. 3 5
      main/admin/subscribe_user2course.php
  7. 5 2
      main/admin/teacher_time_report.php
  8. 1 1
      main/attendance/attendance_controller.php
  9. 1 1
      main/attendance/attendance_sheet.php
  10. 1 0
      main/attendance/index.php
  11. 1 14
      main/auth/courses.php
  12. 4 0
      main/auth/courses_categories.php
  13. 2 6
      main/auth/courses_controller.php
  14. 2 3
      main/auth/inscription.php
  15. 1 5
      main/course_home/activity.php
  16. 0 1
      main/course_progress/index.php
  17. 21 1
      main/cron/import_csv.php
  18. 0 2
      main/exercise/exercise.php
  19. 5 3
      main/exercise/question_pool.php
  20. 4 3
      main/gradebook/index.php
  21. 29 7
      main/gradebook/lib/be/category.class.php
  22. 13 9
      main/gradebook/lib/fe/gradebooktable.class.php
  23. 3 3
      main/inc/ajax/message.ajax.php
  24. 17 8
      main/inc/lib/AnnouncementManager.php
  25. 4 4
      main/inc/lib/attendance.lib.php
  26. 6 1
      main/inc/lib/certificate.lib.php
  27. 18 13
      main/inc/lib/course_home.lib.php
  28. 6 5
      main/inc/lib/formvalidator/Element/DateRangePicker.php
  29. 2 3
      main/inc/lib/formvalidator/Element/HtmlEditor.php
  30. 74 0
      main/inc/lib/formvalidator/FormValidator.class.php
  31. 25 25
      main/inc/lib/lp_item.lib.php
  32. 5 1
      main/inc/lib/message.lib.php
  33. 2 1
      main/inc/lib/pear/HTML/Common.php
  34. 15 14
      main/inc/lib/sessionmanager.lib.php
  35. 6 1
      main/inc/lib/tracking.lib.php
  36. 10 1
      main/lp/learnpath.class.php
  37. 4 7
      main/lp/learnpathItem.class.php
  38. 2 2
      main/lp/lp_content.php
  39. 1 0
      main/lp/lp_controller.php
  40. 1 1
      main/lp/lp_edit_item_prereq.php
  41. 16 5
      main/mySpace/myStudents.php
  42. 21 1
      main/session/add_edit_users_to_session.php
  43. 82 57
      main/survey/surveyUtil.class.php
  44. 1 1
      main/survey/survey_list.php
  45. 43 14
      main/tracking/courseLog.php

+ 1 - 1
main/admin/dashboard_add_users_to_user.php

@@ -32,7 +32,7 @@ $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
 $tbl_access_url_rel_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
 
 // initializing variables
-$user_id = intval($_GET['user']);
+$user_id = isset($_GET['user']) ? (int) $_GET['user'] : 0;
 $user_info = api_get_user_info($user_id);
 $user_anonymous = api_get_anonymous_id();
 $current_user_id = api_get_user_id();

+ 2 - 0
main/admin/email_tester.php

@@ -18,6 +18,8 @@ $this_section = SECTION_PLATFORM_ADMIN;
 $toolName = get_lang('EMailTester');
 
 $form = new FormValidator('email_tester');
+$form->addText('smtp_host', get_lang('Host'), false, ['cols-size' => [2, 8, 2]]);
+$form->addText('smtp_port', get_lang('Port'), false, ['cols-size' => [2, 8, 2]]);
 $form->addText('destination', get_lang('Destination'), true, ['cols-size' => [2, 8, 2]]);
 $form->addText('subject', get_lang('Subject'), true, ['cols-size' => [2, 8, 2]]);
 $form->addHtmlEditor(

+ 18 - 5
main/admin/index.php

@@ -98,11 +98,6 @@ if (api_is_platform_admin()) {
     if (api_get_configuration_value('show_link_request_hrm_user')) {
         $items[] = ['url' => 'user_linking_requests.php', 'label' => get_lang('UserLinkingRequests')];
     }
-} elseif (api_is_session_admin() && api_get_configuration_value('limit_session_admin_role')) {
-    $items = [
-        ['url' => 'user_list.php', 'label' => get_lang('UserList')],
-        ['url' => 'user_add.php', 'label' => get_lang('AddUsers')],
-    ];
 } else {
     $items = [
         ['url' => 'user_list.php', 'label' => get_lang('UserList')],
@@ -110,6 +105,24 @@ if (api_is_platform_admin()) {
         ['url' => 'user_import.php', 'label' => get_lang('ImportUserListXMLCSV')],
         ['url' => 'usergroups.php', 'label' => get_lang('Classes')],
     ];
+
+    if (api_is_session_admin()) {
+        if (true === api_get_configuration_value('limit_session_admin_role')) {
+            $items = array_filter($items, function (array $item) {
+                $urls = ['user_list.php', 'user_add.php'];
+
+                return in_array($item['url'], $urls);
+            });
+        }
+
+        if (true === api_get_configuration_value('limit_session_admin_list_users')) {
+            $items = array_filter($items, function (array $item) {
+                $urls = ['user_list.php'];
+
+                return !in_array($item['url'], $urls);
+            });
+        }
+    }
 }
 
 $blocks['users']['items'] = $items;

+ 4 - 4
main/admin/languages.php

@@ -197,13 +197,13 @@ if ($action == 'disable_all_except_default') {
 
 if (isset($_POST['Submit']) && $_POST['Submit']) {
     // changing the name
-    $sql = "UPDATE $tbl_admin_languages SET original_name='{$_POST['txt_name']}'
-            WHERE id='{$_POST['edit_id']}'";
+    $name = Database::escape_string($_POST['txt_name']);
+    $postId = (int) $_POST['edit_id'];
+    $sql = "UPDATE $tbl_admin_languages SET original_name='$name'
+            WHERE id='$postId'";
     $result = Database::query($sql);
     // changing the Platform language
     if ($_POST['platformlanguage'] && $_POST['platformlanguage'] != '') {
-        //$sql_update_2 = "UPDATE $tbl_settings_current SET selected_value='{$_POST['platformlanguage']}' WHERE variable='platformLanguage'";
-        //$result_2 = Database::query($sql_update_2);
         api_set_setting('platformLanguage', $_POST['platformlanguage'], null, null, $_configuration['access_url']);
     }
 } elseif (isset($_POST['action'])) {

+ 1 - 0
main/admin/promotions.php

@@ -117,6 +117,7 @@ $(function() {
 </script>
 <?php
 $promotion = new Promotion();
+$token = Security::get_token();
 
 switch ($action) {
     case 'add':

+ 3 - 5
main/admin/subscribe_user2course.php

@@ -17,8 +17,6 @@ $this_section = SECTION_PLATFORM_ADMIN;
 
 api_protect_admin_script();
 
-/* Global constants and variables */
-
 $form_sent = 0;
 $first_letter_user = '';
 $first_letter_course = '';
@@ -30,7 +28,7 @@ $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
 
 /* Header */
 $tool_name = get_lang('AddUsersToACourse');
-$interbreadcrumb[] = ["url" => 'index.php', "name" => get_lang('PlatformAdmin')];
+$interbreadcrumb[] = ['url' => 'index.php', 'name' => get_lang('PlatformAdmin')];
 
 $htmlHeadXtra[] = '<script>
 function validate_filter() {
@@ -83,8 +81,8 @@ if (isset($_POST['form_sent']) && $_POST['form_sent']) {
     $form_sent = $_POST['form_sent'];
     $users = isset($_POST['UserList']) && is_array($_POST['UserList']) ? $_POST['UserList'] : [];
     $courses = isset($_POST['CourseList']) && is_array($_POST['CourseList']) ? $_POST['CourseList'] : [];
-    $first_letter_user = $_POST['firstLetterUser'];
-    $first_letter_course = $_POST['firstLetterCourse'];
+    $first_letter_user = Database::escape_string($_POST['firstLetterUser']);
+    $first_letter_course = Database::escape_string($_POST['firstLetterCourse']);
 
     foreach ($users as $key => $value) {
         $users[$key] = intval($value);

+ 5 - 2
main/admin/teacher_time_report.php

@@ -46,11 +46,11 @@ if ($form->validate()) {
     $selectedTeacher = $formValues['teacher'];
 
     if (!empty($formValues['from'])) {
-        $selectedFrom = $formValues['from'];
+        $selectedFrom = Security::remove_XSS($formValues['from']);
     }
 
     if (!empty($formValues['until'])) {
-        $selectedUntil = $formValues['until'];
+        $selectedUntil = Security::remove_XSS($formValues['until']);
     }
 }
 
@@ -96,6 +96,9 @@ $timeReport = new TeacherTimeReport();
 if (!empty($selectedCourse)) {
     $withFilter = true;
     $course = api_get_course_info($selectedCourse);
+    if (empty($course)) {
+        api_not_allowed(true);
+    }
     $reportTitle = sprintf(get_lang('TimeReportForCourseX'), $course['title']);
     $teachers = CourseManager::get_teacher_list_from_course_code($selectedCourse);
 

+ 1 - 1
main/attendance/attendance_controller.php

@@ -303,7 +303,7 @@ class AttendanceController
         $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
             api_get_user_id(),
             api_get_course_info()
-        );
+        ) || api_is_drh();
 
         if ($edit == true) {
             if (api_is_allowed_to_edit(null, true) || $isDrhOfCourse) {

+ 1 - 1
main/attendance/attendance_sheet.php

@@ -16,7 +16,7 @@ api_protect_course_script(true);
 $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
     api_get_user_id(),
     api_get_course_info()
-);
+) || api_is_drh();
 
 if (api_is_allowed_to_edit(null, true) ||
     api_is_coach(api_get_session_id(), api_get_course_int_id()) ||

+ 1 - 0
main/attendance/index.php

@@ -187,6 +187,7 @@ $(function() {
 </script>';
 $student_param = '';
 $student_id = null;
+
 if (api_is_drh() && isset($_GET['student_id'])) {
     $student_id = intval($_GET['student_id']);
     $student_param = '&student_id='.$student_id;

+ 1 - 14
main/auth/courses.php

@@ -199,7 +199,7 @@ switch ($action) {
         exit;
         break;
     case 'createcoursecategory':
-        $courseController->categoryList($action);
+        $courseController->categoryList();
         break;
     case 'deletecoursecategory':
         $courseController->courseList($action);
@@ -213,19 +213,6 @@ switch ($action) {
         }
         header('Location: '.api_get_self());
         exit;
-        /* if (!CoursesAndSessionsCatalog::is(CATALOG_SESSIONS)) {
-            $courseController->courses_categories(
-                $action,
-                $categoryCode,
-                null,
-                null,
-                null,
-                $limit
-            );
-        } else {
-            header('Location: ' . api_get_self());
-            exit;
-        }*/
         break;
     case 'display_random_courses':
         if (!$user_can_view_page) {

+ 4 - 0
main/auth/courses_categories.php

@@ -8,6 +8,7 @@
  *
  * @package chamilo.auth
  */
+
 if (isset($_REQUEST['action']) && Security::remove_XSS($_REQUEST['action']) !== 'subscribe') {
     $stok = Security::get_token();
 } else {
@@ -15,6 +16,9 @@ if (isset($_REQUEST['action']) && Security::remove_XSS($_REQUEST['action']) !==
 }
 
 $action = !empty($_REQUEST['action']) ? Security::remove_XSS($_REQUEST['action']) : 'display_courses';
+global $actions;
+$action = in_array($action, $actions) ? $action : 'display_courses';
+
 $showCourses = CoursesAndSessionsCatalog::showCourses();
 $showSessions = CoursesAndSessionsCatalog::showSessions();
 $pageCurrent = isset($pageCurrent) ? $pageCurrent : isset($_GET['pageCurrent']) ? intval($_GET['pageCurrent']) : 1;

+ 2 - 6
main/auth/courses_controller.php

@@ -57,14 +57,10 @@ class CoursesController
     }
 
     /**
-     * It's used for listing categories,
-     * render to categories_list view.
+     * It's used for listing categories, render to categories_list view.
      *
-     * @param string $action
-     * @param string $message confirmation message(optional)
-     * @param string $error   error message(optional)
      */
-    public function categoryList($action, $message = '', $error = '')
+    public function categoryList()
     {
         api_block_anonymous_users();
 

+ 2 - 3
main/auth/inscription.php

@@ -992,7 +992,7 @@ if ($form->validate()) {
 
         if ($is_allowedCreateCourse) {
             if ($usersCanCreateCourse) {
-                $form_data['message'] = '<p>'.get_lang('NowGoCreateYourCourse')."</p>";
+                $form_data['message'] = '<p>'.get_lang('NowGoCreateYourCourse').'</p>';
             }
             $form_data['action'] = api_get_path(WEB_CODE_PATH).'create_course/add_course.php';
 
@@ -1030,9 +1030,9 @@ if ($form->validate()) {
     }
 
     if ($sessionPremiumChecker && $sessionId) {
-        header('Location:'.api_get_path(WEB_PLUGIN_PATH).'buycourses/src/process.php?i='.$sessionId.'&t=2');
         Session::erase('SessionIsPremium');
         Session::erase('sessionId');
+        header('Location:'.api_get_path(WEB_PLUGIN_PATH).'buycourses/src/process.php?i='.$sessionId.'&t=2');
         exit;
     }
 
@@ -1045,7 +1045,6 @@ if ($form->validate()) {
     }
 
     $form_data = CourseManager::redirectToCourse($form_data);
-
     $form_register = new FormValidator('form_register', 'post', $form_data['action']);
     if (!empty($form_data['message'])) {
         $form_register->addElement('html', $form_data['message'].'<br /><br />');

+ 1 - 5
main/course_home/activity.php

@@ -12,7 +12,7 @@
  *
  * @package chamilo.course_home
  */
-$id = isset($_GET['id']) ? intval($_GET['id']) : null;
+$id = isset($_GET['id']) ? (int) $_GET['id'] : null;
 $course_id = api_get_course_int_id();
 $session_id = api_get_session_id();
 
@@ -29,8 +29,6 @@ if (api_is_platform_admin()) {
         /*
         * Process hiding a tools from available tools.
         */
-        //where $id is set?
-        $id = intval($id);
         Database::query("DELETE FROM $tool_table WHERE c_id = $course_id AND id='$id' AND added_tool=1");
     }
 }
@@ -45,9 +43,7 @@ if ($enabled === 'true') {
 }
 
 //	COURSE ADMIN ONLY VIEW
-
 $blocks = [];
-
 // Start of tools for CourseAdmins (teachers/tutors)
 if ($session_id === 0 && api_is_course_admin() && api_is_allowed_to_edit(null, true)) {
     $content .= '<div class="alert alert-success" style="border:0px; margin-top: 0px;padding:0px;">

+ 0 - 1
main/course_progress/index.php

@@ -286,7 +286,6 @@ switch ($action) {
     case 'export_documents':
     case 'export_single_documents':
         $thematic_controller->thematic($action);
-
         break;
     case 'thematic_plan_add':
     case 'thematic_plan_edit':

+ 21 - 1
main/cron/import_csv.php

@@ -158,6 +158,10 @@ class ImportCsv
                         $method = 'importCareersDiagram';
                     }
 
+                    if ($method == 'importOpensessions') {
+                        $method = 'importOpenSessions';
+                    }
+
                     if ($method == 'importSubsessionsextidStatic') {
                         $method = 'importSubscribeUserToCourseSessionExtStatic';
                     }
@@ -200,6 +204,7 @@ class ImportCsv
                 'teachers',
                 'courses',
                 'sessions',
+                'opensessions',
                 'subscribe-static',
                 'courseinsert-static',
                 'unsubscribe-static',
@@ -220,7 +225,7 @@ class ImportCsv
                         echo PHP_EOL;
                         $this->logger->addInfo("Reading file: $file");
                         $this->logger->addInfo("Loading method $method ");
-                        if ($method == 'importSessions') {
+                        if ($method == 'importSessions' || $method == 'importOpenSessions') {
                             $this->$method(
                                 $file,
                                 true,
@@ -2238,6 +2243,21 @@ class ImportCsv
         }
     }
 
+    /**
+     * @param $file
+     * @param bool  $moveFile
+     * @param array $teacherBackup
+     * @param array $groupBackup
+     */
+    private function importOpenSessions(
+        $file,
+        $moveFile = true,
+        &$teacherBackup = [],
+        &$groupBackup = []
+    ) {
+        $this->importSessions($file, $moveFile, $teacherBackup, $groupBackup);
+    }
+
     /**
      * @param string $file
      * @param bool   $moveFile

+ 0 - 2
main/exercise/exercise.php

@@ -19,8 +19,6 @@ use ChamiloSession as Session;
 require_once __DIR__.'/../inc/global.inc.php';
 $current_course_tool = TOOL_QUIZ;
 
-$charset = 'UTF-8';
-
 // Setting the tabs
 $this_section = SECTION_COURSES;
 

+ 5 - 3
main/exercise/question_pool.php

@@ -256,9 +256,11 @@ if (!empty($session_id) && $session_id != '-1' && !empty($sessionList)) {
     }
     $course_list = $sessionInfo['courses'];
 } else {
-    $course_list = CourseManager::get_course_list_of_user_as_course_admin(
-        api_get_user_id()
-    );
+    if (api_is_platform_admin()) {
+        $course_list = CourseManager::get_courses_list(0, 0, 'title');
+    } else {
+        $course_list = CourseManager::get_course_list_of_user_as_course_admin(api_get_user_id());
+    }
 
     // Admin fix, add the current course in the question pool.
     if (api_is_platform_admin()) {

+ 4 - 3
main/gradebook/index.php

@@ -919,7 +919,6 @@ if (isset($first_time) && $first_time == 1 && api_is_allowed_to_edit(null, true)
 
                 $loadStats = [];
                 $teacher = api_is_allowed_to_edit(null, true);
-
                 if (!$teacher) {
                     if (api_get_setting('gradebook_detailed_admin_view') === 'true') {
                         $loadStats = [1, 2, 3];
@@ -948,15 +947,17 @@ if (isset($first_time) && $first_time == 1 && api_is_allowed_to_edit(null, true)
                         4 => 'class="text-center"',
                     ];
                 } else {
-                    if (empty($model)) {
+                    /*if (empty($model)) {
                         $gradebookTable->td_attributes = [
                             3 => 'class="text-right"',
                             4 => 'class="text-center"',
                         ];
 
+                        if (!empty($loadStats)) {
                         for ($z = 5; $z < count($loadStats); $z++) {
                             $gradebookTable->td_attributes[$z] = 'class="text-center"';
                         }
+                        }
                     } else {
                         $gradebookTable->td_attributes = [
                             3 => 'class="text-right"',
@@ -966,7 +967,7 @@ if (isset($first_time) && $first_time == 1 && api_is_allowed_to_edit(null, true)
 
                     if ($action == 'export_table') {
                         unset($gradebookTable->td_attributes[7]);
-                    }
+                    }*/
                 }
 
                 $table = $gradebookTable->return_table();

+ 29 - 7
main/gradebook/lib/be/category.class.php

@@ -770,16 +770,38 @@ class Category implements GradebookItem
     }
 
     /**
-     * Delete this category from the database.
+     * Delete the gradebook categories from a course, including course sessions.
      *
-     * @param int $courseId
+     * @param string $courseCode
      */
-    public static function deleteCategoryFromCourse($courseId)
+    public static function deleteFromCourse($courseCode)
     {
-        $table = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
-        $sql = 'DELETE FROM '.$table.' 
-                WHERE c_id ="'.intval($courseId).'"';
-        Database::query($sql);
+        $em = Database::getManager();
+        $categories = $em
+            ->createQuery(
+                'SELECT DISTINCT gc.sessionId
+                FROM ChamiloCoreBundle:GradebookCategory gc WHERE gc.courseCode = :code'
+            )
+            ->setParameter('code', $courseCode)
+            ->getResult();
+
+        foreach ($categories as $category) {
+            $cats = self::load(
+                null,
+                null,
+                $courseCode,
+                null,
+                null,
+                (int) $category['sessionId']
+            );
+
+            if (!empty($cats)) {
+                /** @var self $cat */
+                foreach ($cats as $cat) {
+                    $cat->delete_all();
+                }
+            }
+        }
     }
 
     /**

+ 13 - 9
main/gradebook/lib/fe/gradebooktable.class.php

@@ -111,7 +111,10 @@ class GradebookTable extends SortableTable
             '',
             'width="100px"'
         );
-        $this->set_header($column++, get_lang('Result'), false);
+
+        if (!$this->teacherView) {
+            $this->set_header($column++, get_lang('Result'), false);
+        }
 
         if (empty($model)) {
             if (in_array(1, $this->loadStats)) {
@@ -464,7 +467,6 @@ class GradebookTable extends SortableTable
                         }
                     } else {
                         $row[] = $scoreToDisplay;
-
                         if (!empty($this->cats)) {
                             if ($this->exportToPdf == false) {
                                 $row[] = $this->build_edit_column($item);
@@ -574,6 +576,7 @@ class GradebookTable extends SortableTable
                                     if (!is_null($value_data)) {
                                         // Result
                                         $row[] = $value_data;
+
                                         $best = isset($data['best']) ? $data['best'] : null;
                                         $average = isset($data['average']) ? $data['average'] : null;
                                         $ranking = isset($data['ranking']) ? $data['ranking'] : null;
@@ -702,7 +705,7 @@ class GradebookTable extends SortableTable
 
                 $row = [
                         null,
-                        '<h3>'.get_lang('Total').'</h3>',
+                        '<strong>'.get_lang('Total').'</strong>',
                     ];
 
                 if (!$this->exportToPdf) {
@@ -742,13 +745,12 @@ class GradebookTable extends SortableTable
                     if ($invalidateRanking) {
                         $totalRanking = null;
                     }
-
                     $row[] = $totalRanking;
                 }
+
                 if (in_array(2, $this->loadStats)) {
                     // Overwrite main weight
                     $totalBest[1] = $main_weight;
-
                     $totalBest = $scoredisplay->display_score(
                             $totalBest,
                             SCORE_DIV,
@@ -770,7 +772,9 @@ class GradebookTable extends SortableTable
 
                     $row[] = $totalAverage;
                 }
-                $sortable_data[] = $row;
+                if (!empty($row)) {
+                    $sortable_data[] = $row;
+                }
             }
         }
 
@@ -860,9 +864,9 @@ class GradebookTable extends SortableTable
         }
 
         if (!$this->teacherView) {
-            $rowTotal = [];
+            /*$rowTotal = [];
             $rowTotal[] = ' ';
-            $rowTotal[] = get_lang('FinalScore');
+            $rowTotal[] = '<strong>'.get_lang('FinalScore').'</strong>';
 
             if (!$this->exportToPdf) {
                 $rowTotal[] = ' ';
@@ -877,7 +881,7 @@ class GradebookTable extends SortableTable
                 $rowTotal[] = ' ';
             }
 
-            $sortable_data[] = $rowTotal;
+            $sortable_data[] = $rowTotal;*/
         }
 
         return $sortable_data;

+ 3 - 3
main/inc/ajax/message.ajax.php

@@ -63,12 +63,12 @@ switch ($action) {
                 $group_pending_invitations = 0;
             }
             $invitations = [
-                'ms_friends' => intval($number_of_new_messages_of_friend),
+                'ms_friends' => $number_of_new_messages_of_friend,
                 'ms_groups' => $group_pending_invitations,
-                'ms_inbox' => intval($count_unread_message),
+                'ms_inbox' => $count_unread_message,
             ];
         }
-        header("Content-type:application/json");
+        header('Content-type:application/json');
         echo json_encode($invitations);
         break;
     case 'send_message':

+ 17 - 8
main/inc/lib/AnnouncementManager.php

@@ -1620,7 +1620,7 @@ class AnnouncementManager
             $extraGroupCondition = " AND ip.to_group_id = $group_id ";
         }
 
-        if (api_is_allowed_to_edit(false, true) ||
+        if ((api_is_allowed_to_edit(false, true) || api_is_drh()) &&
             ($allowUserEditSetting && !api_is_anonymous())
         ) {
             // A.1. you are a course admin with a USER filter
@@ -1737,11 +1737,13 @@ class AnnouncementManager
                 } else {
                     if ($group_id == 0) {
                         $cond_user_id = " AND (
-                            (ip.to_user_id='$user_id' OR ip.to_user_id IS NULL) AND (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(", ", $group_memberships)."))
+                            (ip.to_user_id='$user_id' OR ip.to_user_id IS NULL) AND 
+                            (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".implode(", ", $group_memberships)."))
                         ) ";
                     } else {
                         $cond_user_id = " AND (
-                            (ip.to_user_id='$user_id' OR ip.to_user_id IS NULL) AND (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".$group_id."))
+                            (ip.to_user_id='$user_id' OR ip.to_user_id IS NULL) AND 
+                            (ip.to_group_id IS NULL OR ip.to_group_id IN (0, ".$group_id."))
                         )";
                         $cond_user_id .= $extraGroupCondition;
                     }
@@ -1766,10 +1768,15 @@ class AnnouncementManager
                     if ($allowUserEditSetting && !api_is_anonymous()) {
                         $cond_user_id = " AND (
                             ip.lastedit_user_id = '".api_get_user_id()."' OR
-                            ((ip.to_user_id='$user_id' OR ip.to_user_id IS NULL) AND (ip.to_group_id='0' OR ip.to_group_id IS NULL))
+                            (
+                                (ip.to_user_id='$user_id' OR ip.to_user_id IS NULL) AND
+                                (ip.to_group_id='0' OR ip.to_group_id IS NULL)
+                            )
                         ) ";
                     } else {
-                        $cond_user_id = " AND ((ip.to_user_id='$user_id' OR ip.to_user_id IS NULL) AND (ip.to_group_id='0' OR ip.to_group_id IS NULL) ) ";
+                        $cond_user_id = " AND (
+                        (ip.to_user_id='$user_id' OR ip.to_user_id IS NULL) AND 
+                        (ip.to_group_id='0' OR ip.to_group_id IS NULL) ) ";
                     }
 
                     $sql = "SELECT $select
@@ -1876,20 +1883,22 @@ class AnnouncementManager
         while ($row = Database::fetch_array($result, 'ASSOC')) {
             if (!in_array($row['id'], $displayed)) {
                 $sent_to_icon = '';
+                // the email icon
                 if ($row['email_sent'] == '1') {
                     $sent_to_icon = ' '.$emailIcon;
                 }
-                $groupReference = $row['to_group_id'] > 0 ? ' <span class="label label-info">'.get_lang(
-                        'Group'
-                    ).'</span> ' : '';
+
+                $groupReference = $row['to_group_id'] > 0 ? ' <span class="label label-info">'.get_lang('Group').'</span> ' : '';
                 $disableEdit = false;
                 $to = self::loadEditUsers('announcement', $row['id'], true);
                 $separated = CourseManager::separateUsersGroups($to);
                 if (!empty($group_id)) {
+                    // If the announcement was sent to many groups, disable edition inside a group
                     if (isset($separated['groups']) && count($separated['groups']) > 1) {
                         $disableEdit = true;
                     }
 
+                    // If the announcement was sent only to the course disable edition
                     if (empty($separated['groups']) && empty($separated['users'])) {
                         $disableEdit = true;
                     }

+ 4 - 4
main/inc/lib/attendance.lib.php

@@ -154,8 +154,9 @@ class Attendance
 
         while ($attendance = Database::fetch_row($res)) {
             $student_param = '';
-            if (api_is_drh() && $_GET['student_id']) {
-                $student_param = '&student_id='.intval($_GET['student_id']);
+            $studentRequestId = isset($_GET['student_id']) ? (int) $_GET['student_id'] : 0;
+            if (api_is_drh() && !empty($studentRequestId)) {
+                $student_param = '&student_id='.$studentRequestId;
             }
 
             $session_star = '';
@@ -166,8 +167,7 @@ class Attendance
                 $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
                     api_get_user_id(),
                     api_get_course_info()
-                );
-
+                ) || api_is_drh();
                 if (api_is_allowed_to_edit(null, true) || $isDrhOfCourse) {
                     // Link to edit
                     $attendance[1] = '<a href="index.php?'.api_get_cidreq().'&action=attendance_sheet_list&attendance_id='.$attendance[0].$student_param.'">'.$attendance[1].'</a>'.$session_star;

+ 6 - 1
main/inc/lib/certificate.lib.php

@@ -393,6 +393,7 @@ class Certificate extends Model
             '((author_last_name))',
             '((score))',
             '((portal_name))',
+            '((certificate_link))',
         ];
 
         return $tags;
@@ -419,6 +420,9 @@ class Certificate extends Model
         }
 
         $currentUserInfo = api_get_user_info();
+        $url = api_get_path(WEB_PATH).
+            'certificates/index.php?id='.$certificateInfo['id'].'&user_id='.$certificateInfo['user_id'];
+        $link = Display::url($url, $url);
 
         $replace = [
             $courseInfo['title'],
@@ -428,9 +432,10 @@ class Certificate extends Model
             $currentUserInfo['lastname'],
             $certificateInfo['score_certificate'],
             api_get_setting('Institution'),
+            $link,
         ];
-        $message = str_replace(self::notificationTags(), $replace, $message);
 
+        $message = str_replace(self::notificationTags(), $replace, $message);
         MessageManager::send_message(
             $userInfo['id'],
             $subject,

+ 18 - 13
main/inc/lib/course_home.lib.php

@@ -34,7 +34,9 @@ class CourseHome
         switch ($cat) {
             case 'Basic':
                 $condition_display_tools = ' WHERE a.c_id = '.$course_id.' AND  a.link=t.link AND t.position="basic" ';
-                if ((api_is_coach() || api_is_course_tutor()) && !$studentView) {
+                if ((api_is_coach() || api_is_course_tutor() || api_is_platform_admin()) &&
+                    !$studentView
+                ) {
                     $condition_display_tools = ' WHERE 
                         a.c_id = '.$course_id.' AND 
                         a.link=t.link AND
@@ -176,7 +178,7 @@ class CourseHome
 
             // VISIBLE
             if (($tool['visibility'] ||
-                ((api_is_coach() || api_is_course_tutor()) && $tool['name'] == TOOL_TRACKING)) ||
+                ((api_is_coach() || api_is_course_tutor() || api_is_platform_admin()) && $tool['name'] == TOOL_TRACKING)) ||
                 $cat == 'courseAdmin' || $cat == 'platformAdmin'
             ) {
                 if (strpos($tool['name'], 'visio_') !== false) {
@@ -270,7 +272,9 @@ class CourseHome
         switch ($course_tool_category) {
             case TOOL_PUBLIC:
                 $condition_display_tools = ' WHERE c_id = '.$course_id.' AND visibility = 1 ';
-                if ((api_is_coach() || api_is_course_tutor()) && !$studentView) {
+                if ((api_is_coach() || api_is_course_tutor() || api_is_platform_admin()) &&
+                    !$studentView
+                ) {
                     $condition_display_tools = ' WHERE 
                         c_id = '.$course_id.' AND 
                         (visibility = 1 OR (visibility = 0 AND name = "'.TOOL_TRACKING.'")) ';
@@ -308,13 +312,15 @@ class CourseHome
             case TOOL_PUBLIC:
                 $sql_links = "SELECT tl.*, tip.visibility
                         FROM $course_link_table tl
-                        LEFT JOIN $course_item_property_table tip ON tip.tool='link' AND tl.c_id = tip.c_id AND tl.c_id = $course_id AND tip.ref=tl.id
+                        LEFT JOIN $course_item_property_table tip 
+                        ON tip.tool='link' AND tl.c_id = tip.c_id AND tl.c_id = $course_id AND tip.ref=tl.id
                         WHERE tl.on_homepage='1' AND tip.visibility = 1";
                 break;
             case TOOL_PUBLIC_BUT_HIDDEN:
                 $sql_links = "SELECT tl.*, tip.visibility
                     FROM $course_link_table tl
-                    LEFT JOIN $course_item_property_table tip ON tip.tool='link' AND tl.c_id = tip.c_id AND tl.c_id = $course_id AND tip.ref=tl.id
+                    LEFT JOIN $course_item_property_table tip 
+                    ON tip.tool='link' AND tl.c_id = tip.c_id AND tl.c_id = $course_id AND tip.ref=tl.id
                     WHERE tl.on_homepage='1' AND tip.visibility = 0";
 
                 break;
@@ -425,7 +431,8 @@ class CourseHome
                         }
                     }
                     if (isset($tool['adminlink'])) {
-                        $html .= '<a href="'.$tool['adminlink'].'">'.Display::return_icon('edit.gif', get_lang('Edit')).'</a>';
+                        $html .= '<a href="'.$tool['adminlink'].'">'.
+                            Display::return_icon('edit.gif', get_lang('Edit')).'</a>';
                     }
                 }
                 if (api_is_platform_admin() && !api_is_coach()) {
@@ -466,7 +473,6 @@ class CourseHome
                 if ($i % 2) {
                     $html .= "</tr>";
                 }
-
                 $i++;
             }
         }
@@ -519,7 +525,7 @@ class CourseHome
                 $conditions = ' WHERE visibility = 1 AND 
                                 (category = "authoring" OR category = "interaction" OR category = "plugin") AND 
                                 t.name <> "notebookteacher" ';
-                if ((api_is_coach() || api_is_course_tutor()) && !$studentView) {
+                if ((api_is_coach() || api_is_course_tutor() || api_is_platform_admin()) && !$studentView) {
                     $conditions = ' WHERE (
                         visibility = 1 AND (
                             category = "authoring" OR 
@@ -779,9 +785,9 @@ class CourseHome
             }
         }
 
-        $all_tools_list = CourseHome::filterPluginTools($all_tools_list, $course_tool_category);
+        $list = self::filterPluginTools($all_tools_list, $course_tool_category);
 
-        return $all_tools_list;
+        return $list;
     }
 
     /**
@@ -1113,15 +1119,14 @@ class CourseHome
      */
     public static function show_session_data($id_session)
     {
-        $session_category_table = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
-
         $sessionInfo = api_get_session_info($id_session);
 
         if (empty($sessionInfo)) {
             return '';
         }
 
-        $sql = 'SELECT name FROM '.$session_category_table.'
+        $table = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
+        $sql = 'SELECT name FROM '.$table.'
                 WHERE id = "'.intval($sessionInfo['session_category_id']).'"';
         $rs_category = Database::query($sql);
         $session_category = '';

+ 6 - 5
main/inc/lib/formvalidator/Element/DateRangePicker.php

@@ -53,6 +53,7 @@ class DateRangePicker extends HTML_QuickForm_text
      */
     public function parseDateRange($dateRange)
     {
+        $dateRange = Security::remove_XSS($dateRange);
         $dates = explode('/', $dateRange);
         $dates = array_map('trim', $dates);
         $start = isset($dates[0]) ? $dates[0] : '';
@@ -82,7 +83,7 @@ class DateRangePicker extends HTML_QuickForm_text
         $d = DateTime::createFromFormat($format, $dates['end']);
         $resultEnd = $d && $d->format($format) == $dates['end'];
 
-        if (!($resultStart) || !$resultEnd) {
+        if (!$resultStart || !$resultEnd) {
             return false;
         }
 
@@ -133,7 +134,7 @@ class DateRangePicker extends HTML_QuickForm_text
         }
 
         $minDate = null;
-        $minDateValue = $this->getAttribute('minDate');
+        $minDateValue = Security::remove_XSS($this->getAttribute('minDate'));
         if (!empty($minDateValue)) {
             $minDate = "
                 minDate: '{$minDateValue}',
@@ -141,7 +142,7 @@ class DateRangePicker extends HTML_QuickForm_text
         }
 
         $maxDate = null;
-        $maxDateValue = $this->getAttribute('maxDate');
+        $maxDateValue = Security::remove_XSS($this->getAttribute('maxDate'));
         if (!empty($maxDateValue)) {
             $maxDate = "
                 maxDate: '{$maxDateValue}',
@@ -149,13 +150,13 @@ class DateRangePicker extends HTML_QuickForm_text
         }
 
         $format = 'YYYY-MM-DD HH:mm';
-        $formatValue = $this->getAttribute('format');
+        $formatValue = Security::remove_XSS($this->getAttribute('format'));
         if (!empty($formatValue)) {
             $format = $formatValue;
         }
 
         $timePicker = 'true';
-        $timePickerValue = $this->getAttribute('timePicker');
+        $timePickerValue = Security::remove_XSS($this->getAttribute('timePicker'));
         if (!empty($timePickerValue)) {
             $timePicker = $timePickerValue;
         }

+ 2 - 3
main/inc/lib/formvalidator/Element/HtmlEditor.php

@@ -54,8 +54,7 @@ class HtmlEditor extends HTML_QuickForm_textarea
      */
     public function toHtml()
     {
-        $value = $this->getValue();
-
+        $value = Security::remove_XSS($this->getValue());
         if ($this->editor) {
             if ($this->editor->getConfigAttribute('fullPage')) {
                 if (strlen(trim($value)) == 0) {
@@ -100,7 +99,7 @@ class HtmlEditor extends HTML_QuickForm_textarea
     {
         $result = '';
         if ($this->editor) {
-            $this->editor->value = $this->getValue();
+            $this->editor->value = Security::remove_XSS($this->getValue());
             $this->editor->setName($this->getName());
             if ($style === true) {
                 $result = $this->editor->createHtmlStyle();

+ 74 - 0
main/inc/lib/formvalidator/FormValidator.class.php

@@ -1764,6 +1764,80 @@ EOT;
         return $this->addElement('UserAvatar', $name, $label, ['image_size' => $imageSize, 'sub_title' => $subtitle]);
     }
 
+    /**
+     * @param array $typeList
+     */
+    public function addEmailTemplate($typeList)
+    {
+        $mailManager = new MailTemplateManager();
+        foreach ($typeList as $type) {
+            $list = $mailManager->get_all(
+                ['where' => ['type = ? AND url_id = ?' => [$type, api_get_current_access_url_id()]]]
+            );
+
+            $options = [get_lang('Select')];
+            $name = $type;
+            $defaultId = '';
+            foreach ($list as $item) {
+                $options[$item['id']] = $item['name'];
+                $name = $item['name'];
+                if (empty($defaultId)) {
+                    $defaultId = $item['default_template'] == 1 ? $item['id'] : '';
+                }
+            }
+
+            $url = api_get_path(WEB_AJAX_PATH).'mail.ajax.php?a=select_option';
+            $typeNoDots = 'email_template_option_'.str_replace('.tpl', '', $type);
+            $this->addSelect(
+                'email_template_option['.$type.']',
+                $name,
+                $options,
+                ['id' => $typeNoDots]
+            );
+
+            $templateNoDots = 'email_template_'.str_replace('.tpl', '', $type);
+            $templateNoDotsBlock = 'email_template_block_'.str_replace('.tpl', '', $type);
+            $this->addHtml('<div id="'.$templateNoDotsBlock.'" style="display:none">');
+            $this->addTextarea(
+                $templateNoDots,
+                get_lang('Preview'),
+                ['disabled' => 'disabled ', 'id' => $templateNoDots, 'rows' => '5']
+            );
+            $this->addHtml('</div>');
+
+            $this->addHtml("<script>            
+            $(document).on('ready', function() {
+                var defaultValue = '$defaultId';
+                $('#$typeNoDots').val(defaultValue);
+                $('#$typeNoDots').selectpicker('render');
+                if (defaultValue != '') {
+                    var selected = $('#$typeNoDots option:selected').val();                    
+                    $.ajax({ 
+                        url: '$url' + '&id=' + selected+ '&template_name=$type',
+                        success: function (data) {
+                            $('#$templateNoDots').html(data);
+                            $('#$templateNoDotsBlock').show();
+                            return;
+                        }, 
+                    });
+                }
+                                
+                $('#$typeNoDots').on('change', function(){                    
+                    var selected = $('#$typeNoDots option:selected').val();                    
+                    $.ajax({ 
+                        url: '$url' + '&id=' + selected,
+                        success: function (data) {
+                            $('#$templateNoDots').html(data);
+                            $('#$templateNoDotsBlock').show();
+                            return;
+                        }, 
+                    });
+                });
+            });
+            </script>");
+        }
+    }
+
     /**
      * @param string $url           page that will handle the upload
      * @param string $inputName

+ 25 - 25
main/inc/lib/lp_item.lib.php

@@ -43,10 +43,10 @@ class LpItem
     {
         if ($in_c_id > 0 && $in_id > 0) {
             $item_view_table = Database::get_course_table(TABLE_LP_ITEM);
-            $sql = "SELECT * FROM $item_view_table
-                    WHERE
-                        c_id=".intval($in_c_id)." AND
-                        id=".intval($in_id);
+            $sql = "SELECT * FROM $item_view_table
+                    WHERE
+                        c_id=".intval($in_c_id)." AND
+                        iid=".intval($in_id);
 
             $res = Database::query($sql);
             $data = Database::fetch_array($res);
@@ -84,27 +84,27 @@ class LpItem
     {
         $table = Database::get_course_table(TABLE_LP_ITEM);
         if ($this->c_id > 0 && $this->id > 0) {
-            $sql = "UPDATE $table SET
-                        lp_id = '".intval($this->lp_id)."' ,
-                        item_type = '".Database::escape_string($this->item_type)."' ,
-                        ref = '".Database::escape_string($this->ref)."' ,
-                        title = '".Database::escape_string($this->title)."' ,
-                        description = '".Database::escape_string($this->description)."' ,
-                        path = '".Database::escape_string($this->path)."' ,
-                        min_score = '".Database::escape_string($this->min_score)."' ,
-                        max_score = '".Database::escape_string($this->max_score)."' ,
-                        mastery_score = '".Database::escape_string($this->mastery_score)."' ,
-                        parent_item_id = '".Database::escape_string($this->parent_item_id)."' ,
-                        previous_item_id = '".Database::escape_string($this->previous_item_id)."' ,
-                        next_item_id = '".Database::escape_string($this->next_item_id)."' ,
-                        display_order = '".Database::escape_string($this->display_order)."' ,
-                        prerequisite = '".Database::escape_string($this->prerequisite)."' ,
-                        parameters = '".Database::escape_string($this->parameters)."' ,
-                        launch_data = '".Database::escape_string($this->launch_data)."' ,
-                        max_time_allowed = '".Database::escape_string($this->max_time_allowed)."' ,
-                        terms = '".Database::escape_string($this->terms)."' ,
-                        search_did = '".Database::escape_string($this->search_did)."' ,
-                        audio = '".Database::escape_string($this->audio)."'
+            $sql = "UPDATE $table SET
+                        lp_id = '".intval($this->lp_id)."' ,
+                        item_type = '".Database::escape_string($this->item_type)."' ,
+                        ref = '".Database::escape_string($this->ref)."' ,
+                        title = '".Database::escape_string($this->title)."' ,
+                        description = '".Database::escape_string($this->description)."' ,
+                        path = '".Database::escape_string($this->path)."' ,
+                        min_score = '".Database::escape_string($this->min_score)."' ,
+                        max_score = '".Database::escape_string($this->max_score)."' ,
+                        mastery_score = '".Database::escape_string($this->mastery_score)."' ,
+                        parent_item_id = '".Database::escape_string($this->parent_item_id)."' ,
+                        previous_item_id = '".Database::escape_string($this->previous_item_id)."' ,
+                        next_item_id = '".Database::escape_string($this->next_item_id)."' ,
+                        display_order = '".Database::escape_string($this->display_order)."' ,
+                        prerequisite = '".Database::escape_string($this->prerequisite)."' ,
+                        parameters = '".Database::escape_string($this->parameters)."' ,
+                        launch_data = '".Database::escape_string($this->launch_data)."' ,
+                        max_time_allowed = '".Database::escape_string($this->max_time_allowed)."' ,
+                        terms = '".Database::escape_string($this->terms)."' ,
+                        search_did = '".Database::escape_string($this->search_did)."' ,
+                        audio = '".Database::escape_string($this->audio)."'
                     WHERE c_id=".$this->c_id." AND id=".$this->id;
             Database::query($sql);
         }

+ 5 - 1
main/inc/lib/message.lib.php

@@ -78,7 +78,11 @@ class MessageManager
         $result = Database::query($sql);
         $result = Database::fetch_array($result);
 
-        return $result['number_messages'];
+        if ($result) {
+            return (int) $result['number_messages'];
+        }
+
+        return 0;
     }
 
     /**

+ 2 - 1
main/inc/lib/pear/HTML/Common.php

@@ -251,12 +251,13 @@ class HTML_Common
      * @access    public
      * @return    string|null   returns null if an attribute does not exist
      */
-    function getAttribute($attr)
+    public function getAttribute($attr)
     {
         $attr = strtolower($attr);
         if (isset($this->_attributes[$attr])) {
             return $this->_attributes[$attr];
         }
+
         return null;
     } //end func getAttribute
 

+ 15 - 14
main/inc/lib/sessionmanager.lib.php

@@ -131,9 +131,9 @@ class SessionManager
      * @param string $displayEndDate               (YYYY-MM-DD hh:mm:ss)
      * @param string $coachStartDate               (YYYY-MM-DD hh:mm:ss)
      * @param string $coachEndDate                 (YYYY-MM-DD hh:mm:ss)
-     * @param int    $sessionCategoryId            ID of the session category in which this session is registered
      * @param mixed  $coachId                      If int, this is the session coach id,
      *                                             if string, the coach ID will be looked for from the user table
+     * @param int      $sessionCategoryId            ID of the session category in which this session is registered
      * @param int    $visibility                   Visibility after end date (0 = read-only, 1 = invisible, 2 = accessible)
      * @param bool   $fixSessionNameIfExists
      * @param string $duration
@@ -143,6 +143,9 @@ class SessionManager
      * @param int    $sessionAdminId               Optional. If this sessions was created by a session admin, assign it to him
      * @param bool   $sendSubscriptionNotification Optional.
      *                                             Whether send a mail notification to users being subscribed
+     * @param int|null $accessUrlId                  Optional.
+     *
+     * @return mixed Session ID on success, error message otherwise
      *
      * @todo use an array to replace all this parameters or use the model.lib.php ...
      *
@@ -165,23 +168,22 @@ class SessionManager
         $showDescription = 0,
         $extraFields = [],
         $sessionAdminId = 0,
-        $sendSubscriptionNotification = false
+        $sendSubscriptionNotification = false,
+        $accessUrlId = null
     ) {
         global $_configuration;
 
         // Check portal limits
-        $access_url_id = 1;
-
-        if (api_get_multiple_access_url()) {
-            $access_url_id = api_get_current_access_url_id();
-        }
+        $accessUrlId = empty($accessUrlId) && api_get_multiple_access_url()
+            ? api_get_current_access_url_id()
+            : 1;
 
-        if (is_array($_configuration[$access_url_id]) &&
-            isset($_configuration[$access_url_id]['hosting_limit_sessions']) &&
-            $_configuration[$access_url_id]['hosting_limit_sessions'] > 0
+        if (is_array($_configuration[$accessUrlId]) &&
+            isset($_configuration[$accessUrlId]['hosting_limit_sessions']) &&
+            $_configuration[$accessUrlId]['hosting_limit_sessions'] > 0
         ) {
             $num = self::count_sessions();
-            if ($num >= $_configuration[$access_url_id]['hosting_limit_sessions']) {
+            if ($num >= $_configuration[$accessUrlId]['hosting_limit_sessions']) {
                 api_warn_hosting_contact('hosting_limit_sessions');
 
                 return get_lang('PortalSessionsLimitReached');
@@ -313,9 +315,8 @@ class SessionManager
                       api_mail_html($complete_name, $user_info['email'], $subject, $message);
                      *
                      */
-                    //Adding to the correct URL
-                    $access_url_id = api_get_current_access_url_id();
-                    UrlManager::add_session_to_url($session_id, $access_url_id);
+                    // Adding to the correct URL
+                    UrlManager::add_session_to_url($session_id, $accessUrlId);
 
                     // add event to system log
                     $user_id = api_get_user_id();

+ 6 - 1
main/inc/lib/tracking.lib.php

@@ -7448,8 +7448,9 @@ class TrackingCourseLog
         $direction,
         $includeInvitedUsers = false
     ) {
-        global $user_ids, $course_code, $export_csv, $csv_content, $session_id;
+        global $user_ids, $course_code, $export_csv, $session_id;
 
+        $csv_content = [];
         $course_code = Database::escape_string($course_code);
         $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
         $tbl_url_rel_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
@@ -7696,6 +7697,10 @@ class TrackingCourseLog
             $users[] = array_values($user_row);
         }
 
+        if ($export_csv) {
+            Session::write('csv_content', $csv_content);
+        }
+
         Session::erase('additional_user_profile_info');
         Session::erase('extra_field_info');
 

+ 10 - 1
main/lp/learnpath.class.php

@@ -10259,11 +10259,14 @@ class learnpath
 
         $selectedMinScore = [];
         $selectedMaxScore = [];
+        $masteryScore = [];
         while ($row = Database::fetch_array($result)) {
-            if ($row['id'] == $item_id) {
+            if ($row['iid'] == $item_id) {
                 $selectedMinScore[$row['prerequisite']] = $row['prerequisite_min_score'];
                 $selectedMaxScore[$row['prerequisite']] = $row['prerequisite_max_score'];
             }
+            $masteryScore[$row['iid']] = $row['mastery_score'];
+
             $arrLP[] = [
                 'id' => $row['iid'],
                 'item_type' => $row['item_type'],
@@ -10296,6 +10299,7 @@ class learnpath
 
             $selectedMaxScoreValue = isset($selectedMaxScore[$item['id']]) ? $selectedMaxScore[$item['id']] : $item['max_score'];
             $selectedMinScoreValue = isset($selectedMinScore[$item['id']]) ? $selectedMinScore[$item['id']] : 0;
+            $masteryScoreAsMinValue = isset($masteryScore[$item['id']]) ? $masteryScore[$item['id']] : 0;
 
             $return .= '<tr>';
             $return .= '<td '.(($item['item_type'] != TOOL_QUIZ && $item['item_type'] != TOOL_HOTPOTATOES) ? ' colspan="3"' : '').'>';
@@ -10328,6 +10332,11 @@ class learnpath
                 $lpItemObj->update();
                 $item['max_score'] = $lpItemObj->max_score;
 
+                if (empty($selectedMinScoreValue) && !empty($masteryScoreAsMinValue)) {
+                    // Backwards compatibility with 1.9.x use mastery_score as min value
+                    $selectedMinScoreValue = $masteryScoreAsMinValue;
+                }
+
                 $return .= '<td>';
                 $return .= '<input 
                     class="form-control" 

+ 4 - 7
main/lp/learnpathItem.class.php

@@ -2175,10 +2175,9 @@ class learnpathItem
                             break;
                         }
                     }
+
                     if (empty($this->prereq_alert) && !$andstatus) {
-                        $this->prereq_alert = get_lang(
-                            'LearnpathPrereqNotCompleted'
-                        );
+                        $this->prereq_alert = get_lang('LearnpathPrereqNotCompleted');
                     }
 
                     return $andstatus;
@@ -2452,7 +2451,7 @@ class learnpathItem
                                     /** @var learnpathItem $itemToCheck */
                                     $itemToCheck = $items[$refs_list[$prereqs_string]];
 
-                                    if ($itemToCheck->type == 'quiz') {
+                                    if ($itemToCheck->type === 'quiz') {
                                         // 1. Checking the status in current items.
                                         $status = $itemToCheck->get_status(true);
                                         $returnstatus = $status == $this->possible_status[2] || $status == $this->possible_status[3];
@@ -2722,9 +2721,7 @@ class learnpathItem
                     }
                 }
                 if (!$orstatus && empty($this->prereq_alert)) {
-                    $this->prereq_alert = get_lang(
-                        'LearnpathPrereqNotCompleted'
-                    );
+                    $this->prereq_alert = get_lang('LearnpathPrereqNotCompleted');
                 }
 
                 return $orstatus;

+ 2 - 2
main/lp/lp_content.php

@@ -62,7 +62,7 @@ if ($dir) {
                 $src = $learnPath->fixBlockedLinks($src);
                 break;
             }
-            $src = 'blank.php?error=prerequisites&prerequisite_message='.$learnPath->error;
+            $src = 'blank.php?error=prerequisites&prerequisite_message='.Security::remove_XSS($learnPath->error);
             break;
         case 2:
             $learnPath->stop_previous_item();
@@ -72,7 +72,7 @@ if ($dir) {
                 $src = $learnPath->get_link('http', $lpItemId);
                 $learnPath->start_current_item(); // starts time counter manually if asset
             } else {
-                $src = 'blank.php?error=prerequisites&prerequisite_message='.$learnPath->error;
+                $src = 'blank.php?error=prerequisites&prerequisite_message='.Security::remove_XSS($learnPath->error);
             }
             break;
         case 3:

+ 1 - 0
main/lp/lp_controller.php

@@ -757,6 +757,7 @@ switch ($action) {
                     $is_success = true;
                 }
 
+                Display::addFlash(Display::return_message(get_lang('Updated')));
                 $url = api_get_self().'?action=add_item&type=step&lp_id='.intval($_SESSION['oLP']->lp_id).'&'.api_get_cidreq();
                 header('Location: '.$url);
                 exit;

+ 1 - 1
main/lp/lp_edit_item_prereq.php

@@ -25,7 +25,7 @@ $learnpath_id = isset($_REQUEST['lp_id']) ? (int) $_REQUEST['lp_id'] : null;
 $submit = isset($_POST['submit_button']) ? $_POST['submit_button'] : null;
 
 /* MAIN CODE */
-if ((!$is_allowed_to_edit) || ($isStudentView)) {
+if ((!$is_allowed_to_edit) || $isStudentView) {
     error_log('New LP - User not authorized in lp_edit_item_prereq.php');
     header('location:lp_controller.php?action=view&lp_id='.$learnpath_id);
     exit;

+ 16 - 5
main/mySpace/myStudents.php

@@ -922,11 +922,22 @@ if (empty($details)) {
                 $courseInfoItem = api_get_course_info_by_id($courseId);
                 $courseId = $courseInfoItem['real_id'];
                 $courseCodeItem = $courseInfoItem['code'];
-                $isSubscribed = CourseManager::is_user_subscribed_in_course(
-                    $student_id,
-                    $courseCodeItem,
-                    true
-                );
+
+                if (empty($session_info)) {
+                    $isSubscribed = CourseManager::is_user_subscribed_in_course(
+                        $student_id,
+                        $courseCodeItem,
+                            false
+                    );
+                } else {
+                    $isSubscribed = CourseManager::is_user_subscribed_in_course(
+                        $student_id,
+                        $courseCodeItem,
+                        true,
+                        $sId
+                    );
+                }
+
                 if ($isSubscribed) {
                     $timeInSeconds = Tracking::get_time_spent_on_the_course(
                         $user_info['user_id'],

+ 21 - 1
main/session/add_edit_users_to_session.php

@@ -643,12 +643,28 @@ if ($add_type == 'multiple') {
         '<a href="'.api_get_self().'?course_id='.$courseId.'&id_session='.$id_session.'&amp;add='.$addProcess.'&amp;add_type=multiple">'
         .Display::return_icon('multiple.gif').get_lang('SessionAddTypeMultiple').'</a>';
 }
-
+$link_add_group = Display::url(
+    Display::return_icon('multiple.gif', get_lang('RegistrationByUsersGroups')).get_lang('RegistrationByUsersGroups'),
+    api_get_path(WEB_CODE_PATH).'admin/usergroups.php'
+);
+
+$newLinks = Display::url(
+    Display::return_icon('teacher.png', get_lang('EnrollTrainersFromExistingSessions'), null, ICON_SIZE_TINY).
+        get_lang('EnrollTrainersFromExistingSessions'),
+    api_get_path(WEB_CODE_PATH).'session/add_teachers_to_session.php?id='.$id_session
+);
+$newLinks .= Display::url(
+    Display::return_icon('user.png', get_lang('EnrollTrainersFromExistingSessions'), null, ICON_SIZE_TINY).
+        get_lang('EnrollStudentsFromExistingSessions'),
+    api_get_path(WEB_CODE_PATH).'session/add_students_to_session.php?id='.$id_session
+);
 ?>
     <div class="actions">
         <?php
         echo $link_add_type_unique;
         echo $link_add_type_multiple;
+        echo $link_add_group;
+        echo $newLinks;
         ?>
     </div>
     <form name="formulaire" method="post"
@@ -746,6 +762,10 @@ if ($add_type == 'multiple') {
                                 } ?>
                             </select>
                         </div>
+                        <input type="checkbox" onchange="checked_in_no_session(this.checked);"
+                               name="user_with_any_session" id="user_with_any_session_id">
+                        <label
+                            for="user_with_any_session_id"><?php echo get_lang('UsersRegisteredInNoSession'); ?></label>
                         <?php
                     }
                     unset($nosessionUsersList);

+ 82 - 57
main/survey/surveyUtil.class.php

@@ -231,7 +231,7 @@ class SurveyUtil
      */
     public static function handle_reporting_actions($survey_data, $people_filled)
     {
-        $action = isset($_GET['action']) ? $_GET['action'] : null;
+        $action = isset($_GET['action']) ? $_GET['action'] : '';
 
         // Getting the number of question
         $temp_questions_data = SurveyManager::get_questions($_GET['survey_id']);
@@ -249,20 +249,22 @@ class SurveyUtil
         // Counting the number of questions that are relevant for the reporting
         $survey_data['number_of_questions'] = count($questions_data);
 
-        if ($action == 'questionreport') {
-            self::display_question_report($survey_data);
-        }
-        if ($action == 'userreport') {
-            self::display_user_report($people_filled, $survey_data);
-        }
-        if ($action == 'comparativereport') {
-            self::display_comparative_report();
-        }
-        if ($action == 'completereport') {
-            self::display_complete_report($survey_data);
-        }
-        if ($action == 'deleteuserreport') {
-            self::delete_user_report($_GET['survey_id'], $_GET['user']);
+        switch ($action) {
+            case 'questionreport':
+                self::display_question_report($survey_data);
+                break;
+            case 'userreport':
+                self::display_user_report($people_filled, $survey_data);
+                break;
+            case 'comparativereport':
+                self::display_comparative_report();
+                break;
+            case 'completereport':
+                self::display_complete_report($survey_data);
+                break;
+            case 'deleteuserreport':
+                self::delete_user_report($_GET['survey_id'], $_GET['user']);
+                break;
         }
     }
 
@@ -379,7 +381,7 @@ class SurveyUtil
 
         echo '<select name="user" onchange="jumpMenu(\'parent\',this,0)">';
         echo '<option value="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action='
-            .Security::remove_XSS($_GET['action']).'&survey_id='.intval($_GET['survey_id']).'">'
+            .Security::remove_XSS($_GET['action']).'&survey_id='.$surveyId.'&'.api_get_cidreq().'">'
             .get_lang('SelectUser').'</option>';
 
         foreach ($people_filled as $key => &$person) {
@@ -395,8 +397,8 @@ class SurveyUtil
                 $id = $person;
             }
             echo '<option value="'.api_get_path(WEB_CODE_PATH).'survey/reporting.php?action='
-                .Security::remove_XSS($_GET['action']).'&survey_id='.intval($_GET['survey_id']).'&user='
-                .Security::remove_XSS($id).'" ';
+                .Security::remove_XSS($_GET['action']).'&survey_id='.$surveyId.'&user='
+                .Security::remove_XSS($id).'&'.api_get_cidreq().'" ';
             if (isset($_GET['user']) && $_GET['user'] == $id) {
                 echo 'selected="selected"';
             }
@@ -431,7 +433,8 @@ class SurveyUtil
 					    survey_question.question_id = survey_question_option.question_id AND
 					    survey_question_option.c_id = $course_id
 					WHERE
-					    survey_question.survey_id = '".intval($_GET['survey_id'])."' AND
+					    survey_question NOT LIKE '%{{%' AND
+					    survey_question.survey_id = '".$surveyId."' AND
                         survey_question.c_id = $course_id
 					ORDER BY survey_question.sort, survey_question_option.sort ASC";
             $result = Database::query($sql);
@@ -451,7 +454,7 @@ class SurveyUtil
             $sql = "SELECT * FROM $table_survey_answer
 			        WHERE
                         c_id = $course_id AND
-                        survey_id = '".intval($_GET['survey_id'])."' AND
+                        survey_id = '".$surveyId."' AND
                         user = '".Database::escape_string($_GET['user'])."'";
             $result = Database::query($sql);
             while ($row = Database::fetch_array($result, 'ASSOC')) {
@@ -583,6 +586,7 @@ class SurveyUtil
 			        WHERE
 			            c_id = $course_id AND
                         survey_id='".$surveyId."' AND
+                        survey_question NOT LIKE '%{{%' AND
                         type <>'pagebreak'                        
                     ORDER BY sort ASC
                     $limitStatement";
@@ -963,6 +967,7 @@ class SurveyUtil
 				LEFT JOIN $table_survey_question_option o
 				ON q.question_id = o.question_id AND q.c_id = o.c_id
 				WHERE 
+				    survey_question NOT LIKE '%{{%' AND
 				    q.survey_id = '".$surveyId."' AND
 				    q.c_id = $course_id
 				GROUP BY q.question_id
@@ -1022,6 +1027,7 @@ class SurveyUtil
 				LEFT JOIN $table_survey_question_option sqo
 				ON sq.question_id = sqo.question_id AND sq.c_id = sqo.c_id
 				WHERE
+				    survey_question NOT LIKE '%{{%' AND
 				    sq.survey_id = '".$surveyId."' AND
                     sq.c_id = $course_id
 				ORDER BY sq.sort ASC, sqo.sort ASC";
@@ -1175,7 +1181,9 @@ class SurveyUtil
             foreach ($possible_options as $question_id => &$possible_option) {
                 if ($questions[$question_id]['type'] == 'open' || $questions[$question_id]['type'] == 'comment') {
                     echo '<td align="center">';
-                    echo $answers_of_user[$question_id]['0']['option_id'];
+                    if (isset($answers_of_user[$question_id]) && isset($answers_of_user[$question_id]['0'])) {
+                        echo $answers_of_user[$question_id]['0']['option_id'];
+                    }
                     echo '</td>';
                 } else {
                     foreach ($possible_option as $option_id => &$value) {
@@ -1216,17 +1224,16 @@ class SurveyUtil
      */
     public static function export_complete_report($survey_data, $user_id = 0)
     {
-        // Database table definitions
-        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
-        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
-        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
-
         $surveyId = isset($_GET['survey_id']) ? (int) $_GET['survey_id'] : 0;
 
         if (empty($surveyId)) {
             return false;
         }
 
+        $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
+        $table_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
+        $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
+
         // The first column
         $return = ';';
 
@@ -1251,12 +1258,17 @@ class SurveyUtil
                     count(options.question_option_id) as number_of_options
 				FROM $table_survey_question questions
                 LEFT JOIN $table_survey_question_option options
-				ON questions.question_id = options.question_id AND options.c_id = questions.c_id
+				ON 
+				  questions.question_id = options.question_id AND 
+				  options.c_id = questions.c_id
 				WHERE
-				    questions.survey_id = '".$surveyId."' AND
+				    survey_question NOT LIKE '%{{%' AND
+				    questions.type <> 'pagebreak' AND
+				    questions.survey_id = $surveyId AND
                     questions.c_id = $course_id
 				GROUP BY questions.question_id
 				ORDER BY questions.sort ASC";
+
         $result = Database::query($sql);
         while ($row = Database::fetch_array($result)) {
             // We show the questions if
@@ -1267,24 +1279,21 @@ class SurveyUtil
                     is_array($_POST['questions_filter']) &&
                     in_array($row['question_id'], $_POST['questions_filter']))
             ) {
-                // We do not show comment and pagebreak question types
-                if ($row['type'] != 'pagebreak') {
-                    if ($row['number_of_options'] == 0 && ($row['type'] == 'open' || $row['type'] == 'comment')) {
+                if ($row['number_of_options'] == 0) {
+                    $return .= str_replace(
+                        "\r\n",
+                        '  ',
+                        api_html_entity_decode(strip_tags($row['survey_question']), ENT_QUOTES)
+                    )
+                    .';';
+                } else {
+                    for ($ii = 0; $ii < $row['number_of_options']; $ii++) {
                         $return .= str_replace(
                             "\r\n",
                             '  ',
                             api_html_entity_decode(strip_tags($row['survey_question']), ENT_QUOTES)
                         )
                         .';';
-                    } else {
-                        for ($ii = 0; $ii < $row['number_of_options']; $ii++) {
-                            $return .= str_replace(
-                                "\r\n",
-                                '  ',
-                                api_html_entity_decode(strip_tags($row['survey_question']), ENT_QUOTES)
-                            )
-                            .';';
-                        }
                     }
                 }
             }
@@ -1306,7 +1315,7 @@ class SurveyUtil
             }
         }
 
-        $sql = "SELECT
+        $sql = "SELECT DISTINCT
 		            survey_question.question_id,
 		            survey_question.survey_id,
 		            survey_question.survey_question,
@@ -1322,7 +1331,9 @@ class SurveyUtil
 				    survey_question.question_id = survey_question_option.question_id AND
 				    survey_question_option.c_id = survey_question.c_id
 				WHERE
-				    survey_question.survey_id = '".$surveyId."' AND
+				    survey_question NOT LIKE '%{{%' AND			
+				    survey_question.type <> 'pagebreak' AND				    
+				    survey_question.survey_id = $surveyId AND
 				    survey_question.c_id = $course_id
 				ORDER BY survey_question.sort ASC, survey_question_option.sort ASC";
         $result = Database::query($sql);
@@ -1337,30 +1348,35 @@ class SurveyUtil
                 in_array($row['question_id'], $_POST['questions_filter'])
             )
             ) {
-                // We do not show comment and pagebreak question types
-                if ($row['type'] != 'pagebreak') {
-                    $row['option_text'] = str_replace(["\r", "\n"], ['', ''], $row['option_text']);
-                    $return .= api_html_entity_decode(strip_tags($row['option_text']), ENT_QUOTES).';';
-                    $possible_answers[$row['question_id']][$row['question_option_id']] = $row['question_option_id'];
-                    $possible_answers_type[$row['question_id']] = $row['type'];
-                }
+                $row['option_text'] = str_replace(["\r", "\n"], ['', ''], $row['option_text']);
+                $return .= api_html_entity_decode(strip_tags($row['option_text']), ENT_QUOTES).';';
+                $possible_answers[$row['question_id']][$row['question_option_id']] = $row['question_option_id'];
+                $possible_answers_type[$row['question_id']] = $row['type'];
             }
         }
+
         $return .= "\n";
 
         // Getting all the answers of the users
         $old_user = '';
         $answers_of_user = [];
         $sql = "SELECT * FROM $table_survey_answer
-		        WHERE c_id = $course_id AND survey_id='".$surveyId."'";
+		        WHERE 
+		          c_id = $course_id AND 
+		          survey_id='".$surveyId."'		           
+		          ";
         if ($user_id != 0) {
             $sql .= "AND user='".Database::escape_string($user_id)."' ";
         }
-        $sql .= "ORDER BY user ASC";
+        $sql .= ' ORDER BY user ASC ';
 
+        $questionIdList = array_keys($possible_answers_type);
         $open_question_iterator = 1;
         $result = Database::query($sql);
-        while ($row = Database::fetch_array($result)) {
+        while ($row = Database::fetch_array($result, 'ASSOC')) {
+            if (!in_array($row['question_id'], $questionIdList)) {
+                continue;
+            }
             if ($old_user != $row['user'] && $old_user != '') {
                 $return .= self::export_complete_report_row(
                     $survey_data,
@@ -1371,6 +1387,7 @@ class SurveyUtil
                 );
                 $answers_of_user = [];
             }
+
             if ($possible_answers_type[$row['question_id']] == 'open' ||
                 $possible_answers_type[$row['question_id']] == 'comment'
             ) {
@@ -1382,6 +1399,7 @@ class SurveyUtil
             }
             $old_user = $row['user'];
         }
+
         // This is to display the last user
         $return .= self::export_complete_report_row(
             $survey_data,
@@ -1639,7 +1657,7 @@ class SurveyUtil
         if ($user_id != 0) {
             $sql .= " AND user='".$user_id."' ";
         }
-        $sql .= " ORDER BY user ASC";
+        $sql .= ' ORDER BY user ASC';
 
         $open_question_iterator = 1;
         $result = Database::query($sql);
@@ -1827,6 +1845,13 @@ class SurveyUtil
         $optionsY = ['----'];
         $defaults = [];
         foreach ($questions as $key => &$question) {
+            // Ignored tagged questions
+            if ($question) {
+                if (strpos($question['question'], '{{') !== false) {
+                    $question = null;
+                    continue;
+                }
+            }
             if (is_array($allowed_question_types)) {
                 if (in_array($question['type'], $allowed_question_types)) {
                     if (isset($_GET['xaxis']) && $_GET['xaxis'] == $question['question_id']) {
@@ -1837,8 +1862,8 @@ class SurveyUtil
                         $defaults['yaxis'] = $question['question_id'];
                     }
 
-                    $optionsX[$question['question_id']] = api_substr(strip_tags($question['question']), 0, 50);
-                    $optionsY[$question['question_id']] = api_substr(strip_tags($question['question']), 0, 50);
+                    $optionsX[$question['question_id']] = api_substr(strip_tags($question['question']), 0, 90);
+                    $optionsY[$question['question_id']] = api_substr(strip_tags($question['question']), 0, 90);
                 }
             }
         }
@@ -2837,13 +2862,13 @@ class SurveyUtil
                 );
 
                 $actions[] = Display::url(
-                    Display::return_icon('star.png', get_lang('MultiplicateSurvey')),
+                    Display::return_icon('multiplicate_survey.png', get_lang('MultiplicateQuestions')),
                     $codePath.'survey/survey_list.php?'
                     .http_build_query($params + ['action' => 'multiplicate', 'survey_id' => $survey_id])
                 );
 
                 $actions[] = Display::url(
-                    Display::return_icon('star_na.png', get_lang('RemoveMultiplicateQuestions')),
+                    Display::return_icon('multiplicate_survey_na.png', get_lang('RemoveMultiplicateQuestions')),
                     $codePath.'survey/survey_list.php?'
                     .http_build_query($params + ['action' => 'remove_multiplicate', 'survey_id' => $survey_id])
                 );

+ 1 - 1
main/survey/survey_list.php

@@ -189,7 +189,7 @@ if (!api_is_session_general_coach() || $extend_rights_for_coachs == 'true') {
     echo '<a href="'.api_get_path(WEB_CODE_PATH).'survey/create_new_survey.php?'.api_get_cidreq().'&amp;action=add">'.
         Display::return_icon('new_survey.png', get_lang('CreateNewSurvey'), '', ICON_SIZE_MEDIUM).'</a> ';
     $url = api_get_path(WEB_CODE_PATH).'survey/create_meeting.php?'.api_get_cidreq();
-    echo Display::url(Display::return_icon('add.png', get_lang('CreateNewSurvey'), '', ICON_SIZE_MEDIUM), $url);
+    echo Display::url(Display::return_icon('add_doodle.png', get_lang('CreateNewSurveyDoodle'), '', ICON_SIZE_MEDIUM), $url);
 }
 echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;search=advanced">'.
     Display::return_icon('search.png', get_lang('Search'), '', ICON_SIZE_MEDIUM).'</a>';

+ 43 - 14
main/tracking/courseLog.php

@@ -35,7 +35,6 @@ $is_allowedToTrack = Tracking::isAllowToTrack($session_id);
 
 if (!$is_allowedToTrack) {
     api_not_allowed(true);
-    exit;
 }
 
 // If the user is a HR director (drh)
@@ -73,7 +72,6 @@ if (api_is_drh()) {
         $coursesFollowedList = array_keys($coursesFollowedList);
         if (!in_array($courseId, $coursesFollowedList)) {
             api_not_allowed(true);
-            exit;
         }
     }
 }
@@ -342,7 +340,7 @@ if ($showReporting) {
 
 // Show the charts part only if there are students subscribed to this course/session
 if ($nbStudents > 0) {
-    $usersTracking = TrackingCourseLog::get_user_data(null, $nbStudents, null, 'DESC');
+    $usersTracking = TrackingCourseLog::get_user_data(null, $nbStudents, null, 'DESC', false);
     $numberStudentsCompletedLP = 0;
     $averageStudentsTestScore = 0;
     $scoresDistribution = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
@@ -412,7 +410,7 @@ if ($nbStudents > 0) {
     $tpl->assign('number_students', $nbStudents);
     $tpl->assign('top_students', $userScoreList);
 
-    $trackingSummaryLayout = $tpl->get_template("tracking/tracking_course_log.tpl");
+    $trackingSummaryLayout = $tpl->get_template('tracking/tracking_course_log.tpl');
     $content = $tpl->fetch($trackingSummaryLayout);
 
     echo $content;
@@ -508,21 +506,50 @@ if (count($a_students) > 0) {
     $table->set_header(3, get_lang('Login'), false);
     $headers['login'] = get_lang('Login');
 
-    $table->set_header(4, get_lang('TrainingTime').'&nbsp;'.
-        Display::return_icon('info3.gif', get_lang('CourseTimeInfo'), ['align' => 'absmiddle', 'hspace' => '3px']), false, ['style' => 'width:110px;']);
+    $table->set_header(
+        4,
+        get_lang('TrainingTime').'&nbsp;'.
+        Display::return_icon('info3.gif', get_lang('CourseTimeInfo'), ['align' => 'absmiddle', 'hspace' => '3px']),
+        false,
+        ['style' => 'width:110px;']
+    );
     $headers['training_time'] = get_lang('TrainingTime');
     $table->set_header(5, get_lang('CourseProgress').'&nbsp;'.
-        Display::return_icon('info3.gif', get_lang('ScormAndLPProgressTotalAverage'), ['align' => 'absmiddle', 'hspace' => '3px']), false, ['style' => 'width:110px;']);
+        Display::return_icon(
+            'info3.gif',
+            get_lang('ScormAndLPProgressTotalAverage'),
+            ['align' => 'absmiddle', 'hspace' => '3px']
+        ),
+        false,
+        ['style' => 'width:110px;']
+    );
     $headers['course_progress'] = get_lang('CourseProgress');
 
     $table->set_header(6, get_lang('ExerciseProgress').'&nbsp;'.
-        Display::return_icon('info3.gif', get_lang('ExerciseProgressInfo'), ['align' => 'absmiddle', 'hspace' => '3px']), false, ['style' => 'width:110px;']);
+        Display::return_icon(
+            'info3.gif',
+            get_lang('ExerciseProgressInfo'),
+            ['align' => 'absmiddle', 'hspace' => '3px']
+        ),
+        false,
+        ['style' => 'width:110px;']
+    );
     $headers['exercise_progress'] = get_lang('ExerciseProgress');
     $table->set_header(7, get_lang('ExerciseAverage').'&nbsp;'.
-        Display::return_icon('info3.gif', get_lang('ExerciseAverageInfo'), ['align' => 'absmiddle', 'hspace' => '3px']), false, ['style' => 'width:110px;']);
+        Display::return_icon('info3.gif', get_lang('ExerciseAverageInfo'), ['align' => 'absmiddle', 'hspace' => '3px']),
+        false,
+        ['style' => 'width:110px;']
+    );
     $headers['exercise_average'] = get_lang('ExerciseAverage');
     $table->set_header(8, get_lang('Score').'&nbsp;'.
-        Display::return_icon('info3.gif', get_lang('ScormAndLPTestTotalAverage'), ['align' => 'absmiddle', 'hspace' => '3px']), false, ['style' => 'width:110px;']);
+        Display::return_icon(
+            'info3.gif',
+            get_lang('ScormAndLPTestTotalAverage'),
+            ['align' => 'absmiddle', 'hspace' => '3px']
+        ),
+        false,
+        ['style' => 'width:110px;']
+    );
     $headers['score'] = get_lang('Score');
     $table->set_header(9, get_lang('Student_publication'), false);
     $headers['student_publication'] = get_lang('Student_publication');
@@ -633,19 +660,21 @@ if ($export_csv) {
     }
     ob_end_clean();
 
+    $csvContentInSession = Session::read('csv_content');
+    // Adding headers before the content.
     // Adding headers before the content.
-    array_unshift($csv_content, $csv_headers);
+    array_unshift($csvContentInSession, $csv_headers);
 
     if ($session_id) {
         $sessionData = [];
         $sessionInfo = api_get_session_info($session_id);
         $sessionDates = SessionManager::parseSessionDates($sessionInfo);
 
-        array_unshift($csv_content, [get_lang('Date'), $sessionDates['access']]);
-        array_unshift($csv_content, [get_lang('SessionName'), $sessionInfo['name']]);
+        array_unshift($csvContentInSession, [get_lang('Date'), $sessionDates['access']]);
+        array_unshift($csvContentInSession, [get_lang('SessionName'), $sessionInfo['name']]);
     }
 
-    Export::arrayToCsv($csv_content, 'reporting_student_list');
+    Export::arrayToCsv($csvContentInSession, 'reporting_student_list');
     exit;
 }
 Display::display_footer();