Browse Source

Minor - partial merge from 1.11.x

Julio Montoya 6 years ago
parent
commit
10c0575477
49 changed files with 6200 additions and 445 deletions
  1. 23 0
      main/extra/create_exam.php
  2. 21 0
      main/extra/create_intervention.php
  3. 82 0
      main/extra/create_school_calendar.php
  4. 97 0
      main/extra/database.php
  5. 21 0
      main/extra/delete_exam.php
  6. 69 0
      main/extra/edit_exam.php
  7. 61 0
      main/extra/edit_intervention.php
  8. 427 0
      main/extra/group_space_tracking.php
  9. 2653 0
      main/extra/myStudents.php
  10. 514 0
      main/extra/my_progress_ind.php
  11. 222 0
      main/extra/print_myStudents.php
  12. 67 0
      main/extra/save_school_calendar.php
  13. 28 0
      main/extra/update_exam.php
  14. 18 0
      main/extra/update_intervention.php
  15. 33 0
      main/extra/upgrade_school_calendar.php
  16. 456 0
      main/extra/userInfo.php
  17. 614 0
      main/extra/userInfoLib.php
  18. 45 31
      main/messages/new_message.php
  19. 24 0
      main/messages/record_audio.php
  20. 2 2
      main/messages/view_message.php
  21. 3 4
      main/mySpace/admin_view.php
  22. 12 1
      main/mySpace/course.php
  23. 26 8
      main/mySpace/index.php
  24. 426 293
      main/mySpace/myStudents.php
  25. 4 6
      main/session/about.php
  26. 1 1
      main/session/add_users_to_session.php
  27. 1 1
      main/session/session_export.php
  28. 14 11
      main/social/groups.php
  29. 2 2
      main/social/home.php
  30. 4 4
      main/social/invitations.php
  31. 1 1
      main/social/my_skills_report.php
  32. 4 6
      main/social/myfiles.php
  33. 0 1
      main/social/vcard_export.php
  34. 33 8
      main/survey/fillsurvey.php
  35. 26 8
      main/survey/surveyUtil.class.php
  36. 14 9
      main/ticket/new_ticket.php
  37. 3 3
      main/ticket/tickets.php
  38. 1 1
      main/ticket/tutor.php
  39. 1 3
      main/upload/form.document.php
  40. 1 1
      main/upload/form.scorm.php
  41. 1 9
      main/upload/index.php
  42. 1 1
      main/upload/upload.scorm.php
  43. 5 6
      main/upload/upload_ppt.php
  44. 1 4
      main/upload/upload_word.php
  45. 8 9
      main/user/class.php
  46. 1 1
      main/user/classes.php
  47. 1 1
      main/webservices/additional_webservices.php
  48. 126 6
      main/webservices/registration.soap.php
  49. 2 3
      main/work/add_document.php

+ 23 - 0
main/extra/create_exam.php

@@ -0,0 +1,23 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+require_once '../inc/global.inc.php';
+
+$allow = api_get_configuration_value('extra');
+if (empty($allow)) {
+    exit;
+}
+
+$table = Database:: get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
+$ex_user_id = isset($_GET['ex_user_id']) ? (int) $_GET['ex_user_id'] : '';
+$mod_no = isset($_GET['mod_no']) ? Database::escape_string($_GET['mod_no']) : '';
+$score_ex = isset($_GET['score_ex']) ? Database::escape_string($_GET['score_ex']) : '';
+$score_rep1 = isset($_GET['score_rep1']) ? Database::escape_string($_GET['score_rep1']) : '';
+$score_rep2 = isset($_GET['score_rep2']) ? Database::escape_string($_GET['score_rep2']) : '';
+$coment = isset($_GET['coment']) ? Database::escape_string($_GET['coment']) : '';
+
+$sql = "INSERT INTO $table (exe_user_id, c_id, mod_no, score_ex, score_rep1, score_rep2, coment)
+        VALUES ($ex_user_id, 0, '$mod_no', '$score_ex', '$score_rep1', '$score_rep2', '$coment')";
+Database::query($sql);
+header("location: myStudents.php?student=$ex_user_id");
+exit;

+ 21 - 0
main/extra/create_intervention.php

@@ -0,0 +1,21 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+require_once '../inc/global.inc.php';
+
+$allow = api_get_configuration_value('extra');
+if (empty($allow)) {
+    exit;
+}
+
+$table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
+$comment = isset($_POST['inter_coment']) ? Database::escape_string($_POST['inter_coment']) : '';
+$date = isset($_POST['date']) ? Database::escape_string($_POST['date']) : '';
+$level = isset($_POST['level']) ? Database::escape_string($_POST['level']) : '';
+$ex_user_id = isset($_POST['ex_user_id']) ? Database::escape_string($_POST['ex_user_id']) : '';
+
+$sql = "INSERT INTO $table (exe_user_id,c_id,level,exe_date,inter_coment)
+        VALUES ($ex_user_id, 0, '$level', '$date', '$comment')";
+Database::query($sql);
+header("location: myStudents.php?student=$ex_user_id");
+exit;

+ 82 - 0
main/extra/create_school_calendar.php

@@ -0,0 +1,82 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+// not used??
+exit;
+
+require_once '../inc/global.inc.php';
+
+$allow = api_get_configuration_value('extra');
+if (empty($allow)) {
+    exit;
+}
+
+$view = $_REQUEST['view'];
+Display::display_header($nameTools, "Tracking");
+
+$title = isset($_POST['title']) ? $_POST['title'] : "";
+$je = isset($_POST['je']) ? Security::remove_XSS($_POST['je']) : "";
+$me = isset($_POST['me']) ? Security::remove_XSS($_POST['me']) : "";
+$ye = isset($_POST['ye']) ? Security::remove_XSS($_POST['ye']) : "";
+
+foreach ($_POST as $index => $valeur) {
+    $$index = Database::escape_string(trim($valeur));
+}
+
+$start_time = "$y-$m-$j";
+$end_time = "$ye-$me-$je";
+
+// On v�rifie si les champs sont vides
+if (empty($title)) {
+    echo '<font color="red">Attention, vous avez oubliez le nom du calendrier</font>';
+}
+?>
+<form action="save_school_calendar.php" method="post" name="save_cal">
+    <table class='data_table'>
+        <tr>
+            <th colspan="3">
+                <?php echo get_lang('edit_save'); ?>
+            </th>
+        <tr>
+            <th><?php echo get_lang('title_calendar'); ?></th>
+            <th><?php echo get_lang('period'); ?></th>
+            <th><?php echo get_lang('action'); ?></th>
+        </tr>
+        <td>
+            <input type=texte name=title value=<?php echo "$title"; ?>/>
+        </td>
+        <td>
+            <input SIZE=25 NAME=period
+                   value=<?php echo "$langFrom", ":", "$start_time", "$langTo", "$end_time"; ?>/>
+        </td>
+        <?php
+
+        $date1 = strtotime($start_time); //Premiere date
+        $date2 = strtotime($end_time); //Deuxieme date
+        $nbjour = ($date2 - $date1) / 60 / 60 / 24; //Nombre de jours entre les deux
+        $nbcol = 2;
+
+        echo "<table border='1'><tr>";
+        if ($i % $nbcol == 0) {
+            for ($i = 0; $i <= $nbjour; $i++) {
+                echo "<td><input type='text' NAME='date_case' size='8' value=".date('Y-m-d', $date1)."> ";
+                $date1 += 60 * 60 * 24; //On additionne d'un jour (en seconde)
+                echo '<br>';
+                echo '</td>';
+                echo "<td><input type='text' NAME='day_number' size='4' value=".$number."/></td>";
+                echo "<td><input type='text' NAME='d_title' size='4' value=".$title."/></td>";
+                $sql4 = "INSERT INTO set_module (cal_name,cal_day_num,cal_date) 
+                         VALUES ('$title','$number','".date('Y-m-d', $date1)."') ";
+                Database::query($sql4);
+                if ($i % $nbcol == ($nbcol - 1)) {
+                    echo "</tr>";
+                }
+            }
+        }
+        ?>
+        </tr>
+        <input type="submit" value="Sauvegarder" name="B1">
+    </table>
+</form>
+<?php
+Display::display_footer();

+ 97 - 0
main/extra/database.php

@@ -0,0 +1,97 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+require_once '../inc/global.inc.php';
+
+// database changes
+
+exit;
+
+$sql = "ALTER TABLE track_e_exercises ADD COLUMN coment VARCHAR(255);";
+Database::query($sql);
+
+$sql = "ALTER TABLE track_e_exercises ADD COLUMN diff VARCHAR(255);";
+Database::query($sql);
+
+$sql = "ALTER TABLE track_e_exercises ADD COLUMN mod_no VARCHAR(255);";
+Database::query($sql);
+
+$sql = "ALTER TABLE track_e_exercises ADD COLUMN score_ex VARCHAR(255);";
+Database::query($sql);
+
+$sql = "ALTER TABLE track_e_exercises ADD COLUMN score_rep1 VARCHAR(255);";
+Database::query($sql);
+
+$sql = "ALTER TABLE track_e_exercises ADD COLUMN score_rep2 VARCHAR(255);";
+Database::query($sql);
+
+$sql = "ALTER TABLE track_e_exercises ADD COLUMN inter_coment VARCHAR(255);";
+Database::query($sql);
+
+$sql = "ALTER TABLE track_e_exercises ADD COLUMN level VARCHAR(255);";
+Database::query($sql);
+
+$sql = "CREATE TABLE IF NOT EXISTS set_module   (
+`id` int(4) NOT NULL AUTO_INCREMENT,
+  `cours` varchar(40) NOT NULL,
+  `module` varchar(40) NOT NULL,
+  `jours` varchar(6) NOT NULL,
+  `cal_name` varchar(20) NOT NULL,
+  `cal_day_num` int(6) NOT NULL,
+  `cal_date` date NOT NULL,
+  PRIMARY KEY (`id`)
+)";
+
+Database::query($sql);
+
+/*$sql = "CREATE TABLE IF NOT EXISTS  `kezprerequisites` (
+`c_id` int(11) NOT NULL,
+  `lp_id` int(11) NOT NULL,
+  `id` int(11) NOT NULL,
+  `prereq` int(11) DEFAULT NULL,
+  `disporder` bigint(20) DEFAULT NULL,
+  PRIMARY KEY (`c_id`,`lp_id`,`id`)
+)";*/
+
+$sql = "CREATE TABLE IF NOT EXISTS `c_cal_dates` (
+`c_id` int(11) NOT NULL,
+  `date` date NOT NULL,
+  `status` varchar(1) NOT NULL,
+  `horaire_name` varchar(190) DEFAULT NULL,
+  UNIQUE KEY `temp` (`c_id`,`date`,`horaire_name`),
+  UNIQUE KEY `indexunique` (`c_id`,`date`,`horaire_name`),
+  KEY `idx` (`c_id`)
+)";
+
+Database::query($sql);
+
+$sql = "CREATE TABLE IF NOT EXISTS `c_cal_horaire` (
+`id` int(11) NOT NULL AUTO_INCREMENT,
+  `c_id` int(11) NOT NULL,
+  `name` varchar(190) NOT NULL,
+  `num_minute` int(11) NOT NULL,
+  `num_hours` int(11) NOT NULL,
+  `learnpath_dw` varchar(256) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `c_id` (`c_id`,`name`),
+  KEY `idx` (`c_id`)
+)";
+Database::query($sql);
+
+$sql = "CREATE TABLE IF NOT EXISTS `c_cal_set_module` (
+`id` int(4) NOT NULL AUTO_INCREMENT,
+  `c_id` varchar(40) NOT NULL,
+  `module` varchar(40) NOT NULL,
+  `minutes` int(6) NOT NULL,
+  PRIMARY KEY (`id`)
+)";
+
+Database::query($sql);
+
+$sql = "CREATE TABLE IF NOT EXISTS `c_cal_temp` (
+`c_id` int(11) NOT NULL,
+  `temp` varchar(250) NOT NULL,
+  `user` varchar(250) NOT NULL,
+  KEY `idx` (`c_id`)
+)";
+Database::query($sql);

+ 21 - 0
main/extra/delete_exam.php

@@ -0,0 +1,21 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+require_once '../inc/global.inc.php';
+
+$allow = api_get_configuration_value('extra');
+if (empty($allow)) {
+    exit;
+}
+
+api_block_anonymous_users();
+
+$ex_user_id = isset($_GET['student_id']) ? (int) $_GET['student_id'] : 0;
+$num = isset($_GET['num']) ? (int) $_GET['num'] : 0;
+
+$table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
+$sql = "DELETE FROM $table WHERE exe_id = $num";
+Database::query($sql);
+
+header("location: myStudents.php?student=$ex_user_id");
+exit;

+ 69 - 0
main/extra/edit_exam.php

@@ -0,0 +1,69 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+require_once '../inc/global.inc.php';
+
+$allow = api_get_configuration_value('extra');
+if (empty($allow)) {
+    exit;
+}
+
+api_block_anonymous_users();
+
+Display::display_header();
+
+$tbl_stats_exercices = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
+$num = isset($_GET['num']) ? (int) $_GET['num'] : '';
+$student_idd = isset($_GET['student_id']) ? (int) $_GET['student_id'] : '';
+
+?>
+<form action="update_exam.php" method="post" name="save_exam">
+    <table class='data_table'>
+        <tr>
+            <th colspan="6">
+                <?php echo get_lang('edit_save'); ?>
+            </th>
+        <tr>
+            <th><?php echo get_lang('module_no'); ?></th>
+            <th><?php echo get_lang('result_exam'); ?></th>
+            <th><?php echo get_lang('result_rep_1'); ?></th>
+            <th><?php echo get_lang('result_rep_2'); ?></th>
+            <th><?php echo get_lang('comment'); ?></th>
+            <th><?php echo get_lang('action'); ?></th>
+        </tr>
+        <?php
+
+        $sqlexam = "SELECT * FROM $tbl_stats_exercices WHERE exe_id = $num";
+        $resultexam = Database::query($sqlexam);
+        while ($a_exam = Database::fetch_array($resultexam)) {
+            $exe_id = $a_exam['exe_id'];
+            $mod_no = $a_exam['mod_no'];
+            $score_ex = $a_exam['score_ex'];
+            $score_rep1 = $a_exam['score_rep1'];
+            $score_rep2 = $a_exam['score_rep2'];
+            $coment = $a_exam['coment'];
+            echo "
+            <tr>
+                <td>
+                    <input type=text name=mod_no size=1 value= ".$a_exam['mod_no'].">
+                </td>
+                <td>
+                    <input type=text name=score_ex size=1 value=".$a_exam['score_ex'].">
+                </td>
+                <td><input type=text name=score_rep1 size=1 value=".$a_exam['score_rep1']."></td>
+                <td><input type=text name=score_rep2 size=1 value=".$a_exam['score_rep2']."></td>
+                <td><textarea name=\"coment\" cols=\"65\" rows=\"2\">$coment</textarea><br /></td>
+                <INPUT type=hidden name=ex_idd value=\"$exe_id\" />
+                <INPUT type=hidden name=student_id value=\"$student_idd\" />
+                <td>
+                    <input type=\"submit\" value=\"".get_lang('Save')."\" name=\"B1\">
+                </td>
+            </tr>
+            ";
+        }
+        ?>
+    </table>
+</form>
+<?php
+
+Display::display_footer();

+ 61 - 0
main/extra/edit_intervention.php

@@ -0,0 +1,61 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+require_once '../inc/global.inc.php';
+
+$allow = api_get_configuration_value('extra');
+if (empty($allow)) {
+    exit;
+}
+
+api_block_anonymous_users();
+
+Display::display_header();
+$num = isset($_GET['num']) ? (int) $_GET['num'] : 0;
+$student_idd = isset($_GET['student_id']) ? (int) $_GET['student_id'] : 0;
+$tbl_stats_exercices = Database:: get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
+
+?>
+<form action="update_intervention.php" method="post" name="save_intercention">
+    <table class='data_table'>
+        <tr>
+            <th colspan="4"><?php echo get_lang('Edit'); ?>
+        <tr>
+            <th><?php echo get_lang('Level'); ?></th>
+            <th><?php echo get_lang('Date'); ?></th>
+            <th><?php echo get_lang('interventions_commentaires'); ?></th>
+            <th><?php echo get_lang('Action'); ?></th>
+        </tr>
+        <?php
+        $sqlinter = "SELECT * FROM $tbl_stats_exercices WHERE exe_id = $num";
+        $resultinter = Database::query($sqlinter);
+        while ($a_inter = Database::fetch_array($resultinter)) {
+            $level = $a_inter['level'];
+            $mod_no = $a_inter['mod_no'];
+            $score_ex = $a_inter['score_ex'];
+            $inter_coment = stripslashes($a_inter['inter_coment']);
+            echo "
+                <tr>
+                <td> ".$a_inter['level']."
+                </td>
+                <td>
+                    ".$a_inter['exe_date']."
+                </td>";
+            $exe_id = $a_inter['exe_id']; ?>
+            <td>
+                <textarea name="inter_coment" cols="65" rows="2">
+                    <?php echo $inter_coment; ?>
+                </textarea>
+            </td>
+            <INPUT type=hidden name=exe_id value= <?php echo "$exe_id"; ?>/>
+            <INPUT type=hidden name=student_id value= <?php echo "$student_idd"; ?>/>
+            <td><input type="submit" value="Sauvegarder" name="B1"></td>
+            </tr>
+            <?php
+        }
+        ?>
+    </table>
+</form>
+<?php
+
+Display::display_footer();

+ 427 - 0
main/extra/group_space_tracking.php

@@ -0,0 +1,427 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+require_once '../inc/global.inc.php';
+
+$allow = api_get_configuration_value('extra');
+if (empty($allow)) {
+    exit;
+}
+
+$current_course_tool = TOOL_GROUP;
+
+// Notice for unauthorized people.
+api_protect_course_script(true);
+
+/*  Libraries & config files */
+require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
+require_once api_get_path(SYS_CODE_PATH).'forum/forumconfig.inc.php';
+/*  MAIN CODE */
+$group_id = api_get_group_id();
+$user_id = api_get_user_id();
+$current_group = GroupManager:: get_group_properties($group_id);
+// regroup table names for maintenance purpose
+if (!api_is_allowed_to_edit(false, true) && !$is_group_member) {
+    api_not_allowed(true);
+}
+$tbl_stats_exercices_temp = Database:: get_main_table(track_e_exercices_temp);
+//on vide la table temp qui recoit les examen complétés
+$query = "TRUNCATE TABLE $tbl_stats_exercices_temp ";
+$result = Database::query($query);
+if (empty($current_group)) {
+    api_not_allowed(true);
+}
+
+$this_section = SECTION_COURSES;
+$nameTools = get_lang('suivi_de');
+$interbreadcrumb[] = ['url' => 'group.php', 'name' => get_lang('Groups')];
+$forums_of_groups = get_forums_of_group($current_group['id']);
+$forum_state_public = 0;
+if (is_array($forums_of_groups)) {
+    foreach ($forums_of_groups as $key => $value) {
+        if ($value['forum_group_public_private'] == 'public') {
+            $forum_state_public = 1;
+        }
+    }
+}
+
+if ($current_group['doc_state'] != 1 &&
+    $current_group['calendar_state'] != 1 &&
+    $current_group['work_state'] != 1 &&
+    $current_group['announcements_state'] != 1 &&
+    $current_group['wiki_state'] != 1 &&
+    $current_group['chat_state'] != 1 &&
+    $forum_state_public != 1
+) {
+    if (!api_is_allowed_to_edit(null, true) &&
+        !GroupManager::is_user_in_group($user_id, $group_id)) {
+        api_not_allowed($print_headers);
+    }
+}
+
+/*  Header */
+Display::display_header($nameTools.' '.Security::remove_XSS($current_group['name']), 'Group');
+Display::display_introduction_section(TOOL_GROUP);
+
+$course_code = api_get_course_id();
+$is_course_member = CourseManager::is_user_subscribed_in_real_or_linked_course(
+    api_get_user_id(),
+    $course_code
+);
+
+/*
+ * List all the tutors of the current group
+ */
+$tutors = GroupManager::get_subscribed_tutors($current_group['id']);
+
+$tutor_info = '';
+if (count($tutors) == 0) {
+    $tutor_info = get_lang('GroupNoneMasc');
+} else {
+    isset($origin) ? $my_origin = $origin : $my_origin = '';
+    $tutor_info .= '<ul class="thumbnails">';
+    foreach ($tutors as $index => $tutor) {
+        $tab_user_info = api_get_user_info($tutor['user_id']);
+        $username = api_htmlentities(sprintf(get_lang('LoginX'), $tab_user_info['username']), ENT_QUOTES);
+        $image_path = UserManager::get_user_picture_path_by_id($tutor['user_id'], 'web', false, true);
+        $image_repository = $image_path['dir'];
+        $existing_image = $image_path['file'];
+        $completeName = api_get_person_name($tutor['firstname'], $tutor['lastname']);
+        $photo = '<img src="'.$image_repository.$existing_image.'" alt="'.$completeName.'" width="32" height="32" title="'.$completeName.'" />';
+        $tutor_info .= '<li><a href="'.api_get_path(
+                WEB_CODE_PATH
+            ).'user/userInfo.php?origin='.$my_origin.'&amp;uInfo='.$tutor['user_id'].'">'.
+            $photo.'&nbsp;'.$completeName.'</a></li>';
+    }
+    $tutor_info .= '</ul>';
+}
+
+echo Display::page_subheader(get_lang('GroupTutors'));
+if (!empty($tutor_info)) {
+    echo $tutor_info;
+}
+
+/*
+ * List all the members of the current group
+ */
+echo '<div class="actions">';
+$now = date('Y-m-d');
+echo '&nbsp;Le '.$now.' <a href="#" onclick="window.print()"><img align="absbottom" src="../img/printmgr.gif">&nbsp;'.get_lang(
+        'Print'
+    ).'</a>';
+echo '&nbsp; <a target="_blank" href="save_diff_all.php"><img src="'.api_get_path(
+        WEB_IMG_PATH
+    ).'addd.gif" border="0" />'.get_lang('save_diff_all').'</a>';
+echo '</div>';
+
+$table = new SortableTable(
+    'group_users',
+    'get_number_of_group_users',
+    'get_group_user_data',
+    (api_is_western_name_order() xor api_sort_by_first_name()) ? 2 : 1
+);
+//$table -> display();
+$my_cidreq = isset($_GET['cidReq']) ? Security::remove_XSS($_GET['cidReq']) : '';
+$my_origin = isset($_GET['origin']) ? Security::remove_XSS($_GET['origin']) : '';
+$my_gidreq = isset($_GET['gidReq']) ? Security::remove_XSS($_GET['gidReq']) : '';
+$parameters = ['cidReq' => $my_cidreq, 'origin' => $my_origin, 'gidReq' => $my_gidreq];
+$table->set_additional_parameters($parameters);
+
+$table->set_header(1, get_lang('OfficialCode'), false, 'align="center"');
+if (api_is_western_name_order()) {
+    $table->set_header(2, get_lang('LastName'));
+    $table->set_header(3, get_lang('FirstName'));
+} else {
+    $table->set_header(2, get_lang('LastName'));
+    $table->set_header(3, get_lang('FirstName'));
+}
+//the order of these calls is important
+$table->set_column_filter(2, 'user_name_filter');
+$table->set_column_filter(3, 'user_name_filter');
+$table->set_header(4, get_lang('Examen'), false);
+//the order of these calls is important
+$table->set_column_filter(2, 'user_name_filter');
+$table->set_column_filter(3, 'user_name_filter');
+$table->set_header(4, get_lang('Examen'), false);
+$table->set_header(5, get_lang('LatestLogin'), false, 'align="center"');
+$table->set_header(6, get_lang('time_tot'), false, 'align="center"');
+$table->set_header(7, get_lang('jours_complet'), false, 'align="center"');
+$table->set_header(8, get_lang('diff_horaire'), false, 'align="center"');
+$table->set_header(9, get_lang('save_diff'), false, 'align="center"');
+$table->set_header(10, get_lang('GroupCalendar'), false, 'align="center"');
+$table->set_header(11, get_lang('Details'), false);
+
+// Database table definition
+$table_group_user = Database:: get_course_table(TABLE_GROUP_USER);
+$table_user = Database:: get_main_table(TABLE_MAIN_USER);
+
+//  $tbl_personal_agenda = Database :: get_user_personal_table(TABLE_PERSONAL_AGENDA);
+$tbl_personal_agenda = Database:: get_main_table(TABLE_PERSONAL_AGENDA);
+$tbl_course = Database:: get_main_table(TABLE_MAIN_COURSE);
+$tbl_course_user = Database:: get_main_table(TABLE_MAIN_COURSE_USER);
+$tbl_stats_exercices = Database:: get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
+$tbl_stats_exercices_temp = Database:: get_main_table(track_e_exercices_temp);
+$tbl_group_course_info = Database:: get_course_table(TABLE_GROUP);
+$course_id = api_get_course_int_id();
+
+//on trouve le vrai groupID
+$sql = "SELECT iid FROM ".$tbl_group_course_info."  
+        WHERE c_id=".$course_id." and id=".$current_group['id'];
+$current_group_result = Database::query($sql);
+$current_group = Database::fetch_assoc($current_group_result)['iid'];
+//on trouve les user dans le groupe
+$sql = "SELECT *
+        FROM ".$table_user." user, ".$table_group_user." group_rel_user 
+        WHERE group_rel_user.c_id = $course_id AND group_rel_user.user_id = user.user_id 
+        AND group_rel_user.group_id = ".$current_group." order by lastname
+  ";
+$result = Database::query($sql);
+// Francois Belisle Kezber
+//  Le TableDisplay contient une fonction qui set les headers... les headers sont plac�s dans la Row 0... Ce qui ecrase le contenue
+// le la vrai row 0... Il faut donc ajouter un empty record a la row 0 qui se fera ecras� par lesh headers plutot que le premier record
+// en ajoutant un empty record, ca fonctionne, mais il faut trouver pourquoi les headers ecrasent le premier record
+$row = [];
+
+$row[] = $student_datas['official_code'];
+$row[] = $student_datas['lastname'];
+$row[] = $student_datas['firstname'];
+$row[] = substr_replace($exampass, '', '0', '2');
+$row[] = $last_connection_date;
+$row[] = $time_tot;
+$row[] = $Total;
+$row[] = '<center>'.$sing.''.$diff.'&nbsp;'.$Days.''.$avertissement.'</font></b></center>';
+$row[] = '<center><a  target="_blank" href="save_diff.php?student='.$user_in_groupe.'&diff='.$ajout.''.$diff.'"><img src="'.api_get_path(
+        WEB_IMG_PATH
+    ).'addd.gif" border="0" /></a></center>';
+$row[] = '<center><a target="_blank" href="suivi_myagenda.php?user_id='.$user_in_groupe.'&action=view&view=personal&firstname='.$student_datas['firstname'].'&name='.$student_datas['lastname'].'"><img src="'.api_get_path(
+        WEB_IMG_PATH
+    ).'calendar_week.gif" border="0" /></a></center>';
+$row[] = '<center><a target="_blank" href="../mySpace/myStudents.php?student='.$user_in_groupe.'"><img src="'.api_get_path(
+        WEB_IMG_PATH
+    ).'2rightarrow.gif" border="0" /></a></center>';
+$all_datas[] = $row;
+
+foreach ($all_datas as $row) {
+    $table->addRow($row);
+}
+
+while ($resulta = Database::fetch_array($result)) {
+    $user_in_groupe = $resulta['user_id'];
+    unset($all_datas);
+    //on cherche les examens
+    $sqlexam = "SELECT  mod_no
+                 FROM $tbl_stats_exercices
+                 WHERE exe_user_id = '$user_in_groupe'
+                AND c_id = 0 AND (score_ex = 'SU' || score_rep1 = 'SU' || score_rep2 ='SU')
+                ORDER BY mod_no ASC";
+    $resultexam = Database::query($sqlexam);
+    while ($a_exam = Database::fetch_array($resultexam)) {
+        $exam = "$exam - $a_exam[0]";
+    }
+    Database::query(
+        "INSERT INTO $tbl_stats_exercices_temp (id, exe_user_id, mod_passed) VALUES('', '$user_in_groupe',  '$exam') "
+    );
+    //fin de exam
+    //on compte le nombre de m% dans l'agenda pour chaque module
+    /*
+       $sqljtot =  "SELECT COUNT( * ) AS TOT
+                                   FROM $tbl_personal_agenda
+                                   WHERE user = '$user_in_groupe'
+                                   And title like 'm%'
+
+                                   ";
+                      $resultjt = Database::query($sqljtot);
+
+                      while($jtot = mysql_fetch_array($resultjt))
+                      {
+                       $jour_realise_tot = ($jour_realise + $jtot['TOT'])/ 2;
+
+                  }
+   //fin des jour de l'agenda
+  */
+    $course_code = $_course['id'];
+    $student_datas = api_get_user_info($user_in_groupe);
+    // affichage des jours complétés dans les parcours par chaque élève
+    //on recherche les cours où sont inscrit les user
+    $sql2 = "SELECT  c_id, user_id
+        FROM course_rel_user
+        WHERE user_id = '$user_in_groupe'
+        ";
+    $result2 = Database::query($sql2);
+    $Total = 0;
+    while ($a_courses = Database::fetch_array($result2)) {
+        $Courses_code = $a_courses['c_id'];
+        $Courses_rel_user_id = $a_courses['user_id'];
+        //on sort le temps passé dans chaque cours
+        $sql = "SELECT  SUM(UNIX_TIMESTAMP(logout_course_date) - UNIX_TIMESTAMP(login_course_date)) as nb_seconds
+                FROM track_e_course_access
+                WHERE UNIX_TIMESTAMP(logout_course_date) > UNIX_TIMESTAMP(login_course_date) AND c_id = $course_id AND user_id = '$user_in_groupe' 
+                ";
+        //echo($sql);
+        $rs = Database::query($sql);
+        $row2 = Database::fetch_array($rs);
+        $nb_secondes = $row2['nb_seconds'];
+        $time_tot1 += $nb_secondes;
+        //convertion secondes en temps
+        $time_tot = api_time_to_hms($time_tot1);
+        //on sort le c_id avec le code du cours
+        //$sql8 = "SELECT *
+        //      FROM course
+        //      WHERE id = '$Courses_code'
+        //      ";
+        //        $result8 = Database::query($sql8);
+        //        $course_code_id = Database::fetch_array($result8) ;
+        $c_id = $Courses_code;
+        //pours chaque cours dans lequel il est inscrit, on cherche les jours complétés
+        $Req3 = "SELECT *
+                    FROM c_lp_view
+                  WHERE user_id  = '$Courses_rel_user_id'
+                  AND c_id = '$c_id'
+                    ";
+        $res3 = Database::query($Req3);
+        while ($result3 = Database::fetch_array($res3)) {
+            $lp_id = $result3['lp_id'];
+            $lp_id_view = $result3['id'];
+            $c_id_view = $result3['c_id'];
+
+            $Req4 = "SELECT id, lp_id ,title ,item_type 
+                    FROM  c_lp_item
+                 WHERE lp_id =  '$lp_id'
+                 AND title LIKE '(+)%'
+                 AND c_id = '$c_id_view'
+                 AND item_type = 'document'
+            ";
+            $res4 = Database::query($Req4);
+
+            while ($resulta4 = Database::fetch_array($res4)) {
+                $lp_item_id = $resulta4['id'];
+                $Req5 = " SELECT Max(id)
+                FROM  c_lp_item_view
+                       WHERE  lp_item_id =  '$lp_item_id'
+                       AND lp_view_id =  '$lp_id_view'
+                        AND c_id = '$c_id_view'
+                         AND status =  'completed'
+                         ";
+                $res5 = Database::query($Req5);
+
+                while ($resul5 = Database::fetch_array($res5)) {
+                    $max = $resul5['0'];
+                    $Req6 = "SELECT COUNT( id )
+                             FROM  c_lp_item_view
+                             WHERE  id = '$max'
+                                  AND c_id = '$c_id_view'
+                                     ";
+                    $res6 = Database::query($Req6);
+                    while ($resultat6 = Database::fetch_array($res6)) {
+                        $Total = $Total + $resultat6[0];
+                    }
+                }
+            }
+        }
+    }
+
+    // fin affichage des jours complétés dans les parcours par chaque élève
+    // on recherche les exam sauvegardé dans la table temp
+    $sqlexamtot = "SELECT  mod_passed
+                 FROM $tbl_stats_exercices_temp
+                 WHERE exe_user_id = '$user_in_groupe'";
+    $resultexamtot = Database::query($sqlexamtot);
+    $a_examtot = Database::fetch_array($resultexamtot);
+    $exampass = $a_examtot['mod_passed'];
+    //on trouve le nombre dans l'agenda selon la date d'aujourdhui
+    //si rien n'est inscrit cette journée dans l'agenda, recule de -1
+    unset($jour_agenda);
+    $tour = -1;
+    while ($jour_agenda == '') {
+        $tour++;
+        $date = date("Y-m-d", mktime(0, 0, 0, date("m"), date("d") - $tour, date("Y")));
+        $sql4 = "SELECT *  FROM $tbl_personal_agenda
+                 WHERE user = '$user_in_groupe' AND 
+                 text='Pour le calendrier, ne pas effacer'
+                 AND date like '".$date." %:%'       
+                  ";
+        $result4 = Database::query($sql4);
+        $res4 = Database::fetch_array($result4);
+        $jour_agenda = $res4['title'];
+        if ($tour > 300) {
+            break;
+        }
+    }
+
+    //on affiche la différence
+    $diff = $jour_agenda - $Total;
+    if ($diff > 0) {
+        $sing = '<b><font color=#CC0000>';
+    } else {
+        $sing = '<b><font color=#008000>';
+    }
+    if ($diff > 0) {
+        $avertissement = get_lang('retard');
+    } else {
+        $avertissement = get_lang('avance');
+    }
+    if ($diff > 0) {
+        $ajout = '-';
+    } else {
+        $ajout = '';
+    }
+
+    $diff = abs($diff);
+    $last_connection_date = Tracking:: get_last_connection_date($user_in_groupe, true);
+    if ($last_connection_date == '') {
+        $last_connection_date = get_lang('NoConnexion');
+    }
+    // on présente tous les résultats
+    $row = [];
+    $row[] = $student_datas['official_code'];
+    $row[] = $student_datas['lastname'];
+    $row[] = $student_datas['firstname'];
+    $row[] = substr_replace($exampass, '', '0', '2');
+    $row[] = $last_connection_date;
+    $row[] = $time_tot;
+    $row[] = $Total;
+    $row[] = '<center>'.$sing.''.$diff.'&nbsp;'.$Days.''.$avertissement.'</font></b></center>';
+    $row[] = '<center><a  target="_blank" href="save_diff.php?student='.$user_in_groupe.'&diff='.$ajout.''.$diff.'"><img src="'.api_get_path(
+            WEB_IMG_PATH
+        ).'addd.gif" border="0" /></a></center>';
+    $row[] = '<center><a target="_blank" href="suivi_myagenda.php?user_id='.$user_in_groupe.'&action=view&view=personal&firstname='.$student_datas['firstname'].'&name='.$student_datas['lastname'].'"><img src="'.api_get_path(
+            WEB_IMG_PATH
+        ).'calendar_week.gif" border="0" /></a></center>';
+    $row[] = '<center><a target="_blank" href="../mySpace/myStudents.php?student='.$user_in_groupe.'"><img src="'.api_get_path(
+            WEB_IMG_PATH
+        ).'2rightarrow.gif" border="0" /></a></center>';
+    $all_datas[] = $row;
+
+    foreach ($all_datas as $row) {
+        $table->addRow($row);
+    }
+}
+$table->display();
+echo $precision_time;
+
+/**
+ * Return user profile link around the given user name.
+ *
+ * The parameters use a trick of the sorteable table, where the first param is
+ * the original value of the column
+ *
+ * @param   string  User name (value of the column at the time of calling)
+ * @param   string  URL parameters
+ * @param   array   Row of the "sortable table" as it is at the time of function call - we extract the user ID from
+ *                      there
+ *
+ * @return string HTML link
+ */
+function user_name_filter($name, $url_params, $row)
+{
+    $tab_user_info = api_get_user_info($row[0]);
+    $username = api_htmlentities(sprintf(get_lang('LoginX'), $tab_user_info['username']), ENT_QUOTES);
+
+    return '<a href="../user/userInfo.php?uInfo='.$row[0].'&amp;'.$url_params.'" title="'.$username.'">'.$name.'</a>';
+}
+
+// Footer
+$orig = isset($origin) ? $origin : '';
+if ($orig != 'learnpath') {
+    Display::display_footer();
+}

+ 2653 - 0
main/extra/myStudents.php

@@ -0,0 +1,2653 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+require_once '../inc/global.inc.php';
+
+$allow = api_get_configuration_value('extra');
+if (empty($allow)) {
+    exit;
+}
+
+api_block_anonymous_users();
+$export_csv = isset($_GET['export']) && $_GET['export'] === 'csv' ? true : false;
+$course_code = isset($_GET['course']) ? Security::remove_XSS($_GET['course']) : null;
+$_course = api_get_course_info();
+$coment = '';
+
+if (!api_is_allowed_to_create_course() &&
+    !api_is_session_admin() &&
+    !api_is_drh() &&
+    !api_is_student_boss() &&
+    !api_is_platform_admin()
+) {
+    // Check if the user is tutor of the course
+    $user_course_status = CourseManager::get_tutor_in_course_status(
+        api_get_user_id(),
+        api_get_course_int_id()
+    );
+
+    // Francois Belisle Kezber...
+    // If user is NOT a teacher -> student, but IS the teacher of the course... Won't have the global teacher status
+    // and won't be tutor... So have to check is_course_teacher
+    if (($user_course_status != 1) && !(CourseManager::is_course_teacher(api_get_user_id(), $course_code))) {
+        api_not_allowed(true);
+    }
+}
+
+$htmlHeadXtra[] = '<script>
+function show_image(image,width,height) {
+    width = parseInt(width) + 20;
+    height = parseInt(height) + 20;
+    window_x = window.open(image,\'windowX\',\'width=\'+ width + \', height=\'+ height + \'\');
+}
+</script>';
+
+$export = isset($_GET['export']) ? $_GET['export'] : false;
+$sessionId = isset($_GET['id_session']) ? intval($_GET['id_session']) : 0;
+$origin = isset($_GET['origin']) ? Security::remove_XSS($_GET['origin']) : '';
+$studentId = (int) $_GET['student'];
+$coachId = isset($_GET['id_coach']) ? (int) $_GET['id_coach'] : 0;
+
+// time spent on the course
+$courseInfo = api_get_course_info($course_code);
+
+if ($export) {
+    ob_start();
+}
+$csv_content = [];
+$from_myspace = false;
+
+if (isset($_GET['from']) && $_GET['from'] == 'myspace') {
+    $from_myspace = true;
+    $this_section = SECTION_TRACKING;
+} else {
+    $this_section = SECTION_COURSES;
+}
+
+$nameTools = get_lang('StudentDetails');
+$em = Database::getManager();
+
+if (isset($_GET['details'])) {
+    if ($origin === 'user_course') {
+        if (empty($cidReq)) {
+            $interbreadcrumb[] = [
+                "url" => api_get_path(WEB_COURSE_PATH).$courseInfo['directory'],
+                'name' => $courseInfo['title'],
+            ];
+        }
+        $interbreadcrumb[] = [
+            "url" => "../user/user.php?cidReq=".$course_code,
+            "name" => get_lang('Users'),
+        ];
+    } else {
+        if ($origin === 'tracking_course') {
+            $interbreadcrumb[] = [
+                "url" => "../tracking/courseLog.php?cidReq=".$course_code.'&id_session='.api_get_session_id(),
+                "name" => get_lang('Tracking'),
+            ];
+        } else {
+            if ($origin === 'resume_session') {
+                $interbreadcrumb[] = [
+                    'url' => "../session/session_list.php",
+                    "name" => get_lang('SessionList'),
+                ];
+                $interbreadcrumb[] = [
+                    'url' => "../session/resume_session.php?id_session=".$sessionId,
+                    "name" => get_lang('SessionOverview'),
+                ];
+            } else {
+                $interbreadcrumb[] = [
+                    "url" => api_is_student_boss() ? "#" : "index.php",
+                    "name" => get_lang('MySpace'),
+                ];
+                if (!empty($coachId)) {
+                    $interbreadcrumb[] = [
+                        "url" => "student.php?id_coach=$coachId",
+                        "name" => get_lang('CoachStudents'),
+                    ];
+                    $interbreadcrumb[] = [
+                        "url" => "myStudents.php?student=$studentId&id_coach=$coachId",
+                        "name" => get_lang("StudentDetails"),
+                    ];
+                } else {
+                    $interbreadcrumb[] = [
+                        "url" => "student.php",
+                        "name" => get_lang("MyStudents"),
+                    ];
+                    $interbreadcrumb[] = [
+                        "url" => "myStudents.php?student=".$studentId,
+                        "name" => get_lang("StudentDetails"),
+                    ];
+                }
+            }
+        }
+    }
+    $nameTools = get_lang("DetailsStudentInCourse");
+} else {
+    if ($origin == 'resume_session') {
+        $interbreadcrumb[] = [
+            'url' => "../session/session_list.php",
+            "name" => get_lang('SessionList'),
+        ];
+        if (!empty($sessionId)) {
+            $interbreadcrumb[] = [
+                'url' => "../session/resume_session.php?id_session=$sessionId",
+                "name" => get_lang('SessionOverview'),
+            ];
+        }
+    } else {
+        $interbreadcrumb[] = [
+            "url" => api_is_student_boss() ? "#" : "index.php",
+            "name" => get_lang('MySpace'),
+        ];
+        if (!empty($coachId)) {
+            if ($sessionId) {
+                $interbreadcrumb[] = [
+                    "url" => "student.php?id_coach=$coachId&id_session=$sessionId",
+                    "name" => get_lang("CoachStudents"),
+                ];
+            } else {
+                $interbreadcrumb[] = [
+                    "url" => "student.php?id_coach=$coachId",
+                    "name" => get_lang("CoachStudents"),
+                ];
+            }
+        } else {
+            $interbreadcrumb[] = [
+                "url" => "student.php",
+                "name" => get_lang("MyStudents"),
+            ];
+        }
+    }
+}
+
+// Database Table Definitions
+//$tbl_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
+//$tbl_stats_exercices = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
+$tbl_user = Database:: get_main_table(TABLE_MAIN_USER);
+$tbl_session_user = Database:: get_main_table(TABLE_MAIN_SESSION_USER);
+$tbl_session = Database:: get_main_table(TABLE_MAIN_SESSION);
+$tbl_session_course = Database:: get_main_table(TABLE_MAIN_SESSION_COURSE);
+$tbl_session_course_user = Database:: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
+$tbl_course = Database:: get_main_table(TABLE_MAIN_COURSE);
+$tbl_course_user = Database:: get_main_table(TABLE_MAIN_COURSE_USER);
+$tbl_stats_access = Database:: get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
+$tbl_stats_exercices = Database:: get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
+$tbl_stats_exercices_attempts = Database:: get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
+$tbl_personal_agenda = Database:: get_main_table(TABLE_PERSONAL_AGENDA);
+$tbl_course_lp_item = Database:: get_course_table(TABLE_LP_ITEM);
+
+$tbl_course_lp_view = 'lp_view';
+$tbl_course_lp_view_item = 'lp_item_view';
+$tbl_course_lp_item = 'lp_item';
+$tbl_course_lp = 'lp';
+$tbl_course_quiz = 'quiz';
+$course_quiz_question = 'quiz_question';
+$course_quiz_rel_question = 'quiz_rel_question';
+$course_quiz_answer = 'quiz_answer';
+$course_student_publication = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
+$TABLECALHORAIRE = Database:: get_course_table(TABLE_CAL_HORAIRE);
+
+if (isset($_GET['user_id']) && $_GET['user_id'] != "") {
+    $user_id = intval($_GET['user_id']);
+} else {
+    $user_id = api_get_user_id();
+}
+
+// Action behaviour
+$action = isset($_GET['action']) ? $_GET['action'] : '';
+
+switch ($action) {
+    case 'send_legal':
+        $subject = get_lang('SendLegalSubject');
+        $content = sprintf(
+            get_lang('SendLegalDescriptionToUrlX'),
+            api_get_path(WEB_PATH)
+        );
+        MessageManager::send_message_simple($studentId, $subject, $content);
+        Display::addFlash(Display::return_message(get_lang('Sent')));
+        break;
+    case 'delete_legal':
+        $extraFieldValue = new ExtraFieldValue('user');
+        $value = $extraFieldValue->get_values_by_handler_and_field_variable($studentId, 'legal_accept');
+        $result = $extraFieldValue->delete($value['id']);
+        if ($result) {
+            Display::addFlash(Display::return_message(get_lang('Deleted')));
+        }
+        break;
+    case 'reset_lp':
+        $lp_id = isset($_GET['lp_id']) ? (int) $_GET['lp_id'] : '';
+
+        if (api_is_allowed_to_edit() &&
+            !empty($lp_id) &&
+            !empty($studentId)
+        ) {
+            Event::delete_student_lp_events(
+                $studentId,
+                $lp_id,
+                $courseInfo,
+                $sessionId
+            );
+
+            // @todo delete the stats.track_e_exercises records.
+            // First implement this http://support.chamilo.org/issues/1334
+            $message = Display::return_message(
+                get_lang('LPWasReset'),
+                'success'
+            );
+        }
+        break;
+    default:
+        break;
+}
+
+// user info
+$user_info = api_get_user_info($studentId);
+$courses_in_session = [];
+
+//See #4676
+$drh_can_access_all_courses = false;
+
+if (api_is_drh() || api_is_platform_admin() || api_is_student_boss()) {
+    $drh_can_access_all_courses = true;
+}
+
+$courses = CourseManager::get_course_list_of_user_as_course_admin(api_get_user_id());
+$courses_in_session_by_coach = [];
+$sessions_coached_by_user = Tracking::get_sessions_coached_by_user(api_get_user_id());
+
+// RRHH or session admin
+if (api_is_session_admin() || api_is_drh()) {
+    $courses = CourseManager::get_courses_followed_by_drh(api_get_user_id());
+    $session_by_session_admin = SessionManager::get_sessions_followed_by_drh(api_get_user_id());
+
+    if (!empty($session_by_session_admin)) {
+        foreach ($session_by_session_admin as $session_coached_by_user) {
+            $courses_followed_by_coach = Tracking:: get_courses_list_from_session($session_coached_by_user['id']);
+            $courses_in_session_by_coach[$session_coached_by_user['id']] = $courses_followed_by_coach;
+        }
+    }
+}
+
+// Teacher or admin
+if (!empty($sessions_coached_by_user)) {
+    foreach ($sessions_coached_by_user as $session_coached_by_user) {
+        $sid = (int) $session_coached_by_user['id'];
+        $courses_followed_by_coach = Tracking::get_courses_followed_by_coach(api_get_user_id(), $sid);
+        $courses_in_session_by_coach[$sid] = $courses_followed_by_coach;
+    }
+}
+
+$sql = "SELECT c_id
+        FROM $tbl_course_user
+        WHERE
+            relation_type <> ".COURSE_RELATION_TYPE_RRHH." AND
+            user_id = ".intval($user_info['user_id']);
+$rs = Database::query($sql);
+
+while ($row = Database:: fetch_array($rs)) {
+    if ($drh_can_access_all_courses) {
+        $courses_in_session[0][] = $row['c_id'];
+    } else {
+        if (isset($courses[$row['c_id']])) {
+            $courses_in_session[0][] = $row['c_id'];
+        }
+    }
+}
+
+// Get the list of sessions where the user is subscribed as student
+$sql = 'SELECT session_id, c_id
+        FROM '.Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER).'
+        WHERE user_id='.intval($user_info['user_id']);
+$rs = Database::query($sql);
+$tmp_sessions = [];
+while ($row = Database:: fetch_array($rs, 'ASSOC')) {
+    $tmp_sessions[] = $row['session_id'];
+    if ($drh_can_access_all_courses) {
+        if (in_array($row['session_id'], $tmp_sessions)) {
+            $courses_in_session[$row['session_id']][] = $row['c_id'];
+        }
+    } else {
+        if (isset($courses_in_session_by_coach[$row['session_id']])) {
+            if (in_array($row['session_id'], $tmp_sessions)) {
+                $courses_in_session[$row['session_id']][] = $row['c_id'];
+            }
+        }
+    }
+}
+
+$isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
+    api_get_user_id(),
+    api_get_course_info()
+);
+
+if (api_is_drh() && !api_is_platform_admin()) {
+    if (!empty($studentId)) {
+        if (api_drh_can_access_all_session_content()) {
+            //@todo securize drh with student id
+            /*$users = SessionManager::getAllUsersFromCoursesFromAllSessionFromStatus('drh_all', api_get_user_id());
+            $userList = [];
+            foreach ($users as $user) {
+                $userList[] = $user['user_id'];
+            }
+            if (!in_array($student_id, $userList)) {
+                api_not_allowed(true);
+            }*/
+        } else {
+            if (!($isDrhOfCourse)) {
+                if (api_is_drh() &&
+                    !UserManager::is_user_followed_by_drh($studentId, api_get_user_id())
+                ) {
+                    api_not_allowed(true);
+                }
+            }
+        }
+    }
+}
+
+Display::display_header($nameTools);
+
+if (isset($message)) {
+    echo $message;
+}
+
+$token = Security::get_token();
+if (!empty($studentId)) {
+    // Actions bar
+    echo '<div class="actions">';
+    echo '<a href="javascript: window.history.go(-1);">'.
+        Display::return_icon('back.png', get_lang('Back'), '', ICON_SIZE_MEDIUM).'</a>';
+
+    echo '<a href="javascript: void(0);" onclick="javascript: window.print();">'.
+        Display::return_icon('printer.png', get_lang('Print'), '', ICON_SIZE_MEDIUM).'</a>';
+
+    echo '<a href="'.api_get_self().'?'.Security:: remove_XSS($_SERVER['QUERY_STRING']).'&export=csv">'.
+        Display::return_icon('export_csv.png', get_lang('ExportAsCSV'), '', ICON_SIZE_MEDIUM).'</a> ';
+
+    echo '<a href="'.api_get_self().'?'.Security:: remove_XSS($_SERVER['QUERY_STRING']).'&export=xls">'.
+        Display::return_icon('export_excel.png', get_lang('ExportAsXLS'), '', ICON_SIZE_MEDIUM).'</a> ';
+
+    if (!empty($user_info['email'])) {
+        $send_mail = '<a href="mailto:'.$user_info['email'].'">'.
+            Display:: return_icon('mail_send.png', get_lang('SendMail'), '', ICON_SIZE_MEDIUM).'</a>';
+    } else {
+        $send_mail = Display:: return_icon('mail_send_na.png', get_lang('SendMail'), '', ICON_SIZE_MEDIUM);
+    }
+    echo $send_mail;
+    if (!empty($studentId) && !empty($course_code)) {
+        // Only show link to connection details if course and student were defined in the URL
+        echo '<a href="access_details.php?student='.$studentId.'&course='.$course_code.'&origin='.$origin.'&cidReq='.$course_code.'&id_session='.$sessionId.'">'.
+            Display:: return_icon('statistics.png', get_lang('AccessDetails'), '', ICON_SIZE_MEDIUM).'</a>';
+    }
+    if (api_can_login_as($studentId)) {
+        echo '<a href="'.api_get_path(
+                WEB_CODE_PATH
+            ).'admin/user_list.php?action=login_as&user_id='.$studentId.'&sec_token='.$token.'">'.
+            Display::return_icon('login_as.png', get_lang('LoginAs'), null, ICON_SIZE_MEDIUM).'</a>&nbsp;&nbsp;';
+    }
+
+    echo Display::url(
+        Display::return_icon('skill-badges.png', get_lang('AssignSkill'), null, ICON_SIZE_MEDIUM),
+        api_get_path(WEB_CODE_PATH).'badge/assign.php?'.http_build_query(['user' => $studentId])
+    );
+    echo '</div>';
+
+    // is the user online ?
+    if (user_is_online($studentId)) {
+        $online = get_lang('Yes');
+    } else {
+        $online = get_lang('No');
+    }
+
+    // get average of score and average of progress by student
+    $avg_student_progress = $avg_student_score = 0;
+    if (CourseManager:: is_user_subscribed_in_course($user_info['user_id'], $course_code, true)) {
+        $avg_student_progress = Tracking::get_avg_student_progress(
+            $user_info['user_id'],
+            $course_code,
+            [],
+            $sessionId
+        );
+
+        // the score inside the Reporting table
+        $avg_student_score = Tracking::get_avg_student_score(
+            $user_info['user_id'],
+            $course_code,
+            [],
+            $sessionId
+        );
+    }
+
+    $avg_student_progress = round($avg_student_progress, 2);
+    $time_spent_on_the_course = 0;
+    if (!empty($courseInfo)) {
+        $time_spent_on_the_course = api_time_to_hms(
+            Tracking:: get_time_spent_on_the_course(
+                $user_info['user_id'],
+                $courseInfo['real_id'],
+                $sessionId
+            )
+        );
+    }
+
+    // get information about connections on the platform by student
+    $first_connection_date = Tracking:: get_first_connection_date($user_info['user_id']);
+    if ($first_connection_date == '') {
+        $first_connection_date = get_lang('NoConnexion');
+    }
+
+    $last_connection_date = Tracking:: get_last_connection_date($user_info['user_id'], true);
+    if ($last_connection_date == '') {
+        $last_connection_date = get_lang('NoConnexion');
+    }
+
+    // cvs information
+    $csv_content[] = [
+        get_lang('Information'),
+    ];
+    $csv_content[] = [
+        get_lang('Name'),
+        get_lang('Email'),
+        get_lang('Tel'),
+    ];
+    $csv_content[] = [
+        $user_info['complete_name'],
+        $user_info['email'],
+        $user_info['phone'],
+    ];
+
+    $csv_content[] = [];
+
+    // csv tracking
+    $csv_content[] = [
+        get_lang('Tracking'),
+    ];
+    $csv_content[] = [
+        get_lang('FirstLoginInPlatform'),
+        get_lang('LatestLoginInPlatform'),
+        get_lang('TimeSpentInTheCourse'),
+        get_lang('Progress'),
+        get_lang('Score'),
+    ];
+    $csv_content[] = [
+        strip_tags($first_connection_date),
+        strip_tags($last_connection_date),
+        $time_spent_on_the_course,
+        $avg_student_progress.'%',
+        $avg_student_score,
+    ];
+
+    $coachs_name = '';
+    $session_name = '';
+    $table_title = Display::return_icon(
+            'user.png',
+            get_lang('User'),
+            [],
+            ICON_SIZE_SMALL
+        ).$user_info['complete_name'];
+
+    echo Display::page_subheader($table_title);
+
+    $userPicture = UserManager::getUserPicture($user_info['user_id']);
+    $userGroupManager = new UserGroup();
+    $userGroups = $userGroupManager->getNameListByUser($user_info['user_id'], UserGroup::NORMAL_CLASS); ?>
+    <img src="<?php echo $userPicture; ?>">
+    <div class="row">
+        <div class="col-sm-6">
+            <table class="table table-striped table-hover">
+                <thead>
+                <tr>
+                    <th><?php echo get_lang('Information'); ?></th>
+                </tr>
+                </thead>
+                <tbody>
+                <tr>
+                    <td><?php echo get_lang('Name').' : '.$user_info['complete_name']; ?></td>
+                </tr>
+                <tr>
+                    <td><?php echo get_lang('Email').' : ';
+    if (!empty($user_info['email'])) {
+        echo '<a href="mailto:'.$user_info['email'].'">'.$user_info['email'].'</a>';
+    } else {
+        echo get_lang('NoEmail');
+    } ?>
+                    </td>
+                </tr>
+                <tr>
+                    <td> <?php echo get_lang('Tel').' : ';
+    if (!empty($user_info['phone'])) {
+        echo $user_info['phone'];
+    } else {
+        echo get_lang('NoTel');
+    } ?>
+                    </td>
+                </tr>
+                <tr>
+                    <td><?php echo get_lang('OfficialCode').' : ';
+    if (!empty($user_info['official_code'])) {
+        echo $user_info['official_code'];
+    } else {
+        echo get_lang('NoOfficialCode');
+    } ?>
+                    </td>
+                </tr>
+                <tr>
+                    <td><?php echo get_lang('OnLine').' : '.$online; ?> </td>
+                </tr>
+                <?php
+
+                // Display timezone if the user selected one and if the admin allows the use of user's timezone
+                $timezone = null;
+    $timezone_user = UserManager::get_extra_user_data_by_field($user_info['user_id'], 'timezone');
+    $use_users_timezone = api_get_setting('use_users_timezone', 'timezones');
+    if ($timezone_user['timezone'] != null && $use_users_timezone == 'true') {
+        $timezone = $timezone_user['timezone'];
+    }
+    if ($timezone !== null) {
+        ?>
+                    <tr>
+                        <td> <?php echo get_lang('Timezone').' : '.$timezone; ?> </td>
+                    </tr>
+                    <?php
+    } ?>
+                </tbody>
+            </table>
+        </div>
+        <div class="col-sm-6">
+            <table class="table table-striped table-hover">
+                <thead>
+                <tr>
+                    <th colspan="2" class="text-center"><?php echo get_lang('Tracking'); ?></th>
+                </tr>
+                </thead>
+                <tbody>
+                <tr>
+                    <td align="right"><?php echo get_lang('FirstLoginInPlatform'); ?></td>
+                    <td align="left"><?php echo $first_connection_date; ?></td>
+                </tr>
+                <tr>
+                    <td align="right"><?php echo get_lang('LatestLoginInPlatform'); ?></td>
+                    <td align="left"><?php echo $last_connection_date; ?></td>
+                </tr>
+                <?php if (isset($_GET['details']) && $_GET['details'] == 'true') {
+        ?>
+                    <tr>
+                        <td align="right"><?php echo get_lang('TimeSpentInTheCourse'); ?></td>
+                        <td align="left"><?php echo $time_spent_on_the_course; ?></td>
+                    </tr>
+                    <tr>
+                        <td align="right">
+                            <?php
+                            echo get_lang('Progress').' ';
+        Display:: display_icon(
+                                'info3.gif',
+                                get_lang('ScormAndLPProgressTotalAverage'),
+                                ['align' => 'absmiddle', 'hspace' => '3px']
+                            ); ?>
+                        </td>
+                        <td align="left"><?php echo $avg_student_progress.'%'; ?></td>
+                    </tr>
+                    <tr>
+                        <td align="right">
+                            <?php
+                            echo get_lang('Score').' ';
+        Display:: display_icon(
+                                'info3.gif',
+                                get_lang('ScormAndLPTestTotalAverage'),
+                                ['align' => 'absmiddle', 'hspace' => '3px']
+                            ); ?>
+                        </td>
+                        <td align="left"><?php
+                            if (is_numeric($avg_student_score)) {
+                                echo $avg_student_score.'%';
+                            } else {
+                                echo $avg_student_score;
+                            } ?>
+                        </td>
+                    </tr>
+                    <?php
+    }
+
+    if (api_get_setting('allow_terms_conditions') === 'true') {
+        $isBoss = UserManager::userIsBossOfStudent(api_get_user_id(), $studentId);
+        if ($isBoss || api_is_platform_admin()) {
+            $extraFieldValue = new ExtraFieldValue('user');
+            $value = $extraFieldValue->get_values_by_handler_and_field_variable(
+                            $studentId,
+                            'legal_accept'
+                        );
+            $icon = Display::return_icon('accept_na.png');
+            if (isset($value['value'])) {
+                list($legalId, $legalLanguageId, $legalTime) = explode(':', $value['value']);
+                $icon = Display::return_icon('accept.png').' '.api_get_local_time($legalTime);
+                $icon .= ' '.Display::url(
+                                    get_lang('DeleteLegal'),
+                                    api_get_self().'?action=delete_legal&student='.$studentId.'&course='.$course_code,
+                                    ['class' => 'btn btn-danger btn-xs']
+                                );
+            } else {
+                $icon .= ' '.Display::url(
+                                    get_lang('SendLegal'),
+                                    api_get_self().'?action=send_legal&student='.$studentId.'&course='.$course_code,
+                                    ['class' => 'btn btn-primary btn-xs']
+                                );
+            }
+            echo '<tr>
+                        <td align="right">';
+            echo get_lang('LegalAccepted').' </td>  <td align="left">'.$icon;
+            echo '</td></tr>';
+        }
+    } ?>
+                </tbody>
+            </table>
+            <?php if (!empty($userGroups)) {
+        ?>
+                <table class="table table-striped table-hover">
+                    <thead>
+                    <tr>
+                        <th><?php echo get_lang('Classes'); ?></th>
+                    </tr>
+                    </thead>
+                    <tbody>
+                    <?php foreach ($userGroups as $class) {
+            ?>
+                        <tr>
+                            <td><?php echo $class; ?></td>
+                        </tr>
+                    <?php
+        } ?>
+                    </tbody>
+                </table>
+            <?php
+    } ?>
+        </div>
+    </div>
+    <?php
+
+    if (empty($_GET['details'])) {
+        $csv_content[] = [];
+        $csv_content[] = [
+            get_lang('Session'),
+            get_lang('Course'),
+            get_lang('Time'),
+            get_lang('Progress'),
+            get_lang('Score'),
+            get_lang('AttendancesFaults'),
+            get_lang('Evaluations'),
+        ];
+
+        $attendance = new Attendance();
+        foreach ($courses_in_session as $sId => $courses) {
+            $session_name = '';
+            $access_start_date = '';
+            $access_end_date = '';
+            $date_session = '';
+            $title = Display::return_icon('course.png', get_lang('Courses'), [], ICON_SIZE_SMALL).' '.get_lang('Courses');
+
+            $session_info = api_get_session_info($sId);
+            if ($session_info) {
+                $session_name = $session_info['name'];
+                if (!empty($session_info['access_start_date'])) {
+                    $access_start_date = api_format_date($session_info['access_start_date'], DATE_FORMAT_SHORT);
+                }
+
+                if (!empty($session_info['access_end_date'])) {
+                    $access_end_date = api_format_date($session_info['access_end_date'], DATE_FORMAT_SHORT);
+                }
+
+                if (!empty($access_start_date) && !empty($access_end_date)) {
+                    $date_session = get_lang('From').' '.$access_start_date.' '.get_lang('Until').' '.$access_end_date;
+                }
+                $title = Display::return_icon(
+                        'session.png',
+                        get_lang('Session'),
+                        [],
+                        ICON_SIZE_SMALL
+                    ).' '.$session_name.($date_session ? ' ('.$date_session.')' : '');
+            }
+
+            // Courses
+            echo '<h3>'.$title.'</h3>';
+            echo '<div class="table-responsive">';
+            echo '<table class="table table-striped table-hover courses-tracking">';
+            echo '<thead>';
+            echo '<tr>
+                <th>'.get_lang('Course').'</th>
+                <th>'.get_lang('Time').'</th>
+                <th>'.get_lang('Progress').'</th>
+                <th>'.get_lang('Score').'</th>
+                <th>'.get_lang('AttendancesFaults').'</th>
+                <th>'.get_lang('Evaluations').'</th>
+                <th>'.get_lang('Details').'</th>
+            </tr>';
+            echo '</thead>';
+            echo '<tbody>';
+
+            if (!empty($courses)) {
+                foreach ($courses as $courseId) {
+                    $courseInfoItem = api_get_course_info_by_id($courseId);
+                    $courseId = $courseInfoItem['real_id'];
+                    $courseCodeItem = $courseInfoItem['code'];
+
+                    if (CourseManager:: is_user_subscribed_in_course($studentId, $courseCodeItem, true)) {
+                        $time_spent_on_course = api_time_to_hms(
+                            Tracking:: get_time_spent_on_the_course($user_info['user_id'], $courseId, $sId)
+                        );
+
+                        // get average of faults in attendances by student
+                        $results_faults_avg = $attendance->get_faults_average_by_course(
+                            $studentId,
+                            $courseCodeItem,
+                            $sId
+                        );
+
+                        if (!empty($results_faults_avg['total'])) {
+                            if (api_is_drh()) {
+                                $attendances_faults_avg =
+                                    '<a title="'.get_lang('GoAttendance').'" href="'.api_get_path(
+                                        WEB_CODE_PATH
+                                    ).'attendance/index.php?cidReq='.$courseCodeItem.'&id_session='.$sId.'&student_id='.$studentId.'">'.
+                                    $results_faults_avg['faults'].'/'.$results_faults_avg['total'].' ('.$results_faults_avg['porcent'].'%)</a>';
+                            } else {
+                                $attendances_faults_avg =
+                                    $results_faults_avg['faults'].'/'.
+                                    $results_faults_avg['total'].
+                                    ' ('.$results_faults_avg['porcent'].'%)';
+                            }
+                        } else {
+                            $attendances_faults_avg = '0/0 (0%)';
+                        }
+
+                        // Get evaluations by student
+                        $cats = Category::load(null, null, $courseCodeItem, null, null, $sId);
+                        $scoretotal = [];
+                        if (isset($cats) && isset($cats[0])) {
+                            if (!empty($sId)) {
+                                $scoretotal = $cats[0]->calc_score($studentId, null, $courseCodeItem, $sId);
+                            } else {
+                                $scoretotal = $cats[0]->calc_score($studentId, null, $courseCodeItem);
+                            }
+                        }
+
+                        $scoretotal_display = '0/0 (0%)';
+                        if (!empty($scoretotal) && !empty($scoretotal[1])) {
+                            $scoretotal_display =
+                                round($scoretotal[0], 1).'/'.
+                                round($scoretotal[1], 1).
+                                ' ('.round(($scoretotal[0] / $scoretotal[1]) * 100, 2).' %)';
+                        }
+
+                        $progress = Tracking::get_avg_student_progress(
+                            $user_info['user_id'],
+                            $courseCodeItem,
+                            null,
+                            $sId
+                        );
+
+                        $score = Tracking:: get_avg_student_score($user_info['user_id'], $courseCodeItem, [], $sId);
+                        $progress = empty($progress) ? '0%' : $progress.'%';
+                        $score = empty($score) ? '0%' : $score.'%';
+
+                        $csv_content[] = [
+                            $session_name,
+                            $courseInfoItem['title'],
+                            $time_spent_on_course,
+                            $progress,
+                            $score,
+                            $attendances_faults_avg,
+                            $scoretotal_display,
+                        ];
+
+                        echo '<tr>
+                        <td ><a href="'.$courseInfoItem['course_public_url'].'?id_session='.$sId.'">'.
+                            $courseInfoItem['title'].'</a></td>
+                        <td >'.$time_spent_on_course.'</td>
+                        <td >'.$progress.'</td>
+                        <td >'.$score.'</td>
+                        <td >'.$attendances_faults_avg.'</td>
+                        <td >'.$scoretotal_display.'</td>';
+
+                        if (!empty($coachId)) {
+                            echo '<td width="10"><a href="'.api_get_self().
+                                '?student='.$user_info['user_id'].'&details=true&course='.$courseInfoItem['code'].'&id_coach='.$coachId.
+                                '&origin='.$origin.'&id_session='.$sId.'#infosStudent">
+                            '.Display::return_icon('2rightarrow.png', get_lang('Details')).'</a></td>';
+                        } else {
+                            echo '<td width="10"><a href="'.api_get_self(
+                                ).'?student='.$user_info['user_id'].'&details=true&course='.$courseInfoItem['code'].'&origin='.$origin.'&id_session='.$sId.'#infosStudent">
+                            '.Display::return_icon('2rightarrow.png', get_lang('Details')).'</a></td>';
+                        }
+                        echo '</tr>';
+                    }
+                }
+            } else {
+                echo "<tr><td colspan='5'>".get_lang('NoCourse')."</td></tr>";
+            }
+            echo '</tbody>';
+            echo '</table>';
+            echo '</div>';
+        }
+    } else {
+        if ($user_info['status'] != INVITEE) {
+            $csv_content[] = [];
+            $csv_content[] = [str_replace('&nbsp;', '', $table_title)];
+            $t_lp = Database:: get_course_table(TABLE_LP_MAIN);
+
+            // csv export headers
+            $csv_content[] = [];
+            $csv_content[] = [
+                get_lang('Learnpath'),
+                get_lang('Time'),
+                get_lang('AverageScore'),
+                get_lang('LatestAttemptAverageScore'),
+                get_lang('Progress'),
+                get_lang('LastConnexion'),
+            ];
+
+            $query = $em
+                ->createQuery(
+                    '
+                    SELECT lp FROM ChamiloCourseBundle:CLp lp
+                    WHERE lp.sessionId = :session AND lp.cId = :course
+                    ORDER BY lp.displayOrder ASC
+                '
+                );
+
+            if (empty($sessionId)) {
+                $query->setParameters(
+                    [
+                        'session' => 0,
+                        'course' => $courseInfo['real_id'],
+                    ]
+                );
+            } else {
+                $query->setParameters(
+                    [
+                        'session' => $sessionId,
+                        'course' => $courseInfo['real_id'],
+                    ]
+                );
+            }
+
+            $rs_lp = $query->getResult();
+
+            if (count($rs_lp) > 0) {
+                ?>
+                <!-- LPs-->
+                <div class="table-responsive">
+                    <table class="table table-striped table-hover">
+                        <thead>
+                        <tr>
+                            <th><?php echo get_lang('LearningPath'); ?></th>
+                            <th>
+                                <?php
+                                echo get_lang('Time').' ';
+                Display:: display_icon(
+                                    'info3.gif',
+                                    get_lang('TotalTimeByCourse'),
+                                    ['align' => 'absmiddle', 'hspace' => '3px']
+                                ); ?>
+                            </th>
+                            <th>
+                                <?php
+                                echo get_lang('AverageScore').' ';
+                Display:: display_icon(
+                                    'info3.gif',
+                                    get_lang('AverageIsCalculatedBasedInAllAttempts'),
+                                    ['align' => 'absmiddle', 'hspace' => '3px']
+                                ); ?>
+                            </th>
+                            <th><?php
+                                echo get_lang('LatestAttemptAverageScore').' ';
+                Display::display_icon(
+                                    'info3.gif',
+                                    get_lang('AverageIsCalculatedBasedInTheLatestAttempts'),
+                                    ['align' => 'absmiddle', 'hspace' => '3px']
+                                ); ?>
+                            </th>
+                            <th><?php
+                                echo get_lang('Progress').' ';
+                Display:: display_icon(
+                                    'info3.gif',
+                                    get_lang('LPProgressScore'),
+                                    ['align' => 'absmiddle', 'hspace' => '3px']
+                                ); ?>
+                            </th>
+                            <th><?php
+                                echo get_lang('LastConnexion').' ';
+                Display:: display_icon(
+                                    'info3.gif',
+                                    get_lang('LastTimeTheCourseWasUsed'),
+                                    ['align' => 'absmiddle', 'hspace' => '3px']
+                                ); ?>
+                            </th>
+                            <?php
+                            echo '<th>'.get_lang('Details').'</th>';
+                if (api_is_allowed_to_edit()) {
+                    echo '<th>'.get_lang('ResetLP').'</th>';
+                } ?>
+                        </tr>
+                        </thead>
+                        <tbody>
+                        <?php
+
+                        $i = 0;
+                foreach ($rs_lp as $learnpath) {
+                    $lp_id = $learnpath->getId();
+                    $lp_name = $learnpath->getName();
+                    $any_result = false;
+
+                    // Get progress in lp
+                    $progress = Tracking::get_avg_student_progress(
+                                $studentId,
+                                $course_code,
+                                [$lp_id],
+                                $sessionId
+                            );
+
+                    if ($progress === null) {
+                        $progress = '0%';
+                    } else {
+                        $any_result = true;
+                    }
+
+                    // Get time in lp
+                    $total_time = Tracking::get_time_spent_in_lp(
+                                $studentId,
+                                $course_code,
+                                [$lp_id],
+                                $sessionId
+                            );
+
+                    if (!empty($total_time)) {
+                        $any_result = true;
+                    }
+
+                    // Get last connection time in lp
+                    $start_time = Tracking::get_last_connection_time_in_lp(
+                                $studentId,
+                                $course_code,
+                                $lp_id,
+                                $sessionId
+                            );
+
+                    if (!empty($start_time)) {
+                        $start_time = api_convert_and_format_date($start_time, DATE_TIME_FORMAT_LONG);
+                    } else {
+                        $start_time = '-';
+                    }
+
+                    if (!empty($total_time)) {
+                        $any_result = true;
+                    }
+
+                    // Quiz in lp
+                    $score = Tracking::get_avg_student_score(
+                                $studentId,
+                                $course_code,
+                                [$lp_id],
+                                $sessionId
+                            );
+
+                    // Latest exercise results in a LP
+                    $score_latest = Tracking:: get_avg_student_score(
+                                $studentId,
+                                $course_code,
+                                [$lp_id],
+                                $sessionId,
+                                false,
+                                true
+                            );
+
+                    if ($i % 2 == 0) {
+                        $css_class = "row_even";
+                    } else {
+                        $css_class = "row_odd";
+                    }
+                    $i++;
+
+                    // csv export content
+                    $csv_content[] = [
+                                api_html_entity_decode(stripslashes($lp_name), ENT_QUOTES, $charset),
+                                api_time_to_hms($total_time),
+                                $score.'%',
+                                $score_latest.'%',
+                                $progress.'%',
+                                $start_time,
+                            ];
+
+                    echo '<tr class="'.$css_class.'">';
+                    echo Display::tag('td', stripslashes($lp_name));
+                    echo Display::tag('td', api_time_to_hms($total_time));
+
+                    if (!is_null($score)) {
+                        if (is_numeric($score)) {
+                            $score = $score.'%';
+                        }
+                    }
+
+                    echo Display::tag('td', $score);
+                    if (!is_null($score_latest)) {
+                        if (is_numeric($score_latest)) {
+                            $score_latest = $score_latest.'%';
+                        }
+                    }
+                    echo Display::tag('td', $score_latest);
+
+                    if (is_numeric($progress)) {
+                        $progress = $progress.'%';
+                    } else {
+                        $progress = '-';
+                    }
+
+                    echo Display::tag('td', $progress);
+                    // Do not change with api_convert_and_format_date, because
+                    // this value came from the lp_item_view table
+                    // which implies several other changes not a priority right now
+                    echo Display::tag('td', $start_time);
+
+                    if ($any_result === true) {
+                        $from = '';
+                        if ($from_myspace) {
+                            $from = '&from=myspace';
+                        }
+                        $link = Display::url(
+                                    Display::return_icon('2rightarrow.png', get_lang('Details')),
+                                    'lp_tracking.php?cidReq='.$course_code.'&course='.$course_code.$from.'&origin='.$origin.'&lp_id='.$learnpath->getId(
+                                    ).'&student_id='.$user_info['user_id'].'&id_session='.$sessionId
+                                );
+                        echo Display::tag('td', $link);
+                    }
+
+                    if (api_is_allowed_to_edit()) {
+                        echo '<td>';
+                        if ($any_result === true) {
+                            echo '<a href="myStudents.php?action=reset_lp&sec_token='.$token.
+                                '&cidReq='.$course_code.
+                                '&course='.$course_code.
+                                '&details='.Security::remove_XSS($_GET['details']).
+                                '&origin='.$origin.
+                                '&lp_id='.$learnpath->getId().
+                                '&student='.$user_info['user_id'].
+                                '&details=true&id_session='.$sessionId.'">';
+                            echo Display::return_icon(
+                                            'clean.png',
+                                            get_lang('Clean'),
+                                            '',
+                                            ICON_SIZE_SMALL
+                                        ).'</a>';
+                            echo '</a>';
+                        }
+                        echo '</td>';
+                        echo '</tr>';
+                    }
+                    $data_learnpath[$i][] = $lp_name;
+                    $data_learnpath[$i][] = $progress.'%';
+                } ?>
+                        </tbody>
+                    </table>
+                </div>
+                <?php
+            }
+        } ?>
+        <!-- line about exercises -->
+        <?php if ($user_info['status'] != INVITEE) {
+            ?>
+            <div class="table-responsive">
+                <table class="table table-striped table-hover">
+                    <thead>
+                    <tr>
+                        <th><?php echo get_lang('Exercises'); ?></th>
+                        <th><?php echo get_lang('LearningPath'); ?></th>
+                        <th><?php echo get_lang('AvgCourseScore').' '.Display:: return_icon(
+                                    'info3.gif',
+                                    get_lang('AverageScore'),
+                                    ['align' => 'absmiddle', 'hspace' => '3px']
+                                ); ?></th>
+                        <th><?php echo get_lang('Attempts'); ?></th>
+                        <th><?php echo get_lang('LatestAttempt'); ?></th>
+                        <th><?php echo get_lang('AllAttempts'); ?></th>
+                    </tr>
+                    </thead>
+                    <tbody>
+                    <?php
+                    $csv_content[] = [];
+            $csv_content[] = [
+                        get_lang('Exercises'),
+                        get_lang('LearningPath'),
+                        get_lang('AvgCourseScore'),
+                        get_lang('Attempts'),
+                    ];
+
+            $t_quiz = Database:: get_course_table(TABLE_QUIZ_TEST);
+            $sessionCondition = api_get_session_condition(
+                $sessionId,
+                true,
+                true,
+                'quiz.session_id'
+            );
+
+            $sql = "SELECT quiz.title, id FROM $t_quiz AS quiz
+                            WHERE
+                                quiz.c_id = ".$courseInfo['real_id']." AND
+                                active IN (0, 1)
+                                $sessionCondition                    
+                            ORDER BY quiz.title ASC ";
+
+            $result_exercices = Database::query($sql);
+            $i = 0;
+            if (Database:: num_rows($result_exercices) > 0) {
+                while ($exercices = Database:: fetch_array($result_exercices)) {
+                    $exercise_id = intval($exercices['id']);
+                    $count_attempts = Tracking::count_student_exercise_attempts(
+                                $studentId,
+                                $courseInfo['real_id'],
+                                $exercise_id,
+                                0,
+                                0,
+                                $sessionId,
+                                2
+                            );
+                    $score_percentage = Tracking::get_avg_student_exercise_score(
+                                $studentId,
+                                $course_code,
+                                $exercise_id,
+                                $sessionId,
+                                1,
+                                0
+                            );
+
+                    if (!isset($score_percentage) && $count_attempts > 0) {
+                        $scores_lp = Tracking::get_avg_student_exercise_score(
+                                    $studentId,
+                                    $course_code,
+                                    $exercise_id,
+                                    $sessionId,
+                                    2,
+                                    1
+                                );
+                        $score_percentage = $scores_lp[0];
+                        $lp_name = $scores_lp[1];
+                    } else {
+                        $lp_name = '-';
+                    }
+                    $lp_name = !empty($lp_name) ? $lp_name : get_lang('NoLearnpath');
+
+                    if ($i % 2) {
+                        $css_class = 'row_odd';
+                    } else {
+                        $css_class = 'row_even';
+                    }
+
+                    echo '<tr class="'.$css_class.'"><td>'.$exercices['title'].'</td>';
+                    echo '<td>';
+
+                    if (!empty($lp_name)) {
+                        echo $lp_name;
+                    } else {
+                        echo '-';
+                    }
+
+                    echo '</td>';
+                    echo '<td>';
+
+                    if ($count_attempts > 0) {
+                        echo $score_percentage.'%';
+                    } else {
+                        echo '-';
+                        $score_percentage = 0;
+                    }
+
+                    echo '</td>';
+                    echo '<td>'.$count_attempts.'</td>';
+                    echo '<td>';
+
+                    $sql = "SELECT exe_id FROM $tbl_stats_exercices
+                            WHERE
+                                exe_exo_id = $exercise_id AND
+                                exe_user_id = $studentId AND
+                                c_id = ".$courseInfo['real_id']." AND
+                                session_id = $sessionId AND
+                                status = ''
+                            ORDER BY exe_date DESC
+                            LIMIT 1";
+                    $result_last_attempt = Database::query($sql);
+                    if (Database:: num_rows($result_last_attempt) > 0) {
+                        $id_last_attempt = Database:: result($result_last_attempt, 0, 0);
+                        if ($count_attempts > 0) {
+                            echo '<a href="../exercise/exercise_show.php?id='.$id_last_attempt.
+                                '&cidReq='.$course_code.
+                                '&session_id='.$sessionId.
+                                '&student='.$studentId.
+                                '&origin='.(empty($origin) ? 'tracking' : $origin).
+                                '">';
+                            echo Display::return_icon('quiz.gif');
+                            echo '</a>';
+                        }
+                    }
+                    echo '</td>';
+                    echo '<td>';
+                    $all_attempt_url = "../exercise/exercise_report.php?exerciseId=$exercise_id&cidReq=$course_code&filter_by_user=$studentId&id_session=$sessionId";
+                    echo Display::url(
+                                Display::return_icon(
+                                    'test_results.png',
+                                    get_lang('AllAttempts'),
+                                    [],
+                                    ICON_SIZE_SMALL
+                                ),
+                                $all_attempt_url
+                            );
+
+                    echo '</td></tr>';
+                    $data_exercices[$i][] = $exercices['title'];
+                    $data_exercices[$i][] = $score_percentage.'%';
+                    $data_exercices[$i][] = $count_attempts;
+                    $csv_content[] = [
+                                $exercices['title'],
+                                $lp_name,
+                                $score_percentage,
+                                $count_attempts,
+                            ];
+                    $i++;
+                }
+            } else {
+                echo '<tr><td colspan="6">'.get_lang('NoExercise').'</td></tr>';
+            } ?>
+                    </tbody>
+                </table>
+            </div>
+            <?php
+        }
+
+        // @when using sessions we do not show the survey list
+        if (empty($sessionId)) {
+            $survey_list = SurveyManager::get_surveys($course_code, $sessionId);
+            $survey_data = [];
+            foreach ($survey_list as $survey) {
+                $user_list = SurveyManager::get_people_who_filled_survey(
+                    $survey['survey_id'],
+                    false,
+                    $courseInfo['real_id']
+                );
+                $survey_done = Display::return_icon("accept_na.png", get_lang('NoAnswer'), [], ICON_SIZE_SMALL);
+                if (in_array($studentId, $user_list)) {
+                    $survey_done = Display::return_icon("accept.png", get_lang('Answered'), [], ICON_SIZE_SMALL);
+                }
+                $data = ['title' => $survey['title'], 'done' => $survey_done];
+                $survey_data[] = $data;
+            }
+
+            if (!empty($survey_list)) {
+                $table = new HTML_Table(['class' => 'data_table']);
+                $header_names = [get_lang('Survey'), get_lang('Answered')];
+                $row = 0;
+                $column = 0;
+                foreach ($header_names as $item) {
+                    $table->setHeaderContents($row, $column, $item);
+                    $column++;
+                }
+                $row = 1;
+                if (!empty($survey_data)) {
+                    foreach ($survey_data as $data) {
+                        $column = 0;
+                        $table->setCellContents($row, $column, $data);
+                        $class = 'class="row_odd"';
+                        if ($row % 2) {
+                            $class = 'class="row_even"';
+                        }
+                        $table->setRowAttributes($row, $class, true);
+                        $column++;
+                        $row++;
+                    }
+                }
+                echo $table->toHtml();
+            }
+        }
+
+        // line about other tools?>
+        <div class="table-responsive">
+            <table class="table table-striped table-hover">
+                <thead>
+                <tr>
+                    <th colspan="2"><?php echo get_lang('OtherTools'); ?></th>
+                </tr>
+                </thead>
+                <tbody>
+                <?php
+                $csv_content[] = [];
+        $nb_assignments = Tracking::count_student_assignments($studentId, $course_code, $sessionId);
+        $messages = Tracking::count_student_messages($studentId, $course_code, $sessionId);
+        $links = Tracking::count_student_visited_links($studentId, $courseInfo['real_id'], $sessionId);
+        $chat_last_connection = Tracking::chat_last_connection($studentId, $courseInfo['real_id'], $sessionId);
+        $documents = Tracking::count_student_downloaded_documents(
+                    $studentId,
+                    $courseInfo['real_id'],
+                    $sessionId
+                );
+        $uploaded_documents = Tracking::count_student_uploaded_documents($studentId, $course_code, $sessionId);
+        $csv_content[] = [
+                    get_lang('OtherTools'),
+                ];
+
+        $csv_content[] = [
+                    get_lang('Student_publication'),
+                    $nb_assignments,
+                ];
+        $csv_content[] = [
+                    get_lang('Messages'),
+                    $messages,
+                ];
+        $csv_content[] = [
+                    get_lang('LinksDetails'),
+                    $links,
+                ];
+        $csv_content[] = [
+                    get_lang('DocumentsDetails'),
+                    $documents,
+                ];
+        $csv_content[] = [
+                    get_lang('UploadedDocuments'),
+                    $uploaded_documents,
+                ];
+        $csv_content[] = [
+                    get_lang('ChatLastConnection'),
+                    $chat_last_connection,
+                ]; ?>
+                <tr><!-- assignments -->
+                    <td width="40%"><?php echo get_lang('Student_publication'); ?></td>
+                    <td><?php echo $nb_assignments; ?></td>
+                </tr>
+                <tr><!-- messages -->
+                    <td><?php echo get_lang('Forum').' - '.get_lang('NumberOfPostsForThisUser'); ?></td>
+                    <td><?php echo $messages; ?></td>
+                </tr>
+                <tr><!-- links -->
+                    <td><?php echo get_lang('LinksDetails'); ?></td>
+                    <td><?php echo $links; ?></td>
+                </tr>
+                <tr><!-- downloaded documents -->
+                    <td><?php echo get_lang('DocumentsDetails'); ?></td>
+                    <td><?php echo $documents; ?></td>
+                </tr>
+                <tr><!-- uploaded documents -->
+                    <td><?php echo get_lang('UploadedDocuments'); ?></td>
+                    <td><?php echo $uploaded_documents; ?></td>
+                </tr>
+                <tr><!-- Chats -->
+                    <td><?php echo get_lang('ChatLastConnection'); ?></td>
+                    <td><?php echo $chat_last_connection; ?></td>
+                </tr>
+                </tbody>
+            </table>
+        </div>
+        <?php
+    } //end details
+
+    echo Tracking::displayUserSkills(
+        $user_info['user_id'],
+        $courseInfo ? $courseInfo['real_id'] : 0,
+        $sessionId
+    );
+}
+
+if ($export) {
+    ob_end_clean();
+    switch ($export) {
+        case 'csv':
+            Export::arrayToCsv($csv_content, 'reporting_student');
+            break;
+        case 'xls':
+            Export::arrayToXls($csv_content, 'reporting_student');
+            break;
+    }
+    exit;
+}
+//Adding AB stuff 2016-12-14 CEMEQ
+$TABLECALHORAIRE = 'c_cal_horaire';
+
+$coursesList = [];
+//On cherche le calendrier pour ce user dans ce cours, groupe
+$sql = "SELECT * FROM user WHERE user_id = $studentId";
+$result = Database::query($sql);
+$horaire_id = Database::fetch_array($result);
+$nom_hor = $horaire_id['official_code'];
+$course_code_real = $_course['real_id'];
+//avec le nom d'horaire= official code, on trouve le nombre de jour a faire
+$sql = "SELECT * FROM $TABLECALHORAIRE
+        where 
+          name = '$nom_hor' and 
+          c_id = $course_code_real ";
+
+$res = Database::query($sql);
+$resulta = Database::fetch_array($res);
+
+$num_hours = $resulta['num_hours'];
+$num_minute = $resulta['num_minute'];
+if ($num_minute == '0') {
+    $num_minute = '1';
+}
+$minute_mod = $num_hours * 60;
+$num_days = 0;
+if (!empty($num_minute)) {
+    $num_days = $minute_mod / $num_minute;
+}
+
+// affichage des jours complétés dans les parcours l'élève
+//on recherche les cours où sont inscrit les user
+$sql2 = "SELECT c_id, user_id FROM course_rel_user WHERE user_id = $studentId";
+
+$result2 = Database::query($sql2);
+$Total = 0;
+while ($a_courses = Database::fetch_array($result2)) {
+    $Courses_code = $a_courses['c_id'];
+    //on sort le c_id avec le code du cours
+    $sql8 = "SELECT * FROM course WHERE code = '$Courses_code'
+        ";
+    $result8 = Database::query($sql8);
+    $course_code_id = Database::fetch_array($result8);
+    $c_id = $Courses_code;
+    // pours chaque cours dans lequel il est inscrit, on cherche les jours complétés
+
+    $Req1 = "SELECT * FROM c_lp_view
+            WHERE user_id = $studentId AND c_id = $c_id";
+    $res = Database::query($Req1);
+
+    while ($result = Database::fetch_array($res)) {
+        $lp_id = $result['lp_id'];
+        $lp_id_view = $result['id'];
+        $c_id_view = $result['c_id'];
+
+        $Req2 = "SELECT id, lp_id ,title ,item_type
+                 FROM  c_lp_item
+                 WHERE lp_id =  $lp_id
+                 AND title LIKE '(+)%'
+                 AND c_id = $c_id_view
+                 AND item_type = 'document'
+            ";
+        $res2 = Database::query($Req2);
+
+        while ($resulta = Database::fetch_array($res2)) {
+            $lp_item_id = $resulta['id'];
+            $Req3 = "SELECT MAX(id)
+                      FROM c_lp_item_view
+                      WHERE  
+                        lp_item_id =  $lp_item_id AND 
+                        lp_view_id =  $lp_id_view AND 
+                        c_id = $c_id_view AND 
+                        status =  'completed'
+                      ";
+            $res3 = Database::query($Req3);
+            while ($resul = Database::fetch_array($res3)) {
+                $max = $resul['0'];
+                $Req4 = "SELECT COUNT( id )
+                         FROM  c_lp_item_view
+                         WHERE  
+                            id = $max AND 
+                            c_id = $c_id_view";
+                $res4 = Database::query($Req4);
+                while ($resultat = Database::fetch_array($res4)) {
+                    $Total = $Total + $resultat[0];
+                }
+            }
+        }
+    }
+}
+
+api_display_tool_title($nameTools);
+$tbl_personal_agenda = Database:: get_main_table(TABLE_PERSONAL_AGENDA);
+$now = date('Y-m-d');
+//on compte le nombre de m% dans l'agenda pour chaque module
+$sqljtot = "SELECT COUNT( * ) AS TOT
+             FROM $tbl_personal_agenda
+             WHERE user = $studentId
+             And title like 'm%'";
+$resultjt = Database::query($sqljtot);
+$jour_realise = 0;
+while ($jtot = Database::fetch_array($resultjt)) {
+    $jour_realise_tot = ($jour_realise + $jtot['TOT']) / 2;
+}
+//fin des jour de l'agenda
+//recherche du jour inséré dans agenda par le calendrier
+$jour_agenda = '';
+$tour = -1;
+while ($jour_agenda == '') {
+    $tour++;
+    $date = date("Y-m-d", mktime(0, 0, 0, date("m"), date("d") - $tour, date("Y")));
+    $sql4 = "SELECT *  FROM $tbl_personal_agenda
+             WHERE 
+              user = $studentId AND  
+                text='Pour le calendrier, ne pas effacer' AND 
+                date like '".$date." %:%' ";
+    $result4 = Database::query($sql4);
+    $res4 = Database::fetch_array($result4);
+    $jour_agenda = $res4['title'];
+    if ($tour > 300) {
+        break;
+    }
+}
+
+$diff = $jour_agenda - $Total;
+if ($diff > 0) {
+    $sing = get_lang('retard');
+} else {
+    $sing = get_lang('avance');
+}
+$diff = abs($diff);
+
+//pour trouver la date de fin de sa formation, on ajoute les retard (%diff) au nombre de jours total de la formation et
+//on regarde dans son agenda pour cette valeur qui donne ainsi la date
+$diff2 = $jour_agenda - $Total;
+$goto = $num_days + $diff2;
+$goto = number_format($goto);
+$sqlgo = "SELECT *  FROM $tbl_personal_agenda
+         WHERE user = $studentId
+            AND title = '".$goto."'  
+         ";
+$result7 = Database::query($sqlgo);
+$res7 = Database::fetch_array($result7);
+$end_dates = $res7['date'];
+$end_date = date("Y-m-d", strtotime($end_dates));
+
+if ($end_date < '2010-01-01') {
+    $end_date = get_lang('hors_cal');
+}
+
+?>
+<table class="data_table">
+    <th rowspan="6">
+        <?php
+        //on récupere les points de controle de l'élève
+        /*$pt[] = '0';
+        $pt[] = '0';
+        $sqlcontrole = "SELECT diff
+                         FROM $tbl_stats_exercices
+                         WHERE exe_user_id = ".$studentId."
+                         AND diff  != ''
+                         ORDER BY exe_date ASC
+                         ";
+        $result = Database::query($sqlcontrole);
+        while ($ptctl = Database::fetch_array($result)) {
+            $pt[] = $ptctl ['diff'];
+        }
+
+        //graphique de suivi
+
+        include "../inc/teechartphp/sources/TChart.php";
+
+        $chart = new TChart(500, 300);
+        $chart->getAspect()->setView3D(false);
+        $chart->getHeader()->setText("Graphique de suivi");
+
+
+        $chart->getAxes()->getLeft()->setMinimumOffset(10);
+        $chart->getAxes()->getLeft()->setMaximumOffset(10);
+
+        $chart->getAxes()->getBottom()->setMinimumOffset(10);
+        $chart->getAxes()->getBottom()->setMaximumOffset(10);
+
+        $line1 = new Line($chart->getChart());
+        $data = $pt;
+        $line1->addArray($data);
+        foreach ($chart->getSeries() as $serie) {
+            $pointer = $serie->getPointer();
+            $pointer->setVisible(true);
+            $pointer->getPen()->setVisible(false);
+            $pointer->setHorizSize(2);
+            $pointer->setVertSize(2);
+
+            $marks = $serie->getMarks();
+            $marks->setVisible(true);
+            $marks->setArrowLength(5);
+            $marks->getArrow()->setVisible(false);
+            $marks->setTransparent(true);
+        }
+        $x = $student_id;
+        $line1->getPointer()->setStyle(PointerStyle::$CIRCLE);
+        $chart->getLegend()->setVisible(false);
+        $chart->render("../garbage/$x-image.png");
+        $rand = rand();
+        print '<img src="../garbage/'.$x.'-image.png?rand='.$rand.'">';
+        */
+        ?>
+        <tr>
+            <th align="left" width="412">
+                <?php echo get_lang('Cumulatif_agenda'); ?>: <b><font
+                            color=#CC0000> <?php echo $jour_realise_tot; ?></font></b></p>
+            </th>
+        </tr>
+        <tr>
+            <th align="left">
+                <?php echo get_lang('Cumulatif'); ?> <b><font color=#CC0000> <?php echo $Total; ?></font></b></p>
+            </th>
+        </tr>
+        <tr>
+            <th align="left">
+                <?php echo get_lang('jours_selon_horaire'); ?>: <b><font
+                            color=#CC0000> <?php echo $jour_agenda; ?><?php echo $Days; ?></font></b></p>
+            </th>
+        </tr>
+        <tr>
+            <th align="left">
+                <?php echo get_lang('dif2'); ?>: <b><font
+                            color=#CC0000> <?php echo $diff; ?><?php echo $Days, $sing; ?></font></b></p>
+            </th>
+        </tr>
+        <tr>
+            <th align="left">
+                <?php echo get_lang('date_fin'); ?>: <b><font color=#CC0000> <?php echo $end_date; ?></font></b></p>
+            </th>
+        </tr>
+    </th>
+</table>
+<hr>
+<br>
+<form action="create_intervention.php" method="post" name="create_intervention">
+    <table class='data_table'>
+        <tr>
+            <th colspan="6">
+                <?php echo get_lang('create_interventions_commentaires');
+                echo $user_info['complete_name']; ?>
+            </th>
+        <tr>
+            <th><?php echo get_lang('level'); ?></th>
+            <th><?php echo get_lang('lang_date'); ?></th>
+            <th><?php echo get_lang('consignes_interventions'); ?></th>
+            <th><?php echo get_lang('Actions'); ?></th>
+        </tr>
+        <tr>
+            <td>
+                <select name="level">
+                    <option value="1">1</option>
+                    <option value="2">2</option>
+                    <option value="3">3</option>
+                </select>
+            </td>
+            <td>
+                <input type="text" name="date" value="<?php echo date("Y-m-d"); ?>">
+            </td>
+            <td><textarea name="inter_coment" style="width:90%;" rows="2"> </textarea></td>
+            <INPUT type=hidden name=ex_user_id value= <?php echo $studentId; ?>>
+            <td><input type="SUBMIT" value="Sauvegarder" name="B1"></td>
+        </tr>
+    </table>
+</form>
+<?php
+
+// formulaire d'édition des commentaires
+?>
+<form>
+    <table class='data_table'>
+        <tr>
+            <th><?php echo get_lang('level'); ?> </th>
+            <th>
+                <?php echo get_lang('lang_date'); ?>
+            </th>
+            <th>
+                <?php echo get_lang('interventions_commentaires'); ?>
+            </th>
+            <th>
+                <?php echo get_lang('Actions'); ?>
+            </th>
+        </tr>
+
+        <?php
+        $tbl_stats_exercices = Database:: get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
+        $sqlinter = "SELECT *
+                     FROM $tbl_stats_exercices
+                     WHERE 
+                        exe_user_id = $studentId AND 
+                        level != 0
+                     ORDER BY exe_date ASC, level ASC 
+                             ";
+        $resultinter = Database::query($sqlinter);
+        $mod_no = null;
+        while ($a_inter = Database::fetch_array($resultinter)) {
+            $level = $a_inter['level'];
+            $mod_no = $a_inter['mod_no'];
+            $inter_coment = stripslashes($a_inter['inter_coment']);
+            $inter_date = substr($a_inter['exe_date'], 0, 11);
+            echo "
+                <tr><center>
+                    <td> ".$a_inter['level']."
+                    </td>
+                <td>
+                     $inter_date
+                    </td>
+                
+                    <td>$inter_coment 
+                </td>
+                ";
+            $exe_id = $a_inter['exe_id']; ?>
+        <td class="highlight">
+            <a href="edit_intervention.php?num=<?php echo $exe_id; ?>&student_id=<?php echo $studentId; ?> ">
+               <?php echo Display::return_icon('edit.png', get_lang('Edit')); ?></a>
+        &nbsp;&nbsp;  <a
+                href="delete_exam.php?num=<?php echo $exe_id; ?>&student_id=<?php echo $studentId; ?>">
+                <img
+                src="../img/delete.gif" border="0"
+                onClick='return confirmDelete2()'>
+            </a>
+            <?php
+        }
+            ?>
+        </td>
+</form>
+<?php
+
+$table_title = '';
+if (!empty($session_id)) {
+    $session_name = api_get_session_name($session_id);
+    $table_title = ($session_name ? Display::return_icon(
+            'session.png',
+            get_lang('Session'),
+            [],
+            ICON_SIZE_SMALL
+        ).' '.$session_name.' ' : '');
+}
+if (!empty($info_course['title'])) {
+    $table_title .= ($info_course ? Display::return_icon(
+            'course.png',
+            get_lang('Course'),
+            [],
+            ICON_SIZE_SMALL
+        ).' '.$info_course['title'].'  ' : '');
+}
+
+echo Display::page_subheader($table_title);
+
+if (empty($_GET['details'])) {
+    $csv_content[] = [];
+    $csv_content[] = [
+        get_lang('Session', ''),
+        get_lang('Course', ''),
+        get_lang('Time', ''),
+        get_lang('Progress', ''),
+        get_lang('Score', ''),
+        get_lang('AttendancesFaults', ''),
+        get_lang('Evaluations'),
+    ];
+
+    $attendance = new Attendance();
+    foreach ($courses_in_session as $key => $courses) {
+        $session_id = $key;
+        $session_info = api_get_session_info($session_id);
+        $session_name = '';
+        if (!empty($session_info)) {
+            $session_name = $session_info['name'];
+        }
+        $date_start = '';
+
+        if (!empty($session_info['date_start']) && $session_info['date_start'] != '0000-00-00') {
+            $date_start = api_format_date($session_info['date_start'], DATE_FORMAT_SHORT);
+        }
+
+        $date_end = '';
+        if (!empty($session_info['date_end']) && $session_info['date_end'] != '0000-00-00') {
+            $date_end = api_format_date($session_info['date_end'], DATE_FORMAT_SHORT);
+        }
+        if (!empty($date_start) && !empty($date_end)) {
+            $date_session = get_lang('From').' '.$date_start.' '.get_lang('Until').' '.$date_end;
+        }
+        $title = '';
+        if (empty($session_id)) {
+            $title = Display::return_icon('course.png', get_lang('Course'), [], ICON_SIZE_SMALL).' '.get_lang(
+                    'Course'
+                );
+        } else {
+            $title = Display::return_icon(
+                    'session.png',
+                    get_lang('Session'),
+                    [],
+                    ICON_SIZE_SMALL
+                ).' '.$session_name.($date_session ? ' ('.$date_session.')' : '');
+        }
+
+        // Courses
+        echo '<table class="data_table">';
+        echo '<h3>'.$title.'</h3>';
+        echo '<tr>
+                <th>'.get_lang('Course').'</th>
+                <th>'.get_lang('Time').'</th>
+                <th>'.get_lang('Score').'</th>
+                <th>'.get_lang('FirstConnexion').'</th>
+                <th>'.get_lang('Progress').'</th>
+                <th>'.get_lang('fin_mod_prevue').'</th>
+                <th>'.get_lang('Details').'</th>
+            </tr>';
+
+        if (!empty($courses)) {
+            foreach ($courses as $course_code) {
+                if (CourseManager:: is_user_subscribed_in_course($studentId, $course_code, true)) {
+                    $course_info = CourseManager:: get_course_information($course_code);
+                    $time_spent_on_course = api_time_to_hms(
+                        Tracking:: get_time_spent_on_the_course($user_info['user_id'], $course_code, $session_id)
+                    );
+                    //on sort le c_id avec le code du cours
+                    $sql8 = "SELECT *
+                      FROM course
+                      WHERE code = '  $course_code'
+                    ";
+                    $result8 = Database::query($sql8);
+                    $course_code_id = Database::fetch_array($result8);
+                    $c_id = $course_code_id['id'];
+
+                    //  firts connection date
+                    $sql2 = 'SELECT STR_TO_DATE(access_date,"%Y-%m-%d")
+                              FROM '.$tbl_stats_access.' 
+                                WHERE access_user_id = '.$studentId.'
+                                AND c_id = '.$c_id.'
+                                    ORDER BY access_id ASC LIMIT 0,1
+                    ';
+                    $rs2 = Database::query($sql2);
+                    $first_connection_date_to_module = Database::result($rs2, 0, 0);
+                    //pour trouver la date de fin prévue du module
+                    $end_date_module = get_lang('hors_cal');
+                    //avec le nom d'horaire= official code, on trouve la date de
+                    // début de chaque module nombre de jour a faire
+                    $sql = "SELECT * FROM c_cal_dates
+                            where horaire_name = '$nom_hor'
+                             and c_id = '$c_id'
+                             AND date = date_format('$first_connection_date_to_module','%Y-%m-%d')
+                             ";
+                    $res = Database::query($sql);
+                    $resulta = Database::fetch_array($res);
+                    $date_debut = $resulta['date'];
+                    //on trouve le nombre de jour pour ce module
+                    $sql = "SELECT * FROM c_cal_set_module where c_id = '$c_id'";
+                    $res = Database::query($sql);
+                    $resulta = Database::fetch_array($res);
+                    $nombre_heure = $resulta['minutes'];
+                    // on trouve le nombre de minute par jour
+                    // Julio
+                    /*$sql = "SELECT * FROM c_cal_horaire where c_id = '$course_code_real'";
+                    $res = Database::query($sql);
+                    $resulta = Database::fetch_array($res);
+                    $nombre_minutes = $resulta['num_minute'];*/
+                    $nombre_minutes = 0;
+                    //on calcule le nombre de jour par module
+                    $nombre_jours_module = $nombre_heure * '60' / $nombre_minutes;
+                    //on arrondi
+                    $nombre_jours_module = number_format($nombre_jours_module, 0);
+                    //on trouve la date de fin de chaque module AND date = date_format('$first_connection_date_to_module','%Y-%m-%d')
+                    $sql = "SELECT * FROM `c_cal_dates`
+                            WHERE 
+                                horaire_name = '$nom_hor' AND 
+                                c_id = '$course_code_real' AND 
+                                STR_TO_DATE(date,'%Y-%m-%d') >= STR_TO_DATE('$first_connection_date_to_module','%Y-%m-%d')
+                            ORDER BY STR_TO_DATE(date, '%Y-%m-%d') ASC ";
+                    $res = Database::query($sql);
+                    mysql_data_seek($res, $nombre_jours_module);
+                    $row = mysql_fetch_row($res);
+                    $end_date_module = $row[1];
+                    //fin de trouver la date de fin prévue du module
+                    // get average of faults in attendances by student
+                    $results_faults_avg = $attendance->get_faults_average_by_course(
+                        $studentId,
+                        $course_code,
+                        $session_id
+                    );
+                    if (!empty($results_faults_avg['total'])) {
+                        if (api_is_drh()) {
+                            $attendances_faults_avg = '<a title="'.get_lang('GoAttendance').'" href="'.api_get_path(
+                                    WEB_CODE_PATH
+                                ).'attendance/index.php?cidReq='.$course_code.'&id_session='.$session_id.'&student_id='.$studentId.'">'.$results_faults_avg['faults'].'/'.$results_faults_avg['total'].' ('.$results_faults_avg['porcent'].'%)</a>';
+                        } else {
+                            $attendances_faults_avg = $results_faults_avg['faults'].'/'.$results_faults_avg['total'].' ('.$results_faults_avg['porcent'].'%)';
+                        }
+                    } else {
+                        $attendances_faults_avg = '0/0 (0%)';
+                    }
+
+                    // Get evaluations by student
+                    $cats = Category::load(null, null, $course_code, null, null, $session_id);
+
+                    $scoretotal = [];
+                    if (isset($cats) && isset($cats[0])) {
+                        if (!empty($session_id)) {
+                            $scoretotal = $cats[0]->calc_score($studentId, $course_code, $session_id);
+                        } else {
+                            $scoretotal = $cats[0]->calc_score($studentId, $course_code);
+                        }
+                    }
+
+                    $scoretotal_display = '0/0 (0%)';
+                    if (!empty($scoretotal)) {
+                        $scoretotal_display = round($scoretotal[0], 1).'/'.round($scoretotal[1], 1).' ('.round(
+                                ($scoretotal[0] / $scoretotal[1]) * 100,
+                                2
+                            ).' %)';
+                    }
+
+                    $progress = Tracking::get_avg_student_progress(
+                        $user_info['user_id'],
+                        $course_code,
+                        null,
+                        $session_id
+                    );
+                    $score = Tracking:: get_avg_student_score($user_info['user_id'], $course_code, null, $session_id);
+                    $progress = empty($progress) ? '0%' : $progress.'%';
+                    $score = empty($score) ? '0%' : $score.'%';
+
+                    $csv_content[] = [
+                        $session_name,
+                        $course_info['title'],
+                        $time_spent_on_course,
+                        $progress,
+                        $score,
+                        $attendances_faults_avg,
+                        $scoretotal_display,
+                    ];
+                    $warming = '';
+                    $today = date('Y-m-d');
+
+                    if ($end_date_module <= $today and $progress != '100%') {
+                        $warming = '<b><font color=#CC0000>  '.get_lang('limite_atteinte').'</font></b>';
+                    }
+
+                    $end_date_module = $end_date_module.$warming;
+
+                    echo '<tr>
+                    <td >'.$course_info['title'].'</td>
+                    <td >'.$time_spent_on_course.'</td>
+                    <td >'.$score.'</td>
+                    <td >'.$first_connection_date_to_module.'</td>
+                    <td >'.$progress.'</td>
+                    <td >'.$end_date_module.'</td>';
+                    if (!empty($coachId)) {
+                        echo '<td width="10">
+                        <a href="'.api_get_self().'?student='.$user_info['user_id'].'&details=true&course='.$course_info['code'].'&id_coach='.$coachId.
+                            '&origin='.Security::remove_XSS($_GET['origin']).'&id_session='.$session_id.'#infosStudent">'.
+                            Display::return_icon('2rightarrow.png', get_lang('Details')).'</a></td>';
+                    } else {
+                        echo '<td width="10"><a href="'.api_get_self(
+                            ).'?student='.$user_info['user_id'].'&details=true&course='.$course_info['code'].'&origin='.Security::remove_XSS(
+                                $_GET['origin']
+                            ).'&id_session='.$session_id.'#infosStudent">'.
+                            Display::return_icon('2rightarrow.png', get_lang('Details')).'</a></td>';
+                    }
+                    echo '</tr>';
+                }
+            }
+        } else {
+            echo "<tr><td colspan='5'>".get_lang('NoCourse')."</td></tr>";
+        }
+        echo '</table>';
+    }
+} else {
+    $csv_content[] = [];
+    $csv_content[] = [str_replace('&nbsp;', '', $table_title)];
+    $t_lp = Database:: get_course_table(TABLE_LP_MAIN);
+
+    // csv export headers
+    $csv_content[] = [];
+    $csv_content[] = [
+        get_lang('Learnpath'),
+        get_lang('Time'),
+        get_lang('AverageScore'),
+        get_lang('LatestAttemptAverageScore'),
+        get_lang('Progress'),
+        get_lang('LastConnexion'),
+    ];
+
+    $sql8 = "SELECT * FROM course WHERE code = '$course_code'";
+    $result8 = Database::query($sql8);
+    $course_code_id = Database::fetch_array($result8);
+    $c_id = $course_code_id['id'];
+    if (empty($session_id)) {
+        $sql_lp = " SELECT lp.name, lp.id FROM $t_lp lp
+                    WHERE session_id = 0 AND c_id = $c_id
+                    ORDER BY lp.display_order";
+    } else {
+        $sql_lp = " SELECT lp.name, lp.id FROM $t_lp lp
+                    WHERE c_id =  $c_id
+                    ORDER BY lp.display_order";
+    }
+
+    $rs_lp = Database::query($sql_lp);
+    if (Database:: num_rows($rs_lp) > 0) {
+        ?>
+        <!-- LPs-->
+        <table class="data_table">
+        <tr>
+            <th><?php echo get_lang('Learnpaths'); ?></th>
+            <th><?php echo get_lang('FirstConnexion'); ?></th>
+            <th><?php echo get_lang('Time').' ';
+        Display:: display_icon(
+                    'info3.gif',
+                    get_lang('TotalTimeByCourse'),
+                    ['align' => 'absmiddle', 'hspace' => '3px']
+                ); ?></th>
+            <th><?php echo get_lang('AverageScore').' ';
+        Display:: display_icon(
+                    'info3.gif',
+                    get_lang('AverageIsCalculatedBasedInAllAttempts'),
+                    ['align' => 'absmiddle', 'hspace' => '3px']
+                ); ?></th>
+            <th><?php echo get_lang('LatestAttemptAverageScore').' ';
+        Display:: display_icon(
+                    'info3.gif',
+                    get_lang('AverageIsCalculatedBasedInTheLatestAttempts'),
+                    ['align' => 'absmiddle', 'hspace' => '3px']
+                ); ?></th>
+            <th><?php echo get_lang('Progress').' ';
+        Display:: display_icon(
+                    'info3.gif',
+                    get_lang('LPProgressScore'),
+                    ['align' => 'absmiddle', 'hspace' => '3px']
+                ); ?></th>
+            <th><?php echo get_lang('LastConnexion').' ';
+        Display:: display_icon(
+                    'info3.gif',
+                    get_lang('LastTimeTheCourseWasUsed'),
+                    ['align' => 'absmiddle', 'hspace' => '3px']
+                ); ?></th>
+            <?php
+            echo '<th>'.get_lang('Details').'</th>';
+        if (api_is_allowed_to_edit()) {
+            echo '<th>'.get_lang('ResetLP').'</th>';
+        } ?>
+        </tr>
+        <?php
+
+        //  firts connection date
+        $sql2 = 'SELECT access_date
+                FROM '.$tbl_stats_access.' 
+                WHERE access_user_id = '.$studentId.'
+                AND c_id = '.$c_id.'
+                ORDER BY access_id ASC LIMIT 0,1
+                ';
+
+        $rs2 = Database::query($sql2);
+        $first_connection_date_to_module = Database::result($rs2, 0, 0);
+        $i = 0;
+        while ($learnpath = Database:: fetch_array($rs_lp)) {
+            $lp_id = intval($learnpath['id']);
+            $lp_name = $learnpath['name'];
+            $any_result = false;
+
+            // Get progress in lp
+            $progress = Tracking::get_avg_student_progress(
+                $studentId,
+                $course_code,
+                [$lp_id],
+                $session_id
+            );
+
+            if ($progress === null) {
+                $progress = '0%';
+            } else {
+                $any_result = true;
+            }
+
+            // Get time in lp
+            $total_time = Tracking::get_time_spent_in_lp(
+                $studentId,
+                $course_code,
+                [$lp_id],
+                $session_id
+            );
+
+            if (!empty($total_time)) {
+                $any_result = true;
+            }
+
+            // Get last connection time in lp
+            $start_time = Tracking::get_last_connection_time_in_lp(
+                $studentId,
+                $course_code,
+                $lp_id,
+                $session_id
+            );
+
+            if (!empty($start_time)) {
+                $start_time = api_convert_and_format_date($start_time, DATE_TIME_FORMAT_LONG);
+            } else {
+                $start_time = '-';
+            }
+
+            if (!empty($total_time)) {
+                $any_result = true;
+            }
+
+            // Quiz in lp
+            $score = Tracking::get_avg_student_score(
+                $studentId,
+                $course_code,
+                [$lp_id],
+                $session_id
+            );
+
+            // Latest exercise results in a LP
+            $score_latest = Tracking:: get_avg_student_score(
+                $studentId,
+                $course_code,
+                [$lp_id],
+                $session_id,
+                false,
+                true
+            );
+
+            if ($i % 2 == 0) {
+                $css_class = "row_even";
+            } else {
+                $css_class = "row_odd";
+            }
+
+            $i++;
+            // csv export content
+            $csv_content[] = [
+                api_html_entity_decode(stripslashes($lp_name), ENT_QUOTES, $charset),
+                api_time_to_hms($total_time),
+                $score.'%',
+                $score_latest.'%',
+                $progress.'%',
+                $start_time,
+            ];
+
+            echo '<tr class="'.$css_class.'">';
+
+            echo Display::tag('td', stripslashes($lp_name));
+            echo Display::tag('td', stripslashes($first_connection_date_to_module));
+            echo Display::tag('td', api_time_to_hms($total_time));
+
+            if (!is_null($score)) {
+                if (is_numeric($score)) {
+                    $score = $score.'%';
+                }
+            }
+            echo Display::tag('td', $score);
+
+            if (!is_null($score_latest)) {
+                if (is_numeric($score_latest)) {
+                    $score_latest = $score_latest.'%';
+                }
+            }
+            echo Display::tag('td', $score_latest);
+
+            if (is_numeric($progress)) {
+                $progress = $progress.'%';
+            } else {
+                $progress = '-';
+            }
+
+            echo Display::tag('td', $progress);
+            //Do not change with api_convert_and_format_date, because this value came from the lp_item_view table
+            //which implies several other changes not a priority right now
+            echo Display::tag('td', $start_time);
+
+            if ($any_result === true) {
+                $from = '';
+                if ($from_myspace) {
+                    $from = '&from=myspace';
+                }
+                $link = Display::url(
+                            Display::return_icon('2rightarrow.png', get_lang('Details')),
+                    'lp_tracking.php?cidReq='.Security::remove_XSS($_GET['course']).'&course='.Security::remove_XSS(
+                        $_GET['course']
+                    ).$from.'&origin='.Security::remove_XSS(
+                        $_GET['origin']
+                    ).'&lp_id='.$learnpath['id'].'&student_id='.$user_info['user_id'].'&id_session='.$session_id
+                );
+                echo Display::tag('td', $link);
+            }
+
+            if (api_is_allowed_to_edit()) {
+                echo '<td>';
+                if ($any_result === true) {
+                    echo '<a href="myStudents.php?action=reset_lp&sec_token='.$token.'&cidReq='.Security::remove_XSS(
+                            $_GET['course']
+                        ).'&course='.Security::remove_XSS($_GET['course']).'&details='.Security::remove_XSS(
+                            $_GET['details']
+                        ).'&origin='.Security::remove_XSS(
+                            $_GET['origin']
+                        ).'&lp_id='.$learnpath['id'].'&student='.$user_info['user_id'].'&details=true&id_session='.Security::remove_XSS(
+                            $_GET['id_session']
+                        ).'">';
+                    echo Display::return_icon('clean.png', get_lang('Clean'), '', ICON_SIZE_SMALL).'</a>';
+                    echo '</a>';
+                }
+                echo '</td>';
+                echo '</tr>';
+            }
+            $data_learnpath[$i][] = $lp_name;
+            $data_learnpath[$i][] = $progress.'%';
+        }
+    } else {
+        //echo '<tr><td colspan="6">'.get_lang('NoLearnpath').'</td></tr>';
+    } ?>
+    </table>
+    <!-- line about exercises -->
+    <table class="data_table">
+        <tr>
+            <th><?php echo get_lang('Exercises'); ?></th>
+            <th><?php echo get_lang('LearningPath'); ?></th>
+            <th><?php echo get_lang('AvgCourseScore').' '.Display:: return_icon(
+                        'info3.gif',
+                        get_lang('AverageScore'),
+                        ['align' => 'absmiddle', 'hspace' => '3px']
+                    ); ?></th>
+            <th><?php echo get_lang('Attempts'); ?></th>
+            <th><?php echo get_lang('LatestAttempt'); ?></th>
+            <th><?php echo get_lang('AllAttempts'); ?></th>
+        </tr>
+        <?php
+
+        $csv_content[] = [];
+    $csv_content[] = [
+            get_lang('Exercises'),
+            get_lang('LearningPath'),
+            get_lang('AvgCourseScore'),
+            get_lang('Attempts'),
+        ];
+
+    $t_quiz = Database:: get_course_table(TABLE_QUIZ_TEST);
+    $sql = "SELECT quiz.title, id FROM ".$t_quiz." AS quiz
+                WHERE
+                    quiz.c_id = $c_id AND
+                    (quiz.session_id = $session_id OR quiz.session_id = 0) AND
+                    active IN (0, 1)
+                ORDER BY quiz.title ASC ";
+    $result_exercices = Database::query($sql);
+    $i = 0;
+    if (Database:: num_rows($result_exercices) > 0) {
+        while ($exercices = Database:: fetch_array($result_exercices)) {
+            $exercise_id = intval($exercices['id']);
+            $count_attempts = Tracking::count_student_exercise_attempts(
+                    $studentId,
+                    $course_code,
+                    $exercise_id,
+                    0,
+                    0,
+                    $session_id,
+                    2
+                );
+            $score_percentage = Tracking::get_avg_student_exercise_score(
+                    $studentId,
+                    $course_code,
+                    $exercise_id,
+                    $session_id,
+                    1,
+                    0
+                );
+
+            if (!isset($score_percentage) && $count_attempts > 0) {
+                $scores_lp = Tracking::get_avg_student_exercise_score(
+                        $studentId,
+                        $course_code,
+                        $exercise_id,
+                        $session_id,
+                        2,
+                        1
+                    );
+                $score_percentage = $scores_lp[0];
+                $lp_name = $scores_lp[1];
+            } else {
+                $lp_name = '-';
+            }
+            $lp_name = !empty($lp_name) ? $lp_name : get_lang('NoLearnpath');
+
+            if ($i % 2) {
+                $css_class = 'row_odd';
+            } else {
+                $css_class = 'row_even';
+            }
+
+            echo '<tr class="'.$css_class.'"><td>'.$exercices['title'].'</td>';
+            echo '<td>';
+
+            if (!empty($lp_name)) {
+                echo $lp_name;
+            } else {
+                echo '-';
+            }
+
+            echo '</td>';
+            echo '<td>';
+
+            if ($count_attempts > 0) {
+                echo $score_percentage.'%';
+            } else {
+                echo '-';
+                $score_percentage = 0;
+            }
+
+            echo '</td>';
+            echo '<td>'.$count_attempts.'</td>';
+            echo '<td>';
+
+            $sql_last_attempt = 'SELECT exe_id FROM '.$tbl_stats_exercices.'
+                                     WHERE  exe_exo_id      ="'.$exercise_id.'" AND
+                                            exe_user_id     ="'.$studentId.'" AND
+                                            c_id    ="'.$course_code.'" AND
+                                            session_id      ="'.$session_id.'" AND
+                                            status          = ""
+                                            ORDER BY exe_date DESC LIMIT 1';
+            $result_last_attempt = Database::query($sql_last_attempt);
+            if (Database:: num_rows($result_last_attempt) > 0) {
+                $id_last_attempt = Database:: result($result_last_attempt, 0, 0);
+                if ($count_attempts > 0) {
+                    echo '<a href="../exercice/exercise_show.php?id='.$id_last_attempt.'&cidReq='.$course_code.'&session_id='.$session_id.'&student='.$studentId.'&origin='.(empty($_GET['origin']) ? 'tracking' : Security::remove_XSS(
+                                $_GET['origin']
+                            )).'"> <img src="'.api_get_path(WEB_IMG_PATH).'quiz.gif" border="0" /> </a>';
+                }
+            }
+            echo '</td>';
+
+            echo '<td>';
+            $all_attempt_url = "../exercice/exercise_report.php?exerciseId=$exercise_id&cidReq=$course_code&filter_by_user=$studentId&id_session=$session_id";
+            echo Display::url(
+                    Display::return_icon('test_results.png', get_lang('AllAttempts'), [], ICON_SIZE_SMALL),
+                    $all_attempt_url
+                );
+
+            echo '</td></tr>';
+            $data_exercices[$i][] = $exercices['title'];
+            $data_exercices[$i][] = $score_percentage.'%';
+            $data_exercices[$i][] = $count_attempts;
+
+            $csv_content[] = [
+                    $exercices['title'],
+                    $lp_name,
+                    $score_percentage,
+                    $count_attempts,
+                ];
+            $i++;
+        }
+    } else {
+        echo '<tr><td colspan="6">'.get_lang('NoExercise').'</td></tr>';
+    }
+    echo '</table>';
+
+    //@when using sessions we do not show the survey list
+    if (empty($session_id)) {
+        $survey_list = SurveyManager::get_surveys($course_code, $session_id);
+        $survey_data = [];
+        foreach ($survey_list as $survey) {
+            $user_list = SurveyManager::get_people_who_filled_survey(
+                    $survey['survey_id'],
+                    false,
+                    $info_course['real_id']
+                );
+            $survey_done = Display::return_icon("accept_na.png", get_lang('NoAnswer'), [], ICON_SIZE_SMALL);
+            if (in_array($studentId, $user_list)) {
+                $survey_done = Display::return_icon("accept.png", get_lang('Answered'), [], ICON_SIZE_SMALL);
+            }
+            $data = ['title' => $survey['title'], 'done' => $survey_done];
+            $survey_data[] = $data;
+        }
+
+        if (!empty($survey_list)) {
+            $table = new HTML_Table(['class' => 'data_table']);
+            $header_names = [get_lang('Survey'), get_lang('Answered')];
+            $row = 0;
+            $column = 0;
+            foreach ($header_names as $item) {
+                $table->setHeaderContents($row, $column, $item);
+                $column++;
+            }
+            $row = 1;
+            if (!empty($survey_data)) {
+                foreach ($survey_data as $data) {
+                    $column = 0;
+                    $table->setCellContents($row, $column, $data);
+                    $class = 'class="row_odd"';
+                    if ($row % 2) {
+                        $class = 'class="row_even"';
+                    }
+                    $table->setRowAttributes($row, $class, true);
+                    $column++;
+                    $row++;
+                }
+            }
+            echo $table->toHtml();
+        }
+    }
+
+    // line about other tools
+    echo '<table class="data_table">';
+
+    $csv_content[] = [];
+    $nb_assignments = Tracking::count_student_assignments($studentId, $course_code, $session_id);
+    $messages = Tracking::count_student_messages($studentId, $course_code, $session_id);
+    $links = Tracking::count_student_visited_links($studentId, $course_code, $session_id);
+    $chat_last_connection = Tracking::chat_last_connection($studentId, $course_code, $session_id);
+    $documents = Tracking::count_student_downloaded_documents($studentId, $course_code, $session_id);
+    $uploaded_documents = Tracking::count_student_uploaded_documents($studentId, $course_code, $session_id);
+
+    $csv_content[] = [
+            get_lang('OtherTools'),
+        ];
+
+    $csv_content[] = [
+            get_lang('StudentPublications'),
+            $nb_assignments,
+        ];
+    $csv_content[] = [
+            get_lang('Messages'),
+            $messages,
+        ];
+    $csv_content[] = [
+            get_lang('LinksDetails'),
+            $links,
+        ];
+    $csv_content[] = [
+            get_lang('DocumentsDetails'),
+            $documents,
+        ];
+    $csv_content[] = [
+            get_lang('UploadedDocuments'),
+            $uploaded_documents,
+        ];
+    $csv_content[] = [
+            get_lang('ChatLastConnection'),
+            $chat_last_connection,
+        ]; ?>
+        <tr>
+            <th colspan="2"><?php echo get_lang('OtherTools'); ?></th>
+        </tr>
+        <tr><!-- assignments -->
+            <td width="40%"><?php echo get_lang('StudentPublications'); ?></td>
+            <td><?php echo $nb_assignments; ?></td>
+        </tr>
+        <tr><!-- messages -->
+            <td><?php echo get_lang('Forum').' - '.get_lang('NumberOfPostsForThisUser'); ?></td>
+            <td><?php echo $messages; ?></td>
+        </tr>
+        <tr><!-- links -->
+            <td><?php echo get_lang('LinksDetails'); ?></td>
+            <td><?php echo $links; ?></td>
+        </tr>
+        <tr><!-- downloaded documents -->
+            <td><?php echo get_lang('DocumentsDetails'); ?></td>
+            <td><?php echo $documents; ?></td>
+        </tr>
+        <tr><!-- uploaded documents -->
+            <td><?php echo get_lang('UploadedDocuments'); ?></td>
+            <td><?php echo $uploaded_documents; ?></td>
+        </tr>
+        <tr><!-- Chats -->
+            <td><?php echo get_lang('ChatLastConnection'); ?></td>
+            <td><?php echo $chat_last_connection; ?></td>
+        </tr>
+    </table>
+    </td>
+    </tr>
+    </table>
+
+    <?php
+} //end details
+
+if ($export_csv) {
+    ob_end_clean();
+    Export:: export_table_csv($csv_content, 'reporting_student');
+    exit;
+}
+?>
+<br>
+<form action="create_exam.php" method="post" name="create_exam">
+    <table class='data_table'>
+        <tr>
+            <th colspan="6">
+                <?php echo get_lang('Title');
+                echo $user_info['complete_name']; ?>
+            </th>
+
+        <tr>
+            <th style="width: 60px">
+                <?php echo get_lang('Module'); ?>
+            </th>
+            <th style="width: 120px">
+                <?php echo get_lang('Results'); ?>
+            </th>
+            <th style="width: 100px">
+                <?php echo get_lang('result_rep_1'); ?>
+            </th>
+            <th style="width: 100px">
+                <?php echo get_lang('result_rep_2'); ?>
+            </th>
+            <th style="width: 720px">
+                <?php echo get_lang('Comment'); ?>
+            </th>
+            <th style="width: 60px">
+                <?php echo get_lang('Actions'); ?>
+            </th>
+        </tr>
+        <tr>
+            <td><input type="text" style="width:90%;" NAME="mod_no" size="1" <?php echo "$mod_no "; ?></textarea></td>
+            <td>
+                <select name="score_ex">
+                    <option value="-">-</option>
+                    <option value="SU">SU</option>
+                    <option value="EC">EC</option>
+                </select>
+            </td>
+            <td>
+                <select name="score_rep1">
+                    <option value="-">-</option>
+                    <option value="SU">SU</option>
+                    <option value="EC">EC</option>
+                </select>
+            </td>
+            <td>
+                <select name="score_rep2">
+                    <option value="-">-</option>
+                    <option value="SU">SU</option>
+                    <option value="EC">EC</option>
+                </select>
+            </td>
+            <td><textarea name="coment" style="width:70%; rows=" 2"><?php echo "$coment"; ?></textarea></td>
+            <INPUT type=hidden name=ex_user_id value= <?php echo $studentId; ?>>
+            <td><input type="SUBMIT" value="<?php echo get_lang('Save'); ?>" name="create_exam"></td>
+        </tr>
+    </table>
+</form>
+
+<form name="save_exam">
+    <table class='data_table'>
+        <tr>
+            <th colspan="6">
+                <?php echo get_lang('result_exam_title');
+                echo $user_info['complete_name']; ?>
+            </th>
+        <tr>
+            <th><?php echo get_lang('Module'); ?> </th>
+            <th>
+                <?php echo get_lang('Results'); ?>
+            </th>
+            <th>
+                <?php echo get_lang('result_rep_1'); ?>
+            </th>
+            <th>
+                <?php echo get_lang('result_rep_2'); ?>
+            </th>
+            <th>
+                <?php echo get_lang('Comment'); ?>
+            </th>
+            <th>
+                <?php echo get_lang('Actions'); ?>
+            </th>
+        </tr>
+        <?php
+        $sqlexam = "SELECT *
+                     FROM $tbl_stats_exercices
+                     WHERE exe_user_id = $studentId
+                     AND c_id = 0 AND mod_no != '0'
+                     ORDER BY mod_no ASC";
+        $resultexam = Database::query($sqlexam);
+        $coment = '';
+        while ($a_exam = Database::fetch_array($resultexam)) {
+            //$ex_id = $a_exam['ex_id'];
+            $mod_no = $a_exam['mod_no'];
+            $score_ex = $a_exam['score_ex'];
+            $score_rep1 = $a_exam['score_rep1'];
+            $score_rep2 = $a_exam['score_rep2'];
+            $coment = stripslashes($a_exam['coment']);
+            echo "
+            <tr><center>
+                <td> ".$a_exam['mod_no']."
+                </td>
+            <td><center>
+                    ".$a_exam['score_ex']."
+                </td>
+            <td><center>
+                    ".$a_exam['score_rep1']."
+                </td>
+                <td><center>
+                    ".$a_exam['score_rep2']."
+                </td>
+                <td>$coment
+
+            ";
+            $exe_idd = $a_exam['exe_id']; ?>
+            <INPUT type=hidden name=ex_idd value= <?php echo "$exe_idd"; ?>>
+            <td class="highlight">&nbsp;
+                <a href="edit_exam.php?num=<?php echo $exe_idd; ?>&student_id=<?php echo $studentId; ?>">
+                    <?php echo Display::return_icon('edit.png', get_lang('Edit')); ?>
+                </a>
+                &nbsp;&nbsp;<a href="delete_exam.php?num=<?php echo $exe_idd; ?>&student_id=<?php echo $studentId; ?>">
+                    <img
+                     src="../img/delete.gif" border="0"
+                    onClick='return confirmDelete2()'></a>
+            </td>
+            </tr>
+            <?php
+        }
+        ?>
+    </table>
+</form>
+<strong><?php echo get_lang('imprime_sommaire'); ?> </strong>
+<?php
+echo '<a target="_blank" 
+    href="print_myStudents.php?student='.$studentId.'&details=true&course='.$course_code.'&origin=tracking_course">
+<img src="'.api_get_path(WEB_IMG_PATH).'printmgr.gif" border="0" /></a>';
+// tableau pour date de fin prévue pour chaque module
+?>
+<table class='data_table'>
+    <tr>
+        <th colspan="6">
+            <?php echo get_lang('fin_mod_prevue');
+            echo $user_info['complete_name']; ?>
+        </th>
+    <tr>
+        <th style="width: 17%">
+            <?php echo get_lang('Module'); ?>
+        </th>
+        <th style="width: 17%">
+            <?php echo get_lang('FirstLogin'); ?>
+        </th>
+        <th style="width: 16%">
+            <?php echo get_lang('ToDo'); ?>
+        </th>
+        <th style="width: 16%">
+            <?php echo get_lang('realise'); ?>
+        </th>
+        <th style="width: 16%">
+            <?php echo get_lang('pour_realise'); ?>
+        </th>
+        <th style="width: 16%">
+            <?php echo get_lang('fin_mod_prevue'); ?>
+        </th>
+    </tr>
+</table>
+
+<?php Display:: display_footer();

+ 514 - 0
main/extra/my_progress_ind.php

@@ -0,0 +1,514 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+require_once '../inc/global.inc.php';
+
+$allow = api_get_configuration_value('extra');
+if (empty($allow)) {
+    exit;
+}
+
+api_block_anonymous_users();
+
+$nameTools = get_lang('MyProgress');
+$this_section = 'session_my_progress_ind';
+$_user = api_get_user_info();
+
+$tbl_stats_exercices = Database:: get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
+$tbl_stats_access = Database:: get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
+
+Display::display_header($nameTools);
+
+$result = Database::query(
+    "SELECT DISTINCT session.id as id, name, access_start_date date_start, access_end_date date_end 
+    FROM session_rel_course_rel_user,session 
+    WHERE session_id=session.id AND user_id=".$_user['user_id']." 
+    ORDER BY date_start, date_end, name");
+
+$Sessions = Database::store_result($result);
+$Courses = [];
+
+foreach ($Sessions as $enreg) {
+    $id_session_temp = $enreg['id'];
+    $sql8 = "SELECT *
+                FROM course
+                WHERE code = '$courses_code'
+                ";
+    $result8 = Database::query($sql8);
+    $course_code_id = Database::fetch_array($result8);
+    $c_id = $course_code_id['id'];
+    $sql = "SELECT DISTINCT c_id,title, CONCAT(lastname, ' ',firstname) coach, username, date_start, date_end, db_name
+            FROM $tbl_course , $tbl_session_course
+            LEFT JOIN $tbl_user
+                ON $tbl_session_course.id_coach = $tbl_user.user_id
+            INNER JOIN $tbl_session_course_user
+                ON $tbl_session_course_user.id_session = $tbl_session_course.id_session
+                AND $tbl_session_course_user.id_user = '".$_user['user_id']."'
+            INNER JOIN $tbl_session ON $tbl_session.id = $tbl_session_course.id_session
+            WHERE $tbl_session_course.c_id=$c_id
+            AND $tbl_session_course.id_session='$id_session_temp'
+            ORDER BY title";
+    $result = Database::query($sql);
+    while ($a_session_courses = Database::fetch_array($result)) {
+        $a_session_courses['id_session'] = $id_session_temp;
+        $Courses[$a_session_courses['code']] = $a_session_courses;
+    }
+}
+
+// affichage des jours complétés dans les parcours l'élève
+//on recherche les cours où sont inscrit les user
+$user_c_id = $_user['user_id'];
+$sql2 = "SELECT  c_id, user_id
+        FROM course_rel_user
+        WHERE user_id = '$user_c_id'
+        ";
+$result2 = Database::query($sql2);
+$Total = 0;
+while ($a_courses = Database::fetch_array($result2)) {
+    $courses_code = $a_courses['c_id'];
+    //on sort le c_id avec le code du cours
+    //$sql8 = "SELECT *
+//      FROM course
+//      WHERE code = '$courses_code'
+//      ";
+//        $result8 = Database::query($sql8);
+//        $course_code_id = Database::fetch_array($result8) ;
+    $c_id = $courses_code;
+    //pours chaque cours dans lequel il est inscrit, on cherche les jours complétés
+    $Req1 = "SELECT *
+             FROM c_lp_view
+             WHERE user_id  =  '$user_c_id' AND c_id = '$c_id'
+    ";
+    $res = Database::query($Req1);
+    while ($result = Database::fetch_array($res)) {
+        $lp_id = $result['lp_id'];
+        $lp_id_view = $result['id'];
+        $c_id_view = $result['c_id'];
+        $Req2 = "SELECT id, lp_id ,title ,item_type
+                    FROM  c_lp_item
+                 WHERE lp_id =  '$lp_id'
+                 AND title LIKE '(+)%'
+                 AND c_id = '$c_id_view'
+                 AND item_type = 'document'
+            ";
+        $res2 = Database::query($Req2);
+        while ($resulta = Database::fetch_array($res2)) {
+            $lp_item_id = $resulta['id'];
+            $Req3 = " SELECT Max(id)
+                      FROM  c_lp_item_view
+                      WHERE  
+                        lp_item_id =  '$lp_item_id' AND 
+                        lp_view_id =  '$lp_id_view' AND 
+                        c_id = '$c_id_view' AND 
+                        status =  'completed'
+                      ";
+            $res3 = Database::query($Req3);
+            while ($resul = Database::fetch_array($res3)) {
+                $max = $resul['0'];
+                $Req4 = "SELECT COUNT( id )
+                          FROM  c_lp_item_view
+                          WHERE  
+                            id = '$max' AND 
+                            c_id = '$c_id_view'    
+                                ";
+                $res4 = Database::query($Req4);
+                while ($resultat = Database::fetch_array($res4)) {
+                    if ($resultat[0] == null) {
+                        $resultat[0] = 0;
+                    }
+                    $Total = $Total + $resultat[0];
+                }
+            }
+        }
+    }
+}
+
+api_display_tool_title($nameTools);
+
+$now = date('Y-m-d');
+$tbl_personal_agenda = Database:: get_main_table(TABLE_PERSONAL_AGENDA);
+
+//on compte le nombre de m% dans l'agenda pour chaque module
+$sqljtot = "SELECT COUNT( * ) AS TOT
+             FROM $tbl_personal_agenda
+             WHERE user = '".$_user['user_id']."'
+             And title like 'm%'
+            
+             ";
+$resultjt = Database::query($sqljtot);
+$jour_realise = 0;
+while ($jtot = Database::fetch_array($resultjt)) {
+    $jour_realise_tot = ($jour_realise + $jtot['TOT']) / 2;
+}
+
+//fin des jour de l'agenda
+//on trouve le nombre dans l'agenda selon la date d'aujourdhui
+//si rien n'est inscrit cette journée dans l'agenda, recule de -1
+$jour_agenda = '';
+$tour = -1;
+while ($jour_agenda == '') {
+    $tour++;
+    $date = date("Y-m-d", mktime(0, 0, 0, date("m"), date("d") - $tour, date("Y")));
+    $sql4 = "SELECT title  FROM $tbl_personal_agenda
+             WHERE user = '".$_user['user_id']."' AND  
+             text='Pour le calendrier, ne pas effacer' AND 
+             date like '".$date." %:%' ";
+    $result4 = Database::query($sql4);
+    $res4 = Database::fetch_array($result4);
+    $jour_agenda = $res4['title'];
+    if ($tour > 300) {
+        break;
+    }
+}
+$diff = $jour_agenda - $Total;
+if ($diff > 0) {
+    $sing = get_lang('retard');
+} else {
+    $sing = get_lang('avance');
+}
+$diff = abs($diff);
+?>
+<table class="data_table">
+    <th rowspan="5">
+        <?php
+        //on récupere les points de controle de l'élève
+        $pt[] = '0';
+        $pt[] = '0';
+        $sqlcontrole = "SELECT diff
+                         FROM $tbl_stats_exercices
+                         WHERE exe_user_id =  ".$_user['user_id']."
+                         AND diff  != ''
+                         ORDER BY exe_date ASC
+                         ";
+        $result = Database::query($sqlcontrole);
+        while ($ptctl = Database::fetch_array($result)) {
+            $pt[] = $ptctl['diff'];
+        }
+
+        //graphique de suivi
+
+        /*include "../inc/teechartphp/sources/TChart.php";
+        $chart = new TChart(500, 300);
+        $chart->getAspect()->setView3D(false);
+        $chart->getHeader()->setText("Graphique de suivi");
+        $chart->getAxes()->getLeft()->setMinimumOffset(10);
+        $chart->getAxes()->getLeft()->setMaximumOffset(10);
+        $chart->getAxes()->getBottom()->setMinimumOffset(10);
+        $chart->getAxes()->getBottom()->setMaximumOffset(10);
+        $line1 = new Line($chart->getChart());
+        $data = $pt;
+        $line1->addArray($data);
+        foreach ($chart->getSeries() as $serie) {
+            $pointer = $serie->getPointer();
+            $pointer->setVisible(true);
+            $pointer->getPen()->setVisible(false);
+            $pointer->setHorizSize(2);
+            $pointer->setVertSize(2);
+
+            $marks = $serie->getMarks();
+            $marks->setVisible(true);
+            $marks->setArrowLength(5);
+            $marks->getArrow()->setVisible(false);
+            $marks->setTransparent(true);
+        }
+
+        $x = $_user['user_id'];
+        $line1->getPointer()->setStyle(PointerStyle::$CIRCLE);
+        $chart->getLegend()->setVisible(false);
+        $chart->render("../garbage/$x-image.png");
+        $rand = rand();
+        print '<img src="../garbage/'.$x.'-image.png?rand='.$rand.'">';
+        */
+        ?>
+        <tr>
+            <th align="left" width="412">
+                <?php echo get_lang('Cumulatif_agenda'); ?>:
+                <b><font color=#CC0000> <?php echo $jour_realise_tot; ?></font></b>
+            </th>
+        </tr>
+        <tr>
+            <th align="left">
+                <?php echo get_lang('Cumulatif'); ?> <b><font color=#CC0000> <?php echo $Total; ?></font></b>
+            </th>
+        </tr>
+        <tr>
+            <th align="left">
+                <?php echo get_lang('jours_selon_horaire'); ?>:
+                <b><font color=#CC0000> <?php echo $jour_agenda; ?><?php echo $Days; ?></font></b>
+            </th>
+        </tr>
+        <tr>
+            <th align="left">
+                <?php echo get_lang('diff2'); ?>:
+                <b><font color=#CC0000> <?php echo $diff; ?><?php echo $Days, $sing; ?></font></b>
+            </th>
+        </tr>
+    </table>
+    <hr>
+    <table class='data_table'>
+        <tr>
+            <th><?php echo get_lang('level'); ?> </th>
+            <th>
+                <?php echo get_lang('lang_date'); ?>
+            </th>
+            <th>
+                <?php echo get_lang('interventions_commentaires'); ?>
+            </th>
+        </tr>
+        <?php
+
+        $sqlinter = "SELECT *
+                     FROM $tbl_stats_exercices
+                     WHERE exe_user_id = ".$_user['user_id']."
+                     And level != 0
+                     Order by LEVEL ASC";
+        $resultinter = Database::query($sqlinter);
+        $level = '';
+        while ($a_inter = Database::fetch_array($resultinter)) {
+            $level = $a_inter['level'];
+            $mod_no = $a_inter['mod_no'];
+            $inter_coment = Security::remove_XSS($a_inter['inter_coment']);
+            $inter_date = substr($a_inter['exe_date'], 0, 11);
+            echo "
+                <tr>
+                    <td> ".$a_inter['level']."</td>
+                    <td> $inter_date </td>                
+                    <td>$inter_coment</td>";
+            $exe_id = $a_inter['exe_id'];
+        }
+        if ($level == 3) {
+            echo '<span style="color: red; font-weight: bold;"><img src="../img/anim/pointeranim.gif"align="middle"  > ';
+            echo $limit;
+            echo '</span>';
+        }
+        ?>
+        <p>
+    </table><br>
+<?php
+//début de fin des cours prevu
+$user_info = api_get_user_info();
+$user_id = api_get_user_id();
+//On cherche le calendrier pour ce user et le c_id de ce calendrier
+$sql = "SELECT * 
+        FROM user
+        WHERE user_id = '$user_id'
+        ";
+$result = Database::query($sql);
+$horaire_id = Database::fetch_array($result);
+$nom_hor = $horaire_id['official_code'];
+$c_id_horaire = strstr($nom_hor, '.');
+$c_id_horaire = str_replace(".", "", "$c_id_horaire");
+// Courses
+echo '<h3>'.get_lang('Course').'</h3>';
+echo '<table class="data_table">';
+echo '<tr>
+        <th>'.get_lang('Course').'</th>
+        <th>'.get_lang('Time').'</th>
+        <th>'.get_lang('FirstConnexion').'</th>
+        <th>'.get_lang('Progress').'</th>
+        <th>'.get_lang('fin_mod_prevue').'</th>            
+    </tr>';
+//on recherche les cours où sont inscrit les user
+$user_c_id = $_user['user_id'];
+$sql2 = "SELECT  c_id, user_id
+         FROM course_rel_user
+         WHERE user_id = '$user_id'";
+
+$result2 = Database::query($sql2);
+while ($a_courses = Database::fetch_array($result2)) {
+    $courses_code = $a_courses['c_id'];
+    //on sort le c_id avec le code du cours
+    $sql8 = "SELECT title, code
+             FROM course
+             WHERE id = '$courses_code'";
+    $result8 = Database::query($sql8);
+    $course_code_id = Database::fetch_array($result8);
+    $c_id = $courses_code;
+    $c_title = $course_code_id['title'];
+    // Francois Belisle Kezber
+    // The Tracking Class still uses the course code rather then the course id.
+    $tracking_c_code = $course_code_id['code'];
+    // time spent on the course
+    $time_spent_on_course = api_time_to_hms(Tracking:: get_time_spent_on_the_course($user_id, $c_id, $session_id));
+    //  firts connection date
+    $sql2 = "SELECT STR_TO_DATE(access_date,'%Y-%m-%d')
+            FROM $tbl_stats_access 
+            WHERE 
+             access_user_id = '$user_id' AND 
+             c_id = '$c_id'
+             ORDER BY access_id ASC 
+            LIMIT 0,1";
+
+    //Francois Belisle Kezber
+    // mysql fonctions rather then Database::
+    // conversion to Database::
+    $rs2 = Database::query($sql2);
+    $num_rows = Database::num_rows($rs2);
+    if ($num_rows > 0) {
+        $rw2 = Database::fetch_array($rs2);
+        $first_connection_date_to_module = $rw2[0];
+    }
+
+    //pour trouver la date de fin prévue du module
+    $end_date_module = get_lang('hors_cal');
+    //on trouve le nombre de jour pour ce module
+    $sql = "SELECT * FROM c_cal_set_module
+            where c_id = '$c_id'";
+    $res = Database::query($sql);
+    $resulta = Database::fetch_array($res);
+    $nombre_heure = $resulta['minutes'];
+    // on trouve le nombre de minute par jour
+    $sql = "SELECT * FROM c_cal_horaire
+            where c_id = '$c_id_horaire'
+            AND name =  '$nom_hor'
+             ";
+
+    $res = Database::query($sql);
+    $resulta = Database::fetch_array($res);
+    $nombre_minutes = (int) $resulta['num_minute'];
+    //on calcule le nombre de jour par module
+    $nombre_jours_module = 0;
+    if (!empty($nombre_minutes)) {
+        $nombre_jours_module = $nombre_heure * '60' / $nombre_minutes;
+    }
+    //on arrondi
+    $nombre_jours_module = (int) $nombre_jours_module;
+    //on trouve la date de fin de chaque module AND date = date_format('$first_connection_date_to_module','%Y-%m-%d')
+    $sql = "SELECT * FROM c_cal_dates
+              WHERE 
+              horaire_name = '$nom_hor' AND 
+              c_id = '$c_id_horaire' AND 
+              STR_TO_DATE(date,'%Y-%m-%d') >= STR_TO_DATE('$first_connection_date_to_module','%Y-%m-%d')
+              ORDER BY STR_TO_DATE(date, '%Y-%m-%d') asc
+              LIMIT $nombre_jours_module, 18446744073709551615          
+          ";
+    $res = Database::query($sql);
+    //Database::data_seek($res,$nombre_jours_module);
+    $row = Database::fetch_row($res);
+    $end_date_module = $row[1];
+    //fin de trouver la date de fin prévue du module
+    //progression en %
+    $t_lp = Database:: get_course_table(TABLE_LP_MAIN);
+    $sql_lp = " SELECT lp.name, lp.id FROM $t_lp lp WHERE c_id = '$c_id'  ORDER BY lp.display_order";
+    $rs_lp = Database::query($sql_lp);
+    $i = 0;
+    while ($learnpath = Database:: fetch_array($rs_lp)) {
+        $lp_id = intval($learnpath['id']);
+        $lp_name = $learnpath['name'];
+        $any_result = false;
+        // Get progress in lp
+        // Francois Belisle Kezber
+        // Course Code passed rather then course_id
+        $progress = Tracking::get_avg_student_progress(
+            $user_c_id, /*$c_id*/
+            $tracking_c_code,
+            [$lp_id],
+            $session_id
+        );
+        if ($progress === null) {
+            $progress = '0%';
+        } else {
+            $any_result = true;
+        }
+
+        // Get time in lp
+        // Francois Belisle Kezber
+        // Course Code passed rather then course_id
+        $total_time = Tracking::get_time_spent_in_lp(
+            $user_c_id, /*$c_id*/
+            $tracking_c_code,
+            [$lp_id],
+            $session_id
+        );
+        if (!empty($total_time)) {
+            $any_result = true;
+        }
+
+        if ($i % 2 == 0) {
+            $css_class = "row_even";
+        } else {
+            $css_class = "row_odd";
+        }
+
+        $i++;
+
+        if (is_numeric($progress)) {
+            $progress = $progress.'%';
+        } else {
+            $progress = '-';
+        }
+        $data_learnpath[/*$i*/
+        $lp_id][] = $progress.'%';
+    }
+    $warming = '';
+    $today = date('Y-m-d');
+    if (isset($end_date_module) && $end_date_module <= $today and $progress != '100%') {
+        $warming = '<b><font color=#CC0000>  '.get_lang('limite_atteinte').'</font></b>';
+    }
+    $end_date_module = $end_date_module.$warming;
+    echo '<tr>
+            <td >'.$c_title.'</td>
+            <td >'.$time_spent_on_course.'</td>
+            <td >'.$first_connection_date_to_module.'</td>
+            <td >'.$progress.'</td>
+            <td >'.$end_date_module.'</td>';
+    echo '</tr>';
+}
+echo '</table>';
+?>   </table>
+    <br/><br/>
+    <table class='data_table'>
+        <tr>
+            <th colspan="6">
+                <?php
+                echo get_lang('result_exam');
+                //echo $_user['name'];
+                ?>
+            </th>
+        <tr>
+            <th><?php echo get_lang('module'); ?></th>
+            <th><?php echo get_lang('result_exam'); ?></th>
+            <th><?php echo get_lang('result_rep_1'); ?></th>
+            <th><?php echo get_lang('result_rep_2'); ?></th>
+            <th><?php echo get_lang('comment'); ?></th>
+        </tr>
+        <?php
+
+        $sqlexam = "SELECT *
+                     FROM $tbl_stats_exercices
+                     WHERE exe_user_id = '".$_user['user_id']."'
+                     AND c_id = '0'  AND mod_no != '0'
+                     ORDER BY mod_no ASC";
+        $resultexam = Database::query($sqlexam);
+        while ($a_exam = Database::fetch_array($resultexam)) {
+            $ex_id = $a_exam['ex_id'];
+            $mod_no = $a_exam['mod_no'];
+            $score_ex = $a_exam['score_ex'];
+            $score_rep1 = $a_exam['score_rep1'];
+            $score_rep2 = $a_exam['score_rep2'];
+            $coment = stripslashes($a_exam['coment']);
+            echo "
+                <tr>
+                    <td><center> ".$a_exam['mod_no']."
+                    </td>
+                <td><center>
+                        ".$a_exam['score_ex']."
+                    </td>
+                <td><center>
+                        ".$a_exam['score_rep1']."
+                    </td><center>
+                    <td><center>
+                        ".$a_exam['score_rep2']."
+                    </td>
+                    <td>$coment
+
+                ";
+            $exe_idd = $a_exam['exe_id']; ?>
+            </tr>
+            <?php
+        }
+        ?>
+    </table>
+<?php
+
+Display::display_footer();

+ 222 - 0
main/extra/print_myStudents.php

@@ -0,0 +1,222 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+require_once '../inc/global.inc.php';
+
+$allow = api_get_configuration_value('extra');
+if (empty($allow)) {
+    exit;
+}
+
+$from_myspace = false;
+if (isset($_GET['from']) && $_GET['from'] == 'myspace') {
+    $from_myspace = true;
+    $this_section = SECTION_TRACKING;
+} else {
+    $this_section = SECTION_COURSES;
+}
+
+//$nameTools = get_lang('StudentDetails');
+$cidReset = true;
+$get_course_code = Security:: remove_XSS($_GET['course']);
+if (isset($_GET['details'])) {
+    if (!empty($_GET['origin']) && $_GET['origin'] == 'user_course') {
+        $course_info = CourseManager:: get_course_information($get_course_code);
+        if (empty($cidReq)) {
+            $interbreadcrumb[] = [
+                "url" => api_get_path(WEB_COURSE_PATH).$course_info['directory'],
+                'name' => $course_info['title'],
+            ];
+        }
+        $interbreadcrumb[] = [
+            "url" => "../user/user.php?cidReq=".$get_course_code,
+            "name" => get_lang("Users"),
+        ];
+    } else {
+        if (!empty($_GET['origin']) && $_GET['origin'] == 'tracking_course') {
+            $course_info = CourseManager:: get_course_information($get_course_code);
+            if (empty($cidReq)) {
+                //$interbreadcrumb[] = array ("url" => api_get_path(WEB_COURSE_PATH).$course_info['directory'], 'name' => $course_info['title']);
+            }
+            $interbreadcrumb[] = [
+                "url" => "../tracking/courseLog.php?cidReq=".$get_course_code.'&studentlist=true&id_session='.(empty($_SESSION['id_session']) ? '' : $_SESSION['id_session']),
+                "name" => get_lang("Tracking"),
+            ];
+        } else {
+            if (!empty($_GET['origin']) && $_GET['origin'] == 'resume_session') {
+                $interbreadcrumb[] = [
+                    'url' => '../admin/index.php',
+                    "name" => get_lang('PlatformAdmin'),
+                ];
+                $interbreadcrumb[] = [
+                    'url' => "../admin/session_list.php",
+                    "name" => get_lang('SessionList'),
+                ];
+                $interbreadcrumb[] = [
+                    'url' => "../admin/resume_session.php?id_session=".Security:: remove_XSS($_GET['id_session']),
+                    "name" => get_lang('SessionOverview'),
+                ];
+            } else {
+                $interbreadcrumb[] = [
+                    "url" => "index.php",
+                    "name" => get_lang('MySpace'),
+                ];
+                if (isset($_GET['id_coach']) && intval($_GET['id_coach']) != 0) {
+                    $interbreadcrumb[] = [
+                        "url" => "student.php?id_coach=".Security:: remove_XSS($_GET['id_coach']),
+                        "name" => get_lang("CoachStudents"),
+                    ];
+                    $interbreadcrumb[] = [
+                        "url" => "myStudents.php?student=".Security:: remove_XSS(
+                                $_GET['student']
+                            ).'&id_coach='.Security:: remove_XSS($_GET['id_coach']),
+                        "name" => get_lang("StudentDetails"),
+                    ];
+                } else {
+                    $interbreadcrumb[] = [
+                        "url" => "student.php",
+                        "name" => get_lang("MyStudents"),
+                    ];
+                    $interbreadcrumb[] = [
+                        "url" => "myStudents.php?student=".Security:: remove_XSS($_GET['student']),
+                        "name" => get_lang("StudentDetails"),
+                    ];
+                }
+            }
+        }
+    }
+    $nameTools = get_lang("DetailsStudentInCourse");
+} else {
+    if (!empty($_GET['origin']) && $_GET['origin'] == 'resume_session') {
+        $interbreadcrumb[] = [
+            'url' => '../admin/index.php',
+            "name" => get_lang('PlatformAdmin'),
+        ];
+        $interbreadcrumb[] = [
+            'url' => "../admin/session_list.php",
+            "name" => get_lang('SessionList'),
+        ];
+        $interbreadcrumb[] = [
+            'url' => "../admin/resume_session.php?id_session=".Security:: remove_XSS($_GET['id_session']),
+            "name" => get_lang('SessionOverview'),
+        ];
+    } else {
+        $interbreadcrumb[] = [
+            "url" => "index.php",
+            "name" => get_lang('MySpace'),
+        ];
+        if (isset($_GET['id_coach']) && intval($_GET['id_coach']) != 0) {
+            if (isset($_GET['id_session']) && intval($_GET['id_session']) != 0) {
+                $interbreadcrumb[] = [
+                    "url" => "student.php?id_coach=".Security:: remove_XSS(
+                            $_GET['id_coach']
+                        )."&id_session=".$_GET['id_session'],
+                    "name" => get_lang("CoachStudents"),
+                ];
+            } else {
+                $interbreadcrumb[] = [
+                    "url" => "student.php?id_coach=".Security:: remove_XSS($_GET['id_coach']),
+                    "name" => get_lang("CoachStudents"),
+                ];
+            }
+        } else {
+            $interbreadcrumb[] = [
+                "url" => "student.php",
+                "name" => get_lang("MyStudents"),
+            ];
+        }
+    }
+}
+
+api_block_anonymous_users();
+
+if (!api_is_allowed_to_edit() && !api_is_coach() && !api_is_drh() && !api_is_course_tutor(
+    ) && $_user['status'] != SESSIONADMIN && !api_is_platform_admin(true)) {
+    api_not_allowed(true);
+}
+
+Display:: display_header($nameTools);
+$tbl_stats_exercices = Database:: get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
+
+if (isset($_GET['user_id']) && $_GET['user_id'] != '') {
+    $user_id = intval($_GET['user_id']);
+} else {
+    $user_id = $_user['user_id'];
+}
+
+$session_id = isset($_GET['id_session']) ? intval($_GET['id_session']) : 0;
+$student_id = (int) $_GET['student'];
+
+// Action behaviour
+$check = Security::check_token('get');
+
+if (!empty($student_id)) { // infos about user
+    $info_user = api_get_user_info($student_id);
+}
+if (api_is_drh() && !UserManager::is_user_followed_by_drh($student_id, $_user['user_id'])) {
+    api_not_allowed();
+}
+
+$info_user['name'] = api_get_person_name($info_user['firstname'], $info_user['lastname']);
+
+?>
+<table class='data_table'>
+    <tr>
+        <th colspan="6">
+            <?php echo get_lang('result_exam_title');
+            echo $info_user['name']; ?>
+        </th>
+    <tr>
+        <th><?php echo get_lang('module_no'); ?></th>
+        <th>
+            <?php echo get_lang('result_exam'); ?>
+        </th>
+        <th>
+            <?php echo get_lang('result_rep_1'); ?>
+        </th>
+        <th>
+            <?php echo get_lang('result_rep_2'); ?>
+        </th>
+        <th>
+            <?php echo get_lang('comment'); ?>
+        </th>
+    </tr>
+    <?php
+    $sqlexam = "SELECT *
+                 FROM $tbl_stats_exercices
+                 WHERE exe_user_id = $student_id
+                 AND c_id = 0 AND mod_no != '0'
+                 ORDER BY mod_no ASC";
+    $resultexam = Database::query($sqlexam);
+    while ($a_exam = Database::fetch_array($resultexam)) {
+        //$ex_id = $a_exam['ex_id'];
+        $mod_no = $a_exam['mod_no'];
+        $score_ex = $a_exam['score_ex'];
+        $score_rep1 = $a_exam['score_rep1'];
+        $score_rep2 = $a_exam['score_rep2'];
+        $coment = stripslashes($a_exam['coment']);
+        echo "
+            <tr>
+                <td> ".$a_exam['mod_no']."
+                </td>
+                <td>
+                    ".$a_exam['score_ex']."
+                </td>
+                <td>
+                    ".$a_exam['score_rep1']."
+                </td>
+                <td>
+                    ".$a_exam['score_rep2']."
+                </td>
+                <td>
+                    $coment
+                </td>
+            </tr>
+            ";
+        $exe_idd = $a_exam['exe_id'];
+    }
+?>
+</table>
+</form>
+<strong><?php echo get_lang('imprime_sommaire'); ?> </strong>
+<a href="#" onclick="window.print()"><img align="absbottom" src="../img/printmgr.gif" border="0"></a>

+ 67 - 0
main/extra/save_school_calendar.php

@@ -0,0 +1,67 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+// not used??
+exit;
+
+require_once '../inc/global.inc.php';
+
+$allow = api_get_configuration_value('extra');
+if (empty($allow)) {
+    exit;
+}
+
+Display::display_header($nameTools, "Tracking");
+
+foreach ($_POST as $index => $valeur) {
+    $$index = Database::escape_string(trim($valeur));
+}
+
+?>
+<form action="upgrade_school_calendar.php" method="post" name="upgrade_cal">
+    <th colspan="6">
+        <?php echo get_lang('edit_save'); ?>
+    </th>
+    <tr>
+        </th>
+    </tr>
+    <?php
+
+    echo "<table border='1'><tr>";
+
+    if ($i % $nbcol == 0) {
+        $sqlexam = "SELECT * FROM set_module
+                    WHERE cal_name =  '$d_title'";
+    }
+
+    $resultexam = Database::query($sqlexam);
+    while ($a_exam = Database::fetch_array($resultexam)) {
+        $name = $a_exam['cal_name'];
+        $id = $a_exam['id'];
+        $num = $a_exam['cal_day_num'];
+        $c_date = $a_exam['cal_date'];
+        echo "
+            <td><input type=text  name=d_cal_date size=8 value=".$c_date."></td>
+            <td><input type=text name=d_number size=5 value=".$num."></td>
+            <td><input type=text  name=d_title size=8 value=".$name."></td>
+            <td><input  name=d_id size=8 value=".$id."></td>";
+        if ($i % $nbcol == ($nbcol - 1)) {
+            echo "</tr>";
+        }
+    }
+
+    $nb = count($d_number);
+    $nbcol = 2;
+    ?>
+    </td>
+    </tr>
+    <input type=hidden name=aaa value=<?= serialize(Database::fetch_array($resultexam)); ?>/>
+    <input type="submit" value="Sauvegarder" name="B1">
+    <?php
+    echo $id, $tableau;
+    ?>
+</form>
+</table>
+<?php
+
+Display::display_footer();

+ 28 - 0
main/extra/update_exam.php

@@ -0,0 +1,28 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+require_once '../inc/global.inc.php';
+
+$allow = api_get_configuration_value('extra');
+if (empty($allow)) {
+    exit;
+}
+
+$tbl_stats_exercices = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
+
+$ex_idd = isset($_POST['exe_id']) ? (int) $_POST['exe_id'] : '';
+$ex_user_id = isset($_POST['ex_user_id']) ? (int) $_POST['ex_user_id'] : '';
+$mod_no = isset($_POST['mod_no']) ? Database::escape_string($_POST['mod_no']) : '';
+$score_ex = isset($_POST['score_ex']) ? Database::escape_string($_POST['score_ex']) : '';
+$score_rep1 = isset($_POST['score_rep1']) ? Database::escape_string($_POST['score_rep1']) : '';
+$score_rep2 = isset($_POST['score_rep2']) ? Database::escape_string($_POST['score_rep2']) : '';
+$coment = isset($_POST['coment']) ? Database::escape_string($_POST['coment']) : '';
+$student_id = isset($_POST['student_id']) ? Database::escape_string($_POST['student_id']) : '';
+
+$sql = "UPDATE $tbl_stats_exercices SET 
+          mod_no='$mod_no', score_ex='$score_ex', score_rep1='$score_rep1', score_rep2='$score_rep2', coment='$coment'
+		WHERE exe_id = '$ex_idd'
+    ";
+Database::query($sql);
+header("location:../extra/myStudents.php?student=$student_id");
+exit;

+ 18 - 0
main/extra/update_intervention.php

@@ -0,0 +1,18 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+require_once '../inc/global.inc.php';
+
+$allow = api_get_configuration_value('extra');
+if (empty($allow)) {
+    exit;
+}
+
+$table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
+$ex_id = isset($_POST['exe_id']) ? (int) $_POST['exe_id'] : '';
+$student_id = isset($_POST['student_id']) ? (int) $_POST['student_id'] : '';
+$inter_coment = isset($_POST['inter_coment']) ? Database::escape_string($_POST['inter_coment']) : '';
+$sql = "UPDATE $table SET inter_coment='$inter_coment' WHERE exe_id = $ex_id";
+Database::query($sql);
+header("location:../extra/myStudents.php?student=$student_id");
+exit;

+ 33 - 0
main/extra/upgrade_school_calendar.php

@@ -0,0 +1,33 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+// not used??
+exit;
+
+require_once '../inc/global.inc.php';
+
+$allow = api_get_configuration_value('extra');
+if (empty($allow)) {
+    exit;
+}
+
+Display::display_header($nameTools, "Tracking");
+
+foreach ($_POST as $x) {
+    echo "$x <br />";
+}
+
+foreach ($_POST as $index => $valeur) {
+    $$index = Database::escape_string(trim($valeur));
+}
+
+?>
+<?php echo get_lang('edit_save'); ?>
+<?php
+$d_id = (int) $d_id;
+$d_number = (int) $d_number;
+$sql4 = "UPDATE set_module SET cal_day_num = $d_number WHERE id = $d_id ";
+Database::query($sql4);
+print_r(unserialize(Security::remove_XSS($_POST['aaa'])));
+
+Display::display_footer();

+ 456 - 0
main/extra/userInfo.php

@@ -0,0 +1,456 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+require_once '../inc/global.inc.php';
+require_once 'userInfoLib.php';
+
+$allow = api_get_configuration_value('extra');
+if (empty($allow)) {
+    exit;
+}
+
+$TABLECALHORAIRE = Database :: get_course_table(cal_horaire);
+$htmlHeadXtra[] = '<script>
+function show_image(image,width,height) {
+	width = parseInt(width) + 20;
+	height = parseInt(height) + 20;
+	window_x = window.open(image,\'windowX\',\'width=\'+ width + \', height=\'+ height + \'\');
+}
+</script>';
+
+$editMainUserInfo = Security::remove_XSS($_REQUEST['editMainUserInfo']);
+$uInfo = $editMainUserInfo;
+$this_section = SECTION_COURSES;
+
+$nameTools = get_lang('Users');
+api_protect_course_script(true);
+$tool_info = api_get_tool_information_by_name(TOOL_USER);
+
+if (api_is_anonymous()) {
+    api_not_allowed(true);
+}
+
+//prepare variables used in userInfoLib.php functions
+$TBL_USERINFO_DEF = Database:: get_course_table(TABLE_USER_INFO_DEF);
+$TBL_USERINFO_CONTENT = Database:: get_course_table(TABLE_USER_INFO_CONTENT);
+
+if ($tool_info['visibility'] == 1) {
+    $interbreadcrumb[] = ['url' => 'user.php', 'name' => get_lang('Users')];
+}
+
+if ($origin != 'learnpath') { //so we are not in learnpath tool
+    Display :: display_header($nameTools, "User");
+    $origin = Security::remove_XSS($_GET['origin']);
+} else {
+    ?> <link rel="stylesheet" type="text/css" href="<?php echo api_get_path(WEB_CODE_PATH); ?>css/default.css" /> <?php
+}
+
+$currentCourse = api_get_course_id();
+$current_session_id = api_get_session_id();
+/*
+ * data  found  in settings  are :
+ *	$uid
+ *	$isAdmin
+ *	$isAdminOfCourse
+ *	$_configuration['main_database']
+ *	$currentCourseID
+ */
+
+$userIdViewed = Security::remove_XSS($_REQUEST['uInfo']);
+
+/**
+ * Connection layer between Chamilo and the current script.
+ */
+$courseCode = api_get_course_id();
+$tbl_coursUser = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
+$userIdViewer = api_get_user_id(); // id fo the user currently online
+$allowedToEditContent = ($userIdViewer == $userIdViewed) || $is_platformAdmin;
+$allowedToEditDef = api_is_allowed_to_edit(null, true);
+$is_allowedToTrack = api_is_allowed_to_edit(null, true);
+$displayMode = "viewContentList";
+$removeDef = Security::remove_XSS($_GET['removeDef']);
+$editDef = Security::remove_XSS($_GET['editDef']);
+$moveUpDef = Security::remove_XSS($_GET['moveUpDef']);
+$moveDownDef = Security::remove_XSS($_GET['moveDownDef']);
+
+if ($allowedToEditDef) {
+    if (!empty($_POST['submitDef'])) {
+        if (!empty($_POST['id'])) {
+            edit_cat_def($_POST['id'], $_POST['title'], $_POST['comment'], $_POST['nbline']);
+        } else {
+            create_cat_def($_POST['title'], $_POST['comment'], $_POST['nbline']);
+        }
+        $displayMode = "viewDefList";
+    } elseif (!empty($_GET['removeDef'])) {
+        remove_cat_def($_GET['removeDef'], true);
+        $displayMode = "viewDefList";
+    } elseif (!empty($_GET['editDef'])) {
+        $displayMode = "viewDefEdit";
+    } elseif (!empty($_POST['addDef'])) {
+        $displayMode = "viewDefEdit";
+    } elseif (!empty($_GET['moveUpDef'])) {
+        move_cat_rank($_GET['moveUpDef'], "up");
+        $displayMode = "viewDefList";
+    } elseif (!empty($_GET['moveDownDef'])) {
+        move_cat_rank($_GET['moveDownDef'], "down");
+        $displayMode = "viewDefList";
+    } elseif (!empty($_POST['viewDefList'])) {
+        $displayMode = "viewDefList";
+    } elseif (!empty($_GET['editMainUserInfo'])) {
+        $userIdViewed = strval(intval($_GET['editMainUserInfo']));
+        $displayMode = "viewMainInfoEdit";
+    } elseif (!empty($_REQUEST['submitMainUserInfo'])) {
+        $userIdViewed = strval(intval($_REQUEST['submitMainUserInfo']));
+        if ($current_session_id) {
+        } else {
+            if (!empty($_POST['promoteCourseAdmin']) && $_POST['promoteCourseAdmin']) {
+                $userProperties['status'] = 1;
+            } else {
+                $userProperties['status'] = 5;
+            }
+            if (!empty($_POST['promoteTutor']) && $_POST['promoteTutor']) {
+                $userProperties['tutor'] = 1;
+            } else {
+                $userProperties['tutor'] = 0;
+            }
+            $userhoraire_name = $_POST['hor_name'];
+            $course_id = $_course['real_id'];
+            update_user_course_properties($userIdViewed, $courseCode, $userProperties, $userhoraire_name, $course_id);
+        }
+        $displayMode = "viewContentList";
+    }
+}
+
+if ($allowedToEditContent) {
+    if (isset($_POST['submitContent'])) {
+        if ($_POST['cntId']) {
+            // submit a content change
+            edit_cat_content($_POST['catId'], $userIdViewed, $_POST['content'], $_SERVER['REMOTE_ADDR']);
+        } else {
+            // submit a totally new content
+            fill_new_cat_content($_POST['catId'], $userIdViewed, $_POST['content'], $_SERVER['REMOTE_ADDR']);
+        }
+        $displayMode = "viewContentList";
+    } elseif (!empty($_GET['editContent'])) {
+        $displayMode = "viewContentEdit";
+        $userIdViewed = $userIdViewed;
+    }
+}
+if (api_is_allowed_to_edit(null, true)) {
+    echo '<div class="actions">';
+    if ($origin == 'users') {
+        echo '<a href="user.php?'.api_get_cidreq().'&origin='.$origin.'">'.
+            Display::return_icon('back.png', get_lang('BackUser'), '', ICON_SIZE_MEDIUM).'</a>';
+    } else {
+        echo '<a href="javascript:history.back(1)">'.
+            Display::return_icon('back.png', get_lang('Back'), '', ICON_SIZE_MEDIUM).'</a>';
+    }
+
+    if (!is_numeric($_GET['editMainUserInfo'])) {
+        if (api_get_setting('allow_user_course_subscription_by_course_admin') == 'true') {
+            echo '<a href="userInfo.php?'.api_get_cidreq(
+                ).'&origin='.$origin.'&editMainUserInfo='.$userIdViewed.'">'.
+                Display::return_icon('edit.png', get_lang('EditUser'), '', ICON_SIZE_MEDIUM).get_lang(
+                    'EditUser'
+                ).'</a>';
+        }
+    } else {
+        if (api_get_setting('allow_user_course_subscription_by_course_admin') == 'true') {
+            echo '<a href="userInfo.php?'.api_get_cidreq().'&origin='.$origin.'&uInfo='.$userIdViewed.'">'.
+                Display::return_icon(
+                    'user.png',
+                    get_lang('ViewUser'),
+                    '',
+                    ICON_SIZE_MEDIUM
+                ).get_lang('ViewUser').'</a>';
+        }
+    }
+    echo '<a href="../mySpace/myStudents.php?'.api_get_cidreq().'&origin=user_course&student='.$userIdViewed.'&details=true&course='.$_course['id'].'">'.Display::return_icon('stats.png', get_lang('UserStatistics'), '', ICON_SIZE_MEDIUM).get_lang('UserStatistics').'</a>';
+    echo '</div>';
+} else {
+    if ($tool_info['visibility'] == 1) {
+        echo '<div class="actions">';
+        if ($origin == 'users') {
+            echo '<a href="user.php?'.api_get_cidreq().'&origin='.$origin.'">'.
+                Display::return_icon(
+                    'back.png',
+                    get_lang('BackUser'),
+                    '',
+                    ICON_SIZE_MEDIUM
+                ).'</a>';
+        } else {
+            echo '<a href="javascript:history.back(1)">'.Display::return_icon(
+                    'back.png',
+                    get_lang('Back'),
+                    '',
+                    ICON_SIZE_MEDIUM
+                ).'</a>';
+        }
+        echo '</div>';
+    }
+}
+
+// get information about user id viewed
+$user_info_viewed = api_get_user_info($userIdViewed);
+$is_session_course_coach = UserManager::is_session_course_coach(
+    $userIdViewed,
+    $_course['sysCode'],
+    $current_session_id
+);
+
+if ($displayMode == "viewDefEdit") {
+    /* CATEGORIES DEFINITIONS : EDIT */
+    $catToEdit = get_cat_def($_GET['editDef']);
+    $edit_heading_form = new FormValidator('edit_heading_form');
+    $edit_heading_form->addElement('hidden', 'id');
+    $edit_heading_form->add_textfield('title', get_lang('Title'));
+    $edit_heading_form->addElement('textarea', 'comment', get_lang('Comment'), ['cols' => 60, 'rows' => 4]);
+    $possible_line_nrs[1] = '1 '.get_lang('Line');
+    $possible_line_nrs[3] = '3 '.get_lang('Lines');
+    $possible_line_nrs[5] = '5 '.get_lang('Lines');
+    $possible_line_nrs[10] = '10 '.get_lang('Lines');
+    $possible_line_nrs[15] = '15 '.get_lang('Lines');
+    $edit_heading_form->addElement('select', 'nbline', get_lang('LineNumber'), $possible_line_nrs);
+    $edit_heading_form->addElement('submit', 'submitDef', get_lang('Ok'));
+    $edit_heading_form->setDefaults($catToEdit);
+    $edit_heading_form->display();
+} elseif ($displayMode == "viewDefList") {
+    $catList = get_cat_def_list();
+    if ($catList) {
+        foreach ($catList as $thisCat) {
+            // displays Title and comments
+            echo "<p>", "<b>".htmlize($thisCat['title'])."</b><br>\n", "<i>".htmlize($thisCat['comment'])."</i>\n", "</p>";
+            // displays lines
+            echo "<blockquote>\n", "<font color=\"gray\">\n";
+            for ($i = 1; $i <= $thisCat['nbline']; $i++) {
+                echo "<br>__________________________________________\n";
+            }
+            echo "</font>\n", "</blockquote>\n";
+            // displays commands
+            echo "<a href=\"".api_get_self()."?".api_get_cidreq()."&removeDef=", $thisCat['catId'], "\">", "<img src=\"../img/delete.gif\" border=\"0\" alt=\"".get_lang('Remove')."\" onclick=\"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES, $charset))."')) return false;\">", "</a>", "<a href=\"".api_get_self()."?".api_get_cidreq()."&editDef=", $thisCat['catId'], "\">", "<img src=\"../img/edit.gif\" border=\"0\" alt=\"".get_lang('Edit')."\" />", "</a>", "<a href=\"".api_get_self()."?".api_get_cidreq()."&moveUpDef=", $thisCat['catId'], "\">", "<img src=\"../img/up.gif\" border=\"0\" alt=\"".get_lang('MoveUp')."\">", "</a>", "<a href=\"".api_get_self()."?".api_get_cidreq()."&moveDownDef=", $thisCat['catId'], "\">", "<img src=\"../img/down.gif\" border=\"0\" alt=\"".get_lang('MoveDown')."\">", "</a>\n";
+        } // end for each
+    } // end if ($catList)
+
+    echo "<center>\n",
+        "<form method=\"post\" action=\"".api_get_self()."\">",
+        "<input type=\"submit\" name=\"addDef\" class=\"plus\" value=\"".get_lang('AddNewHeading')."\" />",
+    "</form>\n",
+    "<center>\n";
+} elseif ($displayMode == 'viewContentEdit') {
+    /* CATEGORIES CONTENTS : EDIT */
+    $catToEdit = get_cat_content($userIdViewed, $_GET['editContent']);
+    $content_heading_form = new FormValidator('content_heading_form');
+    $content_heading_form->addElement('hidden', 'cntId');
+    $content_heading_form->addElement('hidden', 'catId');
+    $content_heading_form->addElement('hidden', 'uInfo');
+    $content_heading_form->addElement('static', null, $catToEdit['title'], htmlize($catToEdit['comment']));
+    if ($catToEdit['nbline'] == 1) {
+        $content_heading_form->addElement('text', 'content', null, ['size' => 80]);
+    } else {
+        $content_heading_form->addElement(
+            'textarea',
+            'content',
+            null,
+            ['cols' => 60, 'rows' => $catToEdit['nbline']]
+        );
+    }
+    $content_heading_form->addElement('submit', 'submitContent', get_lang('Ok'));
+    $defaults = $catToEdit;
+    $defaults['cntId'] = $catToEdit['contentId'];
+    $defaults['uInfo'] = $userIdViewed;
+    $content_heading_form->setDefaults($defaults);
+    $content_heading_form->display();
+} elseif ($displayMode == "viewMainInfoEdit") {
+    $mainUserInfo = api_get_user_info($userIdViewed);
+    if ($mainUserInfo) {
+        ($mainUserInfo['status'] == COURSEMANAGER) ? $courseAdminChecked = "checked" : $courseAdminChecked = "";
+        $image_array = UserManager::get_user_picture_path_by_id($userIdViewed, 'web', false, true);
+        // get the path,width and height from original picture
+        $big_image = $image_array['dir'].'big_'.$image_array['file'];
+        $big_image_size = api_getimagesize($big_image);
+        $big_image_width = $big_image_size['width'];
+        $big_image_height = $big_image_size['height'];
+        $url_big_image = $big_image.'?rnd='.time();
+
+        if ($image_array['file'] == 'unknown.jpg') {
+            echo '<img src="'.$image_array['dir'].$image_array['file'].'" border="1">';
+        } else {
+            echo '<input type="image" src="'.$image_array['dir'].$image_array['file'].'" onclick="return show_image(\''.$url_big_image.'\',\''.$big_image_width.'\',\''.$big_image_height.'\');"/>';
+        }
+
+        echo "<form action=\"".api_get_self()."\" method=\"post\">\n",
+            "<input type=\"hidden\" name=\"submitMainUserInfo\" value=\"$userIdViewed\" />\n",
+            "<table width=\"80%\" border=\"0\">",
+            "<tr align=\"center\" bgcolor=\"#E6E6E6\">\n",
+            "<td align=\"left\">", get_lang('Name'), "</td>\n",
+            "<td width=\"100px\" align=\"left\">", get_lang('Schedule'), "</td>\n";
+        echo "</tr>\n",
+            "<tr align=\"center\">",
+            "<td align=\"left\"><b>", htmlize(api_get_person_name($mainUserInfo['firstName'], $mainUserInfo['lastName'])), "</b></td>\n",
+         "<td align=\"left\"><b>", $mainUserInfo['official_code'], "</td>";
+        //récupérer horaire de l'élève
+        $course_id = $_course['real_id']; ?>
+        <SELECT NAME='hor_name'>
+            <OPTION VALUE='<?php echo $mainUserInfo['official_code']; ?>'><?php echo get_lang('select_calendar_student'); ?></OPTION>
+            <?php
+            $sql = "SELECT distinct name FROM $TABLECALHORAIRE
+            where c_id = $course_id ";
+        $result2 = Database::query($sql);
+        while ($row = Database::fetch_array($result2)) {
+            $horaire_name = $row["name"]; ?>
+                    <OPTION VALUE='<?php echo $horaire_name; ?>'><?php echo "$horaire_name "; ?></OPTION>
+            <?php
+        } ?>
+        </SELECT>
+         <?php
+         echo'<p></p>  ';
+        if (!($is_courseAdmin && $_user['user_id'] == $userIdViewed)) {
+        } else {
+            echo "<td>", get_lang('CourseManager'), "</td>\n";
+        }
+        echo "<td><button class=\"save\" type=\"submit\" name=\"submit\">".get_lang('SaveChanges')."</button></td>\n", "</tr>", "</table>", "</form>\n";
+        if (api_get_setting('show_email_addresses') == 'true') {
+            echo "<p>".Display:: encrypted_mailto_link($mainUserInfo['email'], $mainUserInfo['email'])."</p>";
+        }
+
+        if (api_get_setting('extended_profile') == 'true') {
+            if (!empty($mainUserInfo['competences'])) {
+                echo '<div style="margin-top:10px;" class="actions-message"><strong>'.get_lang('MyCompetences').'</strong></div><div>'.$mainUserInfo['competences'].'</div>';
+            }
+            if (!empty($mainUserInfo['diplomas'])) {
+                echo '<div style="margin-top:10px;" class="actions-message"><strong>'.get_lang('MyDiplomas').'</strong></div><div>'.$mainUserInfo['diplomas'].'</div>';
+            }
+            if (!empty($mainUserInfo['teach'])) {
+                echo '<div style="margin-top:10px;" class="actions-message"><strong>'.get_lang('MyTeach').'</strong></div><div>'.$mainUserInfo['teach'].'</div>';
+            }
+            if (!empty($mainUserInfo['openarea'])) {
+                echo '<div style="margin-top:10px;" class="actions-message"><strong>'.get_lang('MyPersonalOpenArea').'</strong></div><div>'.$mainUserInfo['openarea'].'</div>';
+            }
+            if (!empty($mainUserInfo['competences'])) {
+                echo '<div style="margin-top:10px;" class="actions-message"><strong>'.get_lang('MyProductions').'</strong></div><div>'.UserManager::build_production_list($mainUserInfo['user_id']).'</div>';
+            }
+        }
+    } else {
+        Display :: display_normal_message(get_lang('ThisStudentIsSubscribeThroughASession'));
+    }
+} elseif ($displayMode == "viewContentList") {
+    // default display
+    $virtual_course_code = $_GET["virtual_course"];
+    if (isset($virtual_course_code)) {
+        $courseCode = $virtual_course_code;
+        $allowedToEditDef = false;
+    }
+    $mainUserInfo = api_get_user_info($userIdViewed);
+    if ($mainUserInfo) {
+        $image_array = UserManager::get_user_picture_path_by_id($userIdViewed, 'web', false, true);
+        // get the path,width and height from original picture
+        $big_image = $image_array['dir'].'big_'.$image_array['file'];
+        $big_image_size = api_getimagesize($big_image);
+        $big_image_width = $big_image_size['width'];
+        $big_image_height = $big_image_size['height'];
+        $url_big_image = $big_image.'?rnd='.time();
+
+        if ($image_array['file'] == 'unknown.jpg') {
+            echo '<img src="'.$image_array['dir'].$image_array['file'].'" border="1">';
+        } else {
+            echo '<input type="image" src="'.$image_array['dir'].$image_array['file'].'" onclick="return show_image(\''.$url_big_image.'\',\''.$big_image_width.'\',\''.$big_image_height.'\');"/>';
+        }
+
+        // is the user online?
+        $online = '';
+        if (user_is_online($userIdViewed)) {
+            $online = Display::return_icon('online.gif', get_lang('OnLine'), ['style' => 'with="8"; height="8"']);
+        }
+
+        // DISPLAY TABLE HEADING
+        if ($origin == 'learnpath') {
+            $allowedToEditDef = false;
+            $is_allowedToTrack = false;
+        }
+
+        echo "<table width=\"80%\" border=\"0\">",
+        "<tr align=\"center\" bgcolor=\"#E6E6E6\">\n",
+            "<td align=\"left\">".get_lang('Name')."</td>\n",
+                "<td width=\"20%\" align=\"left\">".get_lang('Description')."</td>\n",
+         "<td width=\"100px\" align=\"left\">", get_lang('OfficialCode'), "</td>\n";
+
+        echo "</tr>\n",
+        "<tr align=\"center\">\n",
+            "<td  align=\"left\"><b>".$online.' '.htmlize(api_get_person_name($mainUserInfo['firstName'], $mainUserInfo['lastName']))."</b></td>\n",
+        "<td align=\"left\"><b>", $mainUserInfo['official_code'], "</td>";
+        // DISPLAY TABLE CONTENT
+        if ($current_session_id) {
+            if ($user_info_viewed['status'] == COURSEMANAGER) {
+                echo "<td> - </td>\n";
+            }
+        } else {
+            if ($user_info_viewed['status'] == STUDENT) {
+                echo "<td> - </td>\n";
+            } else {
+                echo "<td> - </td>\n";
+            }
+        }
+
+        echo "</tr></table>";
+        if (api_get_setting("show_email_addresses") == "true") {
+            echo "<p>".Display::encrypted_mailto_link($mainUserInfo['email'], $mainUserInfo['email'])."</p>";
+        }
+
+        if (api_get_setting('extended_profile') == 'true') {
+            if (!empty($mainUserInfo['competences'])) {
+                echo '<div style="margin-top:10px;" class="actions-message"><strong>'.get_lang('MyCompetences').'</strong></div><div>'.$mainUserInfo['competences'].'</div>';
+            }
+            if (!empty($mainUserInfo['diplomas'])) {
+                echo '<div style="margin-top:10px;" class="actions-message"><strong>'.get_lang('MyDiplomas').'</strong></div><div>'.$mainUserInfo['diplomas'].'</div>';
+            }
+            if (!empty($mainUserInfo['teach'])) {
+                echo '<div style="margin-top:10px;" class="actions-message"><strong>'.get_lang('MyTeach').'</strong></div><div>'.$mainUserInfo['teach'].'</div>';
+            }
+            if (!empty($mainUserInfo['openarea'])) {
+                echo '<div style="margin-top:10px;" class="actions-message"><strong>'.get_lang('MyPersonalOpenArea').'</strong></div><div>'.$mainUserInfo['openarea'].'</div>';
+            }
+            if (!empty($mainUserInfo['competences'])) {
+                echo '<div style="margin-top:10px;" class="actions-message"><strong>'.get_lang('MyProductions').'</strong></div><div>'.UserManager::build_production_list($mainUserInfo['user_id']).'</div>';
+            }
+        }
+    } else {
+        Display::return_message(get_lang('ThisStudentIsSubscribeThroughASession'), 'normal');
+    }
+
+    if (api_get_setting('allow_user_headings') == 'true' && $allowedToEditDef) {
+        // only course administrators see this line
+        echo "<div align=right>",
+            "<form method=\"post\" action=\"".api_get_self()."\">",
+        get_lang('CourseAdministratorOnly')," : ",
+            "<input type=\"submit\" class=\"save\" name=\"viewDefList\" value=\"".get_lang('DefineHeadings')."\" />",
+        "</form>",
+        "<hr noshade size=\"1\" style=\"color:#99CCFF\">",
+        "</div>\n";
+    }
+
+    $catList = get_course_user_info($userIdViewed);
+    if ($catList) {
+        foreach ($catList as $thisCat) {
+            // Category title
+            echo "<p><b>", $thisCat['title'], "</b></p>\n";
+            // Category content
+            echo "<blockquote>\n";
+            if ($thisCat['content']) {
+                echo htmlize($thisCat['content'])."\n";
+            } else {
+                echo "....";
+            }
+            // Edit command
+            if ($allowedToEditContent) {
+                echo "<br /><br />\n",
+                    "<a href=\"".api_get_self()."?".api_get_cidreq(
+                    )."&editContent=", $thisCat['catId'], "&uInfo=", $userIdViewed, "\">",
+                "<img src=\"../img/edit.gif\" border=\"0\" alt=\"edit\">",
+                "</a>\n";
+            }
+            echo "</blockquote>\n";
+        }
+    }
+}
+
+Display::display_footer();

+ 614 - 0
main/extra/userInfoLib.php

@@ -0,0 +1,614 @@
+<?php
+/* For licensing terms, see /license.txt*/
+
+/**
+ * create a new category definition for the user information.
+ *
+ * @author - Hugues peeters <peeters@ipm.ucl.ac.be>
+ * @author - Christophe Gesch� <gesche@ipm.ucl.ac.be>
+ *
+ * @param string $title   - category title
+ * @param string $comment - title comment
+ * @param int    $nbline  - lines number for the field the user will fill
+ *
+ * @return bool true if succeed, else bolean false
+ */
+function create_cat_def($title = "", $comment = "", $nbline = "5")
+{
+    global $TBL_USERINFO_DEF; //taken from userInfo.php
+
+    $title = Database::escape_string(trim($title));
+    $comment = Database::escape_string(trim($comment));
+    $nbline = strval(intval($nbline));
+
+    if (0 == (int) $nbline || empty($title)) {
+        return false;
+    }
+
+    $sql = "SELECT MAX(rank) as maxRank FROM ".$TBL_USERINFO_DEF;
+    $result = Database::query($sql);
+    if ($result) {
+        $maxRank = Database::fetch_array($result);
+    }
+
+    $maxRank = $maxRank['maxRank'];
+    $thisRank = $maxRank + 1;
+
+    $sql = "INSERT INTO $TBL_USERINFO_DEF SET
+            title       = '$title',
+            comment     = '$comment',
+            line_count  = '$nbline',
+            rank        = '$thisRank'";
+
+    Database::query($sql);
+
+    return true;
+}
+
+/**
+ * modify the definition of a user information category.
+ *
+ * @author - Hugues peeters <peeters@ipm.ucl.ac.be>
+ * @author - Christophe Gesch� <gesche@ipm.ucl.ac.be>
+ *
+ * @param int    $id      - id of the category
+ * @param string $title   - category title
+ * @param string $comment - title comment
+ * @param int    $nbline  - lines number for the field the user will fill
+ *
+ * @return - boolean true if succeed, else otherwise
+ */
+function edit_cat_def($id, $title, $comment, $nbline)
+{
+    global $TBL_USERINFO_DEF;
+
+    if (0 == $nbline || 0 == $id) {
+        return false;
+    }
+    $id = strval(intval($id)); //make sure id is integer
+    $title = Database::escape_string(trim($title));
+    $comment = Database::escape_string(trim($comment));
+    $nbline = strval(intval($nbline));
+
+    $sql = "UPDATE $TBL_USERINFO_DEF SET
+            title       = '$title',
+            comment     = '$comment',
+            line_count  = '$nbline'
+            WHERE id    = '$id'";
+    Database::query($sql);
+
+    return true;
+}
+
+/**
+ * remove a category from the category list.
+ *
+ * @author - Hugues peeters <peeters@ipm.ucl.ac.be>
+ * @author - Christophe Gesche <gesche@ipm.ucl.ac.be>
+ *
+ * @param int  $id     - id of the category
+ *                     or "ALL" for all category
+ * @param bool $force  - FALSE (default) : prevents removal if users have
+ *                     already fill this category
+ *                     TRUE : bypass user content existence check
+ * @param int  $nbline - lines number for the field the user will fill
+ *
+ * @return bool - TRUE if succeed, ELSE otherwise
+ */
+function remove_cat_def($id, $force = false)
+{
+    $TBL_USERINFO_DEF = Database:: get_course_table(TABLE_USER_INFO_DEF);
+    $TBL_USERINFO_CONTENT = Database:: get_course_table(TABLE_USER_INFO_CONTENT);
+
+    $id = strval(intval($id));
+
+    if ((0 == (int) $id || $id == "ALL") || !is_bool($force)) {
+        return false;
+    }
+    $sqlCondition = " WHERE id = $id";
+    if (!$force) {
+        $sql = "SELECT * FROM $TBL_USERINFO_CONTENT $sqlCondition";
+        $result = Database::query($sql);
+
+        if (Database::num_rows($result) > 0) {
+            return false;
+        }
+    }
+    $sql = "DELETE FROM $TBL_USERINFO_DEF $sqlCondition";
+    Database::query($sql);
+}
+
+/**
+ * move a category in the category list.
+ *
+ * @author - Hugues peeters <peeters@ipm.ucl.ac.be>
+ * @author - Christophe Gesch� <gesche@ipm.ucl.ac.be>
+ *
+ * @param int    $id        - id of the category
+ * @param string $direction "up" or "down" :
+ *                          "up"    decrease the rank of gived $id by switching rank with the just lower
+ *                          "down"  increase the rank of gived $id by switching rank with the just upper
+ *
+ * @return bool true if succeed, else boolean false
+ */
+function move_cat_rank($id, $direction) // up & down.
+{
+    $TBL_USERINFO_DEF = Database:: get_course_table(userinfo_def);
+    $id = strval(intval($id));
+
+    if (0 == (int) $id || !($direction == "up" || $direction == "down")) {
+        return false;
+    }
+
+    $sql = "SELECT rank FROM $TBL_USERINFO_DEF WHERE id = $id";
+    $result = Database::query($sql);
+
+    if (Database::num_rows($result) < 1) {
+        return false;
+    }
+
+    $cat = Database::fetch_array($result);
+    $rank = (int) $cat['rank'];
+
+    return move_cat_rank_by_rank($rank, $direction);
+}
+
+/**
+ * move a category in the category list.
+ *
+ * @author - Hugues peeters <peeters@ipm.ucl.ac.be>
+ * @author - Christophe Gesche <gesche@ipm.ucl.ac.be>
+ *
+ * @param int    $rank      - actual rank of the category
+ * @param string $direction "up" or "down" :
+ *                          "up"    decrease the rank of gived $rank by switching rank with the just lower
+ *                          "down"  increase the rank of gived $rank by switching rank with the just upper
+ *
+ * @return bool true if succeed, else boolean false
+ */
+function move_cat_rank_by_rank($rank, $direction) // up & down.
+{
+    $TBL_USERINFO_DEF = Database:: get_course_table(userinfo_def);
+
+    if (0 == (int) $rank || !($direction == "up" || $direction == "down")) {
+        return false;
+    }
+
+    if ($direction == "down") {
+        // thus increase rank ...
+        $sort = "ASC";
+        $compOp = ">=";
+    } else {
+        // thus decrease rank ...
+        $sort = "DESC";
+        $compOp = "<=";
+    }
+
+    // this request find the 2 line to be switched (on rank value)
+    $sql = "SELECT id, rank FROM $TBL_USERINFO_DEF 
+            WHERE rank $compOp $rank
+            ORDER BY rank $sort LIMIT 2";
+
+    $result = Database::query($sql);
+
+    if (Database::num_rows($result) < 2) {
+        return false;
+    }
+
+    $thisCat = Database::fetch_array($result);
+    $nextCat = Database::fetch_array($result);
+
+    $sql1 = "UPDATE $TBL_USERINFO_DEF SET rank ='".$nextCat['rank'].
+        "' WHERE id = '".$thisCat['id']."'";
+    $sql2 = "UPDATE $TBL_USERINFO_DEF SET rank ='".$thisCat['rank'].
+        "' WHERE id = '".$nextCat['id']."'";
+
+    Database::query($sql1);
+    Database::query($sql2);
+
+    return true;
+}
+
+/**
+ * @author Hugues Peeters - peeters@ipm.ucl.ac.be
+ *
+ * @param int    $user_id
+ * @param string $course_code
+ * @param array  $properties  - should contain 'role', 'status', 'tutor_id'
+ *
+ * @return bool true if succeed false otherwise
+ */
+function update_user_course_properties($user_id, $course_code, $properties, $horaire_name, $course_id)
+{
+    global $tbl_coursUser, $_user;
+    $sqlChangeStatus = "";
+    $user_id = (int) $user_id; //filter integer
+    $course_code = Database::escape_string($course_code);
+    $course_id = (int) $course_id;
+    $horaire_name = Database::escape_string($horaire_name);
+    $status = Database::escape_string($properties['status']);
+    $tutor = Database::escape_string($properties['tutor']);
+    if ($user_id != $_user['user_id']) {
+        $sqlChangeStatus = "status = '$status',";
+    }
+
+    $sql = "UPDATE $tbl_coursUser
+            SET $sqlChangeStatus 
+                is_tutor = '$tutor'
+            WHERE user_id = $user_id AND c_id = $course_id";
+    Database::query($sql);
+    //update official-code: Horaire
+    $table_user = Database::get_main_table(TABLE_MAIN_USER);
+    $sql2 = "UPDATE $table_user
+             SET official_code = '$horaire_name'
+             WHERE user_id = $user_id";
+    Database::query($sql2);
+    //on récupère l'horaire
+    $tbl_personal_agenda = Database:: get_main_table(TABLE_PERSONAL_AGENDA);
+    $TABLECALDATES = Database:: get_course_table(cal_dates);
+    $jour = 0;
+    $sql3 = "SELECT date FROM $TABLECALDATES 
+             WHERE 
+                horaire_name = '$horaire_name' AND 
+                status = 'C' AND    
+                c_id = $course_id 
+             ORDER BY date ";
+    $result3 = Database::query($sql3);
+
+    if (Database::num_rows($result3) == '0') {
+        return false;
+    }
+
+    //on efface ce qui est déjà inscrit
+    $sql4 = "DELETE FROM $tbl_personal_agenda
+         WHERE user = $user_id 
+         AND text = 'Pour le calendrier, ne pas effacer'";
+    Database::query($sql4);
+
+    $sql = "DELETE FROM $tbl_personal_agenda
+         WHERE user = $user_id AND title = 'Examen*'";
+    Database::query($sql);
+    //à chaque date dans l'horaire
+    while ($res3 = Database::fetch_array($result3)) {
+        $date = $res3['date'];
+        //on incrémente les jours de cours
+        $date = api_get_utc_datetime($date);
+        $jour = $jour + 1;
+        //on réinsère le nouvel horaire
+        $sql = "INSERT ".$tbl_personal_agenda." (user,title,text,date) 
+                VALUES ($user_id, $jour, 'Pour le calendrier, ne pas effacer', '$date')";
+        Database::query($sql);
+        // pour les inscrire examens dans agenda
+        $sql5 = "SELECT date FROM $TABLECALDATES 
+                  WHERE horaire_name = '$horaire_name' AND status = 'E'
+                  AND    c_id = '$course_id' 
+                  ORDER BY date 
+                  ";
+        $result5 = Database::query($sql5);
+    }
+
+    //à chaque date dans l'horaire
+    while ($res5 = Database::fetch_array($result5)) {
+        $date = $res5['date'];
+        $date = api_get_utc_datetime($date);
+        //on réinsère le nouvel horaire
+        $sql7 = "INSERT $tbl_personal_agenda (user, title, date) VALUES  ($user_id, 'Examen*', '$date')";
+        Database::query($sql7);
+    }
+}
+
+/**
+ * fill a bloc for information category.
+ *
+ * @author - Hugues peeters <peeters@ipm.ucl.ac.be>
+ * @author - Christophe Gesche <gesche@ipm.ucl.ac.be>
+ *
+ * @param $definition_id
+ * @param $user_id
+ * @param $user_ip
+ * @param $content
+ *
+ * @return bool true if succeed, else boolean false
+ */
+function fill_new_cat_content($definition_id, $user_id, $content = "", $user_ip = "")
+{
+    global $TBL_USERINFO_CONTENT;
+
+    if (empty($user_ip)) {
+        $user_ip = $_SERVER['REMOTE_ADDR'];
+    }
+    $definition_id = (int) $definition_id;
+    $user_id = (int) $user_id;
+    $content = Database::escape_string(trim($content));
+    $user_ip = Database::escape_string(trim($user_ip));
+
+    if (0 == $definition_id || 0 == $user_id || $content == "") {
+        // Here we should introduce an error handling system...
+
+        return false;
+    }
+
+    // Do not create if already exist
+    $sql = "SELECT id FROM $TBL_USERINFO_CONTENT
+            WHERE   definition_id   = '$definition_id'
+            AND     user_id         = $user_id";
+
+    $result = Database::query($sql);
+
+    if (Database::num_rows($result) > 0) {
+        return false;
+    }
+
+    $sql = "INSERT INTO $TBL_USERINFO_CONTENT SET
+            content         = '$content',
+            definition_id   = $definition_id,
+            user_id         = $user_id,
+            editor_ip       = '$user_ip',
+            edition_time    = now()";
+
+    Database::query($sql);
+
+    return true;
+}
+
+/**
+ * Edit a bloc for information category.
+ *
+ * @author - Hugues peeters <peeters@ipm.ucl.ac.be>
+ * @author - Christophe Gesche <gesche@ipm.ucl.ac.be>
+ *
+ * @param $definition_id
+ * @param $user_id
+ * @param $user_ip       DEFAULT $REMOTE_ADDR
+ * @param $content       if empty call delete the bloc
+ *
+ * @return bool true if succeed, else boolean false
+ */
+function edit_cat_content($definition_id, $user_id, $content = "", $user_ip = "")
+{
+    global $TBL_USERINFO_CONTENT;
+    $definition_id = (int) $definition_id;
+    $user_id = (int) $user_id;
+    $content = Database::escape_string(trim($content));
+    if (empty($user_ip)) {
+        $user_ip = $_SERVER['REMOTE_ADDR'];
+    }
+    $user_ip = Database::escape_string($user_ip);
+
+    if (0 == $user_id || 0 == $definition_id) {
+        return false;
+    }
+
+    if ($content == "") {
+        return cleanout_cat_content($user_id, $definition_id);
+    }
+
+    $sql = "UPDATE $TBL_USERINFO_CONTENT SET
+            content         = '$content',
+            editor_ip       = '$user_ip',
+            edition_time    = now()
+            WHERE definition_id = $definition_id AND user_id = $user_id";
+
+    Database::query($sql);
+
+    return true;
+}
+
+/**
+ * clean the content of a bloc for information category.
+ *
+ * @author Hugues peeters <peeters@ipm.ucl.ac.be>
+ * @author Christophe Gesche <gesche@ipm.ucl.ac.be>
+ *
+ * @param $definition_id
+ * @param $user_id
+ *
+ * @return bool true if succeed, else boolean false
+ */
+function cleanout_cat_content($user_id, $definition_id)
+{
+    global $TBL_USERINFO_CONTENT;
+    $user_id = (int) $user_id;
+    $definition_id = (int) $definition_id;
+
+    if (0 == $user_id || 0 == $definition_id) {
+        return false;
+    }
+
+    $sql = "DELETE FROM $TBL_USERINFO_CONTENT
+            WHERE user_id = $user_id AND definition_id = $definition_id";
+
+    Database::query($sql);
+
+    return true;
+}
+
+/**
+ * get the user info from the user id.
+ *
+ * @author - Hugues Peeters <peeters@ipm.ucl.ac.be>
+ * @author - Christophe Gesche <gesche@ipm.ucl.ac.be>
+ *
+ * @param int $user_id user id as stored in the Dokeos main db
+ *
+ * @return array containg user info sort by categories rank
+ *               each rank contains 'title', 'comment', 'content', 'cat_id'
+ */
+function get_course_user_info($user_id)
+{
+    $TBL_USERINFO_DEF = Database:: get_course_table(TABLE_USER_INFO_DEF);
+    $TBL_USERINFO_CONTENT = Database:: get_course_table(TABLE_USER_INFO_CONTENT);
+
+    $user_id = (int) $user_id;
+    $sql = "SELECT  cat.id catId,   cat.title,
+                    cat.comment ,   content.content
+            FROM    $TBL_USERINFO_DEF cat LEFT JOIN $TBL_USERINFO_CONTENT content
+            ON cat.id = content.definition_id AND content.user_id = $user_id
+            ORDER BY cat.rank, content.id";
+
+    $result = Database::query($sql);
+
+    if (Database::num_rows($result) > 0) {
+        while ($userInfo = Database::fetch_array($result, 'ASSOC')) {
+            $userInfos[] = $userInfo;
+        }
+
+        return $userInfos;
+    }
+
+    return false;
+}
+
+/**
+ * get the main user information.
+ *
+ * @author - Hugues Peeters <peeters@ipm.ucl.ac.be>
+ * @author - Christophe Gesche <gesche@ipm.ucl.ac.be>
+ *
+ * @param int $user_id user id as stored in the Dokeos main db
+ *
+ * @return array containing user info as 'lastName', 'firstName', 'email', 'role'
+ */
+function get_main_user_info($user_id, $courseCode)
+{
+    $user_id = (int) $user_id;
+    $courseCode = Database::escape_string($courseCode);
+    $courseId = api_get_course_int_id($courseCode);
+    if (0 == $user_id) {
+        return false;
+    }
+
+    $table_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
+    $table_user = Database::get_main_table(TABLE_MAIN_USER);
+    $sql = "SELECT  u.*, u.lastname lastName, u.firstname firstName,
+                    u.email, u.picture_uri picture,
+                    cu.status status, cu.is_tutor as tutor_id
+            FROM    $table_user u, $table_course_user cu
+            WHERE   u.user_id = cu.user_id AND cu.relation_type<>".COURSE_RELATION_TYPE_RRHH."
+            AND     u.user_id = $user_id
+            AND     cu.c_id = $courseId";
+
+    $result = Database::query($sql);
+
+    if (Database::num_rows($result) > 0) {
+        $userInfo = Database::fetch_array($result, 'ASSOC');
+        $userInfo['password'] = '';
+
+        return $userInfo;
+    }
+
+    return false;
+}
+
+/**
+ * get the user content of a categories plus the categories definition.
+ *
+ * @author - Hugues Peeters <peeters@ipm.ucl.ac.be>
+ * @author - Christophe Gesche <gesche@ipm.ucl.ac.be>
+ *
+ * @param int $userId id of the user
+ * @param int $catId  id of the categories
+ *
+ * @return array containing 'catId', 'title', 'comment', 'nbline', 'contentId' and 'content'
+ */
+function get_cat_content($userId, $catId)
+{
+    $TBL_USERINFO_DEF = Database:: get_course_table(TABLE_USER_INFO_DEF);
+    $TBL_USERINFO_CONTENT = Database:: get_course_table(TABLE_USER_INFO_CONTENT);
+
+    $userId = (int) $userId;
+    $catId = (int) $catId;
+    $sql = "SELECT  cat.id catId,   cat.title,
+                    cat.comment ,   cat.line_count,
+                    content.id contentId,   content.content
+            FROM    $TBL_USERINFO_DEF cat LEFT JOIN $TBL_USERINFO_CONTENT content
+            ON cat.id = content.definition_id
+            AND content.user_id = $userId
+            WHERE cat.id = $catId ";
+    $result = Database::query($sql);
+
+    if (Database::num_rows($result) > 0) {
+        $catContent = Database::fetch_array($result, 'ASSOC');
+        $catContent['nbline'] = $catContent['line_count'];
+
+        return $catContent;
+    }
+
+    return false;
+}
+
+/**
+ * get the definition of a category.
+ *
+ * @author Christophe Gesche <gesche@ipm.ucl.ac.be>
+ * @author Hugues Peeters <peeters@ipm.ucl.ac.be>
+ *
+ * @param int $catId - id of the categories
+ *
+ * @return array containing 'id', 'title', 'comment', and 'nbline',
+ */
+function get_cat_def($catId)
+{
+    $TBL_USERINFO_DEF = Database:: get_course_table(TABLE_USER_INFO_DEF);
+
+    $catId = (int) $catId;
+    $sql = "SELECT id, title, comment, line_count, rank FROM $TBL_USERINFO_DEF WHERE id = $catId";
+
+    $result = Database::query($sql);
+
+    if (Database::num_rows($result) > 0) {
+        $catDef = Database::fetch_array($result, 'ASSOC');
+        $catDef['nbline'] = $catDef['line_count'];
+
+        return $catDef;
+    }
+
+    return false;
+}
+
+/**
+ * get list of all this course categories.
+ *
+ * @author Christophe Gesche <gesche@ipm.ucl.ac.be>
+ * @author Hugues Peeters <peeters@ipm.ucl.ac.be>
+ *
+ * @return array containing a list of arrays.
+ *               And each of these arrays contains
+ *               'catId', 'title', 'comment', and 'nbline',
+ */
+function get_cat_def_list()
+{
+    $TBL_USERINFO_DEF = Database:: get_course_table(TABLE_USER_INFO_DEF);
+
+    $sql = "SELECT  id catId,   title,  comment , line_count
+            FROM  $TBL_USERINFO_DEF
+            ORDER BY rank";
+
+    $result = Database::query($sql);
+
+    if (Database::num_rows($result) > 0) {
+        while ($cat_def = Database::fetch_array($result, 'ASSOC')) {
+            $cat_def_list[] = $cat_def;
+        }
+
+        return $cat_def_list;
+    }
+
+    return false;
+}
+
+/**
+ * transform content in a html display.
+ *
+ * @author Hugues Peeters <peeters@ipm.ucl.ac.be>
+ *
+ * @param string $string string to htmlize
+ *
+ * @return string htmlized
+ */
+function htmlize($string)
+{
+    global $charset;
+
+    return nl2br(htmlspecialchars($string, ENT_QUOTES, $charset));
+}

+ 45 - 31
main/messages/new_message.php

@@ -23,7 +23,6 @@ if (api_get_setting('allow_message_tool') !== 'true') {
 }
 
 $allowSocial = api_get_setting('allow_social_tool') == 'true';
-
 $nameTools = api_xml_http_response_encode(get_lang('Messages'));
 
 $htmlHeadXtra[] = '<script>
@@ -52,24 +51,28 @@ function add_image_form() {
 </script>';
 $nameTools = get_lang('ComposeMessage');
 
+$tpl = new Template(get_lang('ComposeMessage'));
+
 /**
  * Shows the compose area + a list of users to select from.
  */
-function show_compose_to_any($user_id)
+function show_compose_to_any($tpl)
 {
     $default['user_list'] = 0;
-    $online_user_list = null;
-    $html = manageForm($default, $online_user_list);
+    $html = manageForm($default, null, null, $tpl);
 
     return $html;
 }
 
-function show_compose_reply_to_message($message_id, $receiver_id)
+function show_compose_reply_to_message($message_id, $receiver_id, $tpl)
 {
     $table = Database::get_main_table(TABLE_MESSAGE);
+    $receiver_id = (int) $receiver_id;
+    $message_id = (int) $message_id;
+
     $query = "SELECT user_sender_id
               FROM $table
-              WHERE user_receiver_id = ".intval($receiver_id)." AND id = ".intval($message_id);
+              WHERE user_receiver_id = ".$receiver_id." AND id = ".$message_id;
     $result = Database::query($query);
     $row = Database::fetch_array($result, 'ASSOC');
     $userInfo = api_get_user_info($row['user_sender_id']);
@@ -80,33 +83,34 @@ function show_compose_reply_to_message($message_id, $receiver_id)
     }
 
     $default['users'] = [$row['user_sender_id']];
-    $html = manageForm($default, null, $userInfo['complete_name_with_username']);
+    $html = manageForm($default, null, $userInfo['complete_name_with_username'], $tpl);
 
     return $html;
 }
 
-function show_compose_to_user($receiver_id)
+function show_compose_to_user($receiver_id, $tpl)
 {
     $userInfo = api_get_user_info($receiver_id);
     $html = get_lang('To').':&nbsp;<strong>'.$userInfo['complete_name'].'</strong>';
     $default['title'] = api_xml_http_response_encode(get_lang('EnterTitle'));
     $default['users'] = [$receiver_id];
-    $html .= manageForm($default);
+    $html .= manageForm($default, null, '', $tpl);
 
     return $html;
 }
 
 /**
- * @param $default
- * @param null   $select_from_user_list
- * @param string $sent_to
+ * @param          $default
+ * @param null     $select_from_user_list
+ * @param string   $sent_to
+ * @param Template $tpl
  *
  * @return string
  */
-function manageForm($default, $select_from_user_list = null, $sent_to = '')
+function manageForm($default, $select_from_user_list = null, $sent_to = '', $tpl = null)
 {
-    $group_id = isset($_REQUEST['group_id']) ? intval($_REQUEST['group_id']) : null;
-    $message_id = isset($_GET['message_id']) ? intval($_GET['message_id']) : null;
+    $group_id = isset($_REQUEST['group_id']) ? (int) $_REQUEST['group_id'] : null;
+    $message_id = isset($_GET['message_id']) ? (int) $_GET['message_id'] : null;
 
     $form = new FormValidator(
         'compose_message',
@@ -115,6 +119,7 @@ function manageForm($default, $select_from_user_list = null, $sent_to = '')
         null,
         ['enctype' => 'multipart/form-data']
     );
+
     if (empty($group_id)) {
         if (isset($select_from_user_list)) {
             $form->addText(
@@ -170,8 +175,8 @@ function manageForm($default, $select_from_user_list = null, $sent_to = '')
 
     if (isset($_GET['re_id'])) {
         $message_reply_info = MessageManager::get_message_by_id($_GET['re_id']);
-        $default['title'] = get_lang('MailSubjectReplyShort')." ".$message_reply_info['title'];
-        $form->addHidden('re_id', intval($_GET['re_id']));
+        $default['title'] = get_lang('MailSubjectReplyShort').' '.$message_reply_info['title'];
+        $form->addHidden('re_id', (int) $_GET['re_id']);
         $form->addHidden('save_form', 'save_form');
 
         // Adding reply mail
@@ -204,8 +209,7 @@ function manageForm($default, $select_from_user_list = null, $sent_to = '')
     }
 
     if (empty($group_id)) {
-        $form->addElement(
-            'label',
+        $form->addLabel(
             '',
             '<div id="file_uploads"><div id="filepath_1">
                 <div id="filepaths" class="form-horizontal">
@@ -221,13 +225,12 @@ function manageForm($default, $select_from_user_list = null, $sent_to = '')
                     </div>
                 </div>
             </div>
-            </div>
-            '
+            </div>'
         );
 
         $form->addLabel(
             '',
-            '<span id="link-more-attach"><a href="javascript://" onclick="return add_image_form()">'.
+            '<span id="link-more-attach"><a class="btn btn-default" href="javascript://" onclick="return add_image_form()">'.
             get_lang('AddOneMoreFile').'</a></span>&nbsp;('.
             sprintf(
                 get_lang('MaximunFileSizeX'),
@@ -236,6 +239,13 @@ function manageForm($default, $select_from_user_list = null, $sent_to = '')
         );
     }
 
+    $form->addLabel(
+        '',
+        '<iframe 
+            frameborder="0" height="200" width="100%" scrolling="no" 
+            src="'.api_get_path(WEB_CODE_PATH).'messages/record_audio.php"></iframe>'
+    );
+
     $form->addButtonSend(get_lang('SendMessage'), 'compose');
     $form->setRequiredNote('<span class="form_required">*</span> <small>'.get_lang('ThisFieldIsRequired').'</small>');
 
@@ -262,7 +272,7 @@ function manageForm($default, $select_from_user_list = null, $sent_to = '')
             $forwardId = isset($_POST['forward_id']) ? $_POST['forward_id'] : false;
 
             if (is_array($user_list) && count($user_list) > 0) {
-                //all is well, send the message
+                // All is well, send the message
                 foreach ($user_list as $userId) {
                     $res = MessageManager::send_message(
                         $userId,
@@ -276,7 +286,9 @@ function manageForm($default, $select_from_user_list = null, $sent_to = '')
                         0,
                         null,
                         false,
-                        $forwardId
+                        $forwardId,
+                        [],
+                        true
                     );
 
                     if ($res) {
@@ -288,6 +300,7 @@ function manageForm($default, $select_from_user_list = null, $sent_to = '')
                         ));
                     }
                 }
+                MessageManager::cleanAudioMessage();
             } else {
                 Display::addFlash(Display::return_message('ErrorSendingMessage', 'error'));
             }
@@ -369,12 +382,13 @@ if (!isset($_POST['compose'])) {
     if (isset($_GET['re_id'])) {
         $social_right_content .= show_compose_reply_to_message(
             $_GET['re_id'],
-            api_get_user_id()
+            api_get_user_id(),
+            $tpl
         );
     } elseif (isset($_GET['send_to_user'])) {
-        $social_right_content .= show_compose_to_user($_GET['send_to_user']);
+        $social_right_content .= show_compose_to_user($_GET['send_to_user'], $tpl);
     } else {
-        $social_right_content .= show_compose_to_any(api_get_user_id());
+        $social_right_content .= show_compose_to_any($tpl);
     }
 } else {
     $restrict = false;
@@ -391,19 +405,19 @@ if (!isset($_POST['compose'])) {
 
     // comes from a reply button
     if (isset($_GET['re_id']) || isset($_GET['forward_id'])) {
-        $social_right_content .= manageForm($default);
+        $social_right_content .= manageForm($default, null, null, $tpl);
     } else {
         // post
         if ($restrict) {
             if (!isset($_POST['group_id'])) {
                 $default['users'] = isset($_POST['users']) ? $_POST['users'] : null;
             } else {
-                $default['group_id'] = $_POST['group_id'];
+                $default['group_id'] = (int) $_POST['group_id'];
             }
             if (isset($_POST['hidden_user'])) {
                 $default['users'] = [$_POST['hidden_user']];
             }
-            $social_right_content .= manageForm($default);
+            $social_right_content .= manageForm($default, null, null, $tpl);
         } else {
             $social_right_content .= Display::return_message(get_lang('ErrorSendingMessage'), 'error');
         }
@@ -415,10 +429,10 @@ if ($allowSocial) {
     $social_right_content .= '</div>';
 }
 
-$tpl = new Template(get_lang('ComposeMessage'));
 // Block Social Avatar
 SocialManager::setSocialUserBlock($tpl, api_get_user_id(), 'messages');
 
+MessageManager::cleanAudioMessage();
 if ($allowSocial) {
     $tpl->assign('social_menu_block', $social_menu_block);
     $tpl->assign('social_right_content', $social_right_content);

+ 24 - 0
main/messages/record_audio.php

@@ -0,0 +1,24 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+require_once __DIR__.'/../inc/global.inc.php';
+
+api_block_anonymous_users();
+
+$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_JS_PATH).'rtc/RecordRTC.js"></script>';
+$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'wami-recorder/recorder.js"></script>';
+$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'wami-recorder/gui.js"></script>';
+$htmlHeadXtra[] = '<script type="text/javascript" src="'.api_get_path(WEB_LIBRARY_PATH).'swfobject/swfobject.js"></script>';
+$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'swfobject/swfobject.js"></script>';
+$htmlHeadXtra[] = api_get_js('record_audio/record_audio.js');
+
+$tpl = new Template(get_lang('ComposeMessage'), false, false, false, true);
+$record = $tpl->get_template('message/record_audio.tpl');
+
+$tpl->assign('user_id', api_get_user_id());
+$tpl->assign('audio_title', api_get_unique_id());
+$tpl->assign('reload_page', 0);
+$tpl->assign('content', $tpl->fetch($record));
+$tpl->display_no_layout_template();
+
+exit;

+ 2 - 2
main/messages/view_message.php

@@ -12,8 +12,8 @@ if (api_get_setting('allow_message_tool') != 'true') {
     api_not_allowed(true);
 }
 
-$allowSocial = api_get_setting('allow_social_tool') == 'true';
-$allowMessage = api_get_setting('allow_message_tool') == 'true';
+$allowSocial = api_get_setting('allow_social_tool') === 'true';
+$allowMessage = api_get_setting('allow_message_tool') === 'true';
 
 if ($allowSocial) {
     $this_section = SECTION_SOCIAL;

+ 3 - 4
main/mySpace/admin_view.php

@@ -16,7 +16,6 @@ $this_section = SECTION_TRACKING;
 
 $csv_content = [];
 $nameTools = get_lang('MySpace');
-
 $allowToTrack = api_is_platform_admin(true, true);
 
 if (!$allowToTrack) {
@@ -56,9 +55,9 @@ switch ($display) {
         MySpace::display_tracking_course_overview();
         break;
     case 'accessoverview':
-        $courseId = isset($_GET['course_id']) ? intval($_GET['course_id']) : 0;
-        $sessionId = isset($_GET['session_id']) ? intval($_GET['session_id']) : 0;
-        $studentId = isset($_GET['student_id']) ? intval($_GET['student_id']) : 0;
+        $courseId = isset($_GET['course_id']) ? (int) $_GET['course_id'] : 0;
+        $sessionId = isset($_GET['session_id']) ? (int) $_GET['session_id'] : 0;
+        $studentId = isset($_GET['student_id']) ? (int) $_GET['student_id'] : 0;
 
         MySpace::displayTrackingAccessOverView($courseId, $sessionId, $studentId);
         break;

+ 12 - 1
main/mySpace/course.php

@@ -268,7 +268,18 @@ function get_courses($from, $limit, $column, $direction)
         foreach ($courses as $data) {
             $courseCode = $data['code'];
             $courseInfo = api_get_course_info($courseCode);
-            $userList = CourseManager::get_user_list_from_course_code($data['code'], $sessionId);
+            if (empty($sessionId)) {
+                $userList = CourseManager::get_user_list_from_course_code($data['code']);
+            } else {
+                $userList = CourseManager::get_user_list_from_course_code(
+                    $data['code'],
+                    $sessionId,
+                    null,
+                    null,
+                    0
+                );
+            }
+
             $userIdList = [];
             if (!empty($userList)) {
                 foreach ($userList as $user) {

+ 26 - 8
main/mySpace/index.php

@@ -1,8 +1,6 @@
 <?php
 /* For licensing terms, see /license.txt */
 
-use ChamiloSession as Session;
-
 /**
  * Homepage for the MySpace directory.
  *
@@ -28,7 +26,7 @@ $export_csv = isset($_GET['export']) && $_GET['export'] == 'csv' ? true : false;
 $display = isset($_GET['display']) ? Security::remove_XSS($_GET['display']) : null;
 $csv_content = [];
 $user_id = api_get_user_id();
-$session_id = isset($_GET['session_id']) ? intval($_GET['session_id']) : 0;
+$session_id = isset($_GET['session_id']) ? (int) $_GET['session_id'] : 0;
 $is_coach = api_is_coach($session_id);
 $is_platform_admin = api_is_platform_admin();
 $is_drh = api_is_drh();
@@ -58,6 +56,9 @@ if (isset($_GET['view']) && in_array($_GET['view'], $views)) {
 }
 
 $menu_items = [];
+$pluginCalendar = api_get_plugin_setting('learning_calendar', 'enabled') === 'true';
+$calendarMenuAdded = false;
+
 if ($is_platform_admin) {
     if ($view == 'admin') {
         $title = get_lang('CoachList');
@@ -100,6 +101,15 @@ if ($is_platform_admin) {
             Display::return_icon('statistics.png', get_lang('CurrentCoursesReport'), [], ICON_SIZE_MEDIUM),
             api_get_path(WEB_CODE_PATH).'mySpace/current_courses.php'
         );
+
+        if ($pluginCalendar) {
+            $lpCalendar = LearningCalendarPlugin::create();
+            $menu_items[] = Display::url(
+                Display::return_icon('agenda.png', $lpCalendar->get_lang('LearningCalendar'), [], ICON_SIZE_MEDIUM),
+                api_get_path(WEB_PLUGIN_PATH).'learning_calendar/start.php'
+            );
+            $calendarMenuAdded = true;
+        }
     }
 }
 
@@ -136,7 +146,7 @@ $actionsLeft = '';
 if ($display == 'useroverview' || $display == 'sessionoverview' || $display == 'courseoverview') {
     $actionsRight .= Display::url(
         Display::return_icon(
-            "export_csv.png",
+            'export_csv.png',
             get_lang('ExportAsCSV'),
             null,
             ICON_SIZE_MEDIUM
@@ -144,6 +154,7 @@ if ($display == 'useroverview' || $display == 'sessionoverview' || $display == '
         api_get_self().'?display='.$display.'&export=csv&view='.$view
     );
 }
+
 $actionsRight .= Display::url(
     Display::return_icon(
         'printer.png',
@@ -203,18 +214,26 @@ if (!empty($session_id) &&
             null,
             ICON_SIZE_MEDIUM
         ),
-        api_get_path(WEB_CODE_PATH)."auth/my_progress.php"
+        api_get_path(WEB_CODE_PATH).'auth/my_progress.php'
     );
 
+    if ($pluginCalendar && api_is_teacher() && $calendarMenuAdded === false) {
+        $lpCalendar = LearningCalendarPlugin::create();
+        $actionsLeft .= Display::url(
+            Display::return_icon('agenda.png', $lpCalendar->get_lang('LearningCalendar'), [], ICON_SIZE_MEDIUM),
+            api_get_path(WEB_PLUGIN_PATH).'learning_calendar/start.php'
+        );
+    }
+
     if (api_is_platform_admin(true) || api_is_student_boss()) {
         $actionsLeft .= Display::url(
             Display::return_icon(
                 "certificate_list.png",
-                get_lang("GradebookSeeListOfStudentsCertificates"),
+                get_lang('GradebookSeeListOfStudentsCertificates'),
                 null,
                 ICON_SIZE_MEDIUM
             ),
-            api_get_path(WEB_CODE_PATH)."gradebook/certificate_report.php"
+            api_get_path(WEB_CODE_PATH).'gradebook/certificate_report.php'
         );
     }
 }
@@ -284,7 +303,6 @@ $form = new FormValidator(
     api_get_path(WEB_CODE_PATH).'mySpace/student.php'
 );
 $form = Tracking::setUserSearchForm($form);
-
 $skipData = api_get_configuration_value('tracking_skip_generic_data');
 
 $totalTimeSpent = null;

File diff suppressed because it is too large
+ 426 - 293
main/mySpace/myStudents.php


+ 4 - 6
main/session/about.php

@@ -21,7 +21,7 @@ $cidReset = true;
 
 require_once __DIR__.'/../inc/global.inc.php';
 
-$sessionId = isset($_GET['session_id']) ? intval($_GET['session_id']) : 0;
+$sessionId = isset($_GET['session_id']) ? (int) $_GET['session_id'] : 0;
 
 $em = Database::getManager();
 
@@ -30,13 +30,11 @@ $session = $em->find('ChamiloCoreBundle:Session', $sessionId);
 if (!$session) {
     api_not_allowed(true);
 }
-
 $courses = [];
 $sessionCourses = $em->getRepository('ChamiloCoreBundle:Session')->getCoursesOrderedByPosition($session);
 $fieldsRepo = $em->getRepository('ChamiloCoreBundle:ExtraField');
 $fieldTagsRepo = $em->getRepository('ChamiloCoreBundle:ExtraFieldRelTag');
-/** @var UserRepository $userRepo */
-$userRepo = $em->getRepository('ChamiloUserBundle:User');
+$userRepo = UserManager::getRepository();
 $sequenceResourceRepo = $em->getRepository('ChamiloCoreBundle:SequenceResource');
 
 $tagField = $fieldsRepo->findOneBy([
@@ -123,7 +121,7 @@ foreach ($sessionCourses as $sessionCourse) {
     $courses[] = [
         'course' => $sessionCourse,
         'description' => $courseDescription,
-        'image' => $sessionCourse->getPicturePath(true),
+        'image' => CourseManager::getPicturePath($sessionCourse, true),
         'tags' => $courseTags,
         'objectives' => $courseObjectives,
         'topics' => $courseTopics,
@@ -230,7 +228,7 @@ $template->assign(
 );
 $template->assign('has_requirements', $hasRequirements);
 $template->assign('sequences', $sessionRequirements);
-$template->assign('is_premiun', $sessionIsPremium);
+$template->assign('is_premium', $sessionIsPremium);
 $layout = $template->get_template('session/about.tpl');
 $content = $template->fetch($layout);
 //$template->assign('header', $session->getName());

+ 1 - 1
main/session/add_users_to_session.php

@@ -320,7 +320,7 @@ if (isset($_POST['form_sent']) && $_POST['form_sent']) {
     $form_sent = $_POST['form_sent'];
     $firstLetterUser = isset($_POST['firstLetterUser']) ? $_POST['firstLetterUser'] : '';
     $firstLetterSession = isset($_POST['firstLetterSession']) ? $_POST['firstLetterSession'] : '';
-    $UserList = $_POST['sessionUsersList'];
+    $UserList = isset($_POST['sessionUsersList']) ? $_POST['sessionUsersList'] : [];
 
     if (!is_array($UserList)) {
         $UserList = [];

+ 1 - 1
main/session/session_export.php

@@ -315,5 +315,5 @@ $defaults = [];
 $defaults['file_type'] = 'csv';
 $form->setDefaults($defaults);
 $form->display();
-unset($Courses);
+unset($courses);
 Display::display_footer();

+ 14 - 11
main/social/groups.php

@@ -172,13 +172,11 @@ foreach ($results as $result) {
     $html .= '<div class="members-groups">'.$members.'</div>';
     if ($result['description'] != '') {
         $html .= '<div class="description-groups">'.cut($result['description'], 100, true).'</div>';
-    } else {
-        $html .= '';
     }
-    //Avoiding my groups
-
+    // Avoiding my groups
     if (!in_array($id, $my_group_list)) {
-        $html .= '<a class="btn btn-primary" href="group_view.php?id='.$id.'&action=join&u='.api_get_user_id().'">'.get_lang('JoinGroup').'</a> ';
+        $html .= '<a class="btn btn-primary" href="group_view.php?id='.$id.'&action=join&u='.api_get_user_id().'">'.
+            get_lang('JoinGroup').'</a> ';
     }
 
     $html .= '<div class="group-actions" >'.$join_url.'</div>';
@@ -237,9 +235,10 @@ if (is_array($results) && count($results) > 0) {
         } else {
             $html .= '';
         }
-        //Avoiding my groups
+        // Avoiding my groups
         if (!in_array($id, $my_group_list)) {
-            $html .= '<a class="btn btn-primary" href="group_view.php?id='.$id.'&action=join&u='.api_get_user_id().'">'.get_lang('JoinGroup').'</a> ';
+            $html .= '<a class="btn btn-primary" href="group_view.php?id='.$id.'&action=join&u='.api_get_user_id().'">'.
+                get_lang('JoinGroup').'</a> ';
         }
 
         $html .= '<div class="group-actions" >'.$join_url.'</div>';
@@ -270,11 +269,13 @@ if (isset($_GET['view']) && in_array($_GET['view'], $allowed_views)) {
                 );
             }
             if (api_get_setting('allow_students_to_create_groups_in_social') == 'true') {
-                $create_group_item = '<a class="btn btn-default" href="'.api_get_path(WEB_PATH).'main/social/group_add.php">'.
+                $create_group_item =
+                    '<a class="btn btn-default" href="'.api_get_path(WEB_PATH).'main/social/group_add.php">'.
                     get_lang('CreateASocialGroup').'</a>';
             } else {
                 if (api_is_allowed_to_edit(null, true)) {
-                    $create_group_item = '<a class="btn btn-default" href="'.api_get_path(WEB_PATH).'main/social/group_add.php">'.
+                    $create_group_item =
+                        '<a class="btn btn-default" href="'.api_get_path(WEB_PATH).'main/social/group_add.php">'.
                         get_lang('CreateASocialGroup').'</a>';
                 }
             }
@@ -322,11 +323,13 @@ if (isset($_GET['view']) && in_array($_GET['view'], $allowed_views)) {
         $my_group_content = '<span class="muted">'.get_lang('GroupNone').'</span>';
     }
     if (api_get_setting('allow_students_to_create_groups_in_social') == 'true') {
-        $create_group_item = '<a class="btn btn-default" href="'.api_get_path(WEB_PATH).'main/social/group_add.php">'.
+        $create_group_item =
+            '<a class="btn btn-default" href="'.api_get_path(WEB_PATH).'main/social/group_add.php">'.
             get_lang('CreateASocialGroup').'</a>';
     } else {
         if (api_is_allowed_to_edit(null, true)) {
-            $create_group_item = '<a class="btn btn-default" href="'.api_get_path(WEB_PATH).'main/social/group_add.php">'.
+            $create_group_item =
+                '<a class="btn btn-default" href="'.api_get_path(WEB_PATH).'main/social/group_add.php">'.
                 get_lang('CreateASocialGroup').'</a>';
         }
     }

+ 2 - 2
main/social/home.php

@@ -66,7 +66,6 @@ if (api_get_setting('profile', 'picture') == 'true') {
                 $_FILES['picture']['tmp_name']
             )) {
                 $table_user = Database::get_main_table(TABLE_MAIN_USER);
-
                 $sql = "UPDATE $table_user
                         SET 
                             picture_uri = '$new_picture' 
@@ -168,7 +167,8 @@ foreach ($results as $result) {
         GROUP_IMAGE_SIZE_BIG
     );
     $result['picture_uri'] = '<img class="img-responsive" src="'.$picture['file'].'" />';
-    $group_actions = '<div class="group-more"><a class="btn btn-default" href="groups.php?#tab_browse-3">'.get_lang('SeeMore').'</a></div>';
+    $group_actions = '<div class="group-more"><a class="btn btn-default" href="groups.php?#tab_browse-3">'.
+        get_lang('SeeMore').'</a></div>';
     $group_info = '<div class="description"><p>'.cut($result['description'], 120, true)."</p></div>";
     $groups_pop[] = [
         Display::url($result['picture_uri'], $group_url),

+ 4 - 4
main/social/invitations.php

@@ -123,7 +123,8 @@ if ($number_loop != 0) {
         $date = api_convert_and_format_date($invitation['send_date'], DATE_TIME_FORMAT_LONG);
         $invitationHtml .= '<div class="row">';
         $invitationHtml .= '<div class="col-md-2">';
-        $invitationHtml .= '<a href="profile.php?u='.$sender_user_id.'"><img class="img-responsive img-rounded" src="'.$userPicture.'"/></a>';
+        $invitationHtml .= '<a href="profile.php?u='.$sender_user_id.'">';
+        $invitationHtml .= '<img class="img-responsive img-rounded" src="'.$userPicture.'"/></a>';
         $invitationHtml .= '</div>';
         $invitationHtml .= '<div class="col-md-10">';
 
@@ -170,9 +171,7 @@ if (count($list_get_invitation_sent) > 0) {
     foreach ($list_get_invitation_sent as $invitation) {
         $sender_user_id = $invitation['user_receiver_id'];
         $user_info = api_get_user_info($sender_user_id);
-
         $invitationSentHtml .= '<div id="id_'.$sender_user_id.'" class="well">';
-
         $title = Security::remove_XSS($invitation['title'], STUDENT, true);
         $content = Security::remove_XSS($invitation['content'], STUDENT, true);
         $date = api_convert_and_format_date($invitation['send_date'], DATE_TIME_FORMAT_LONG);
@@ -203,7 +202,8 @@ if (count($pending_invitations) > 0) {
         );
         $img = '<img class="img-responsive" src="'.$picture['file'].'" />';
         $invitation['picture_uri'] = '<a href="group_view.php?id='.$invitation['id'].'">'.$img.'</a>';
-        $invitation['name'] = '<a href="group_view.php?id='.$invitation['id'].'">'.cut($invitation['name'], 120, true).'</a>';
+        $invitation['name'] = '<a href="group_view.php?id='.$invitation['id'].'">'.
+            cut($invitation['name'], 120, true).'</a>';
         $invitation['description'] = cut($invitation['description'], 220, true);
         $new_invitation[] = $invitation;
         $waitingInvitation .= '<div class="panel-invitations"><div class="row">';

+ 1 - 1
main/social/my_skills_report.php

@@ -83,7 +83,7 @@ if ($isStudent) {
                 'course_name' => $resultData['title'],
             ];
 
-            $imageSysPath = sprintf("%s%s/course-pic.png", api_get_path(SYS_COURSE_PATH), $resultData['directory']);
+            $imageSysPath = sprintf('%s%s/course-pic.png', api_get_path(SYS_COURSE_PATH), $resultData['directory']);
 
             if (file_exists($imageSysPath)) {
                 $thumbSysPath = sprintf(

+ 4 - 6
main/social/myfiles.php

@@ -4,7 +4,7 @@
 use ChamiloSession as Session;
 
 /**
- * @author Juan Carlos Trabado herodoto@telefonica.net
+ * @author  Juan Carlos Trabado herodoto@telefonica.net
  *
  * @package chamilo.social
  */
@@ -27,7 +27,7 @@ function denied_friend (element_input) {
 
 	$.ajax({
 	    contentType: "application/x-www-form-urlencoded",
-		beforeSend: function(objeto) {
+		beforeSend: function(myObject) {
 		$("#id_response").html("<img src=\'../inc/lib/javascript/indicator.gif\' />"); },
 		type: "POST",
 		url: "'.api_get_path(WEB_AJAX_PATH).'social.ajax.php?a=deny_friend",
@@ -48,7 +48,7 @@ function register_friend(element_input) {
     	
         $.ajax({
     		contentType: "application/x-www-form-urlencoded",
-    		beforeSend: function(objeto) {
+    		beforeSend: function(myObject) {
     		$("div#dpending_"+user_friend_id).html("<img src=\'../inc/lib/javascript/indicator.gif\' />"); },
     		type: "POST",
     		url: "'.api_get_path(WEB_AJAX_PATH).'social.ajax.php?a=add_friend",
@@ -98,9 +98,7 @@ if (api_get_setting('allow_social_tool') == 'true') {
     ];
 }
 
-$interbreadcrumb[] = ['url' => '#', 'name' => get_lang('MyFiles')];
-
-$tpl = new Template();
+$tpl = new Template(get_lang('MyFiles'));
 SocialManager::setSocialUserBlock($tpl, api_get_user_id(), 'myfiles');
 $editor = new \Chamilo\CoreBundle\Component\Editor\Editor();
 $template = $tpl->get_template($editor->getEditorStandAloneTemplate());

+ 0 - 1
main/social/vcard_export.php

@@ -13,7 +13,6 @@ use JeroenDesloovere\VCard\VCard;
 require_once __DIR__.'/../inc/global.inc.php';
 
 api_block_anonymous_users();
-
 api_protect_admin_script();
 
 if (isset($_REQUEST['userId'])) {

+ 33 - 8
main/survey/fillsurvey.php

@@ -532,7 +532,9 @@ if (!empty($survey_data['survey_subtitle'])) {
 }
 
 // Displaying the survey introduction
-if (!isset($_GET['show'])) {
+if (
+    !isset($_GET['show']) ||
+    (isset($_GET['show'])) && $_GET['show'] == '') {
     // The first thing we do is delete the session
     Session::erase('paged_questions');
     Session::erase('page_questions_sec');
@@ -638,7 +640,10 @@ if ($survey_data['shuffle'] == 1) {
     $shuffle = ' BY RAND() ';
 }
 
-if (isset($_GET['show']) || isset($_POST['personality'])) {
+if (
+    (isset($_GET['show']) && $_GET['show'] != '') ||
+    isset($_POST['personality'])
+) {
     // Getting all the questions for this page and add them to a
     // multidimensional array where the first index is the page.
     // As long as there is no pagebreak fount we keep adding questions to the page
@@ -655,6 +660,12 @@ if (isset($_GET['show']) || isset($_POST['personality'])) {
                     ORDER BY sort ASC";
             $result = Database::query($sql);
             while ($row = Database::fetch_array($result, 'ASSOC')) {
+                if ($survey_data['one_question_per_page'] == 1) {
+                    $paged_questions[$counter][] = $row['question_id'];
+                    $counter++;
+
+                    continue;
+                }
                 if ($row['type'] == 'pagebreak') {
                     $counter++;
                 } else {
@@ -1166,12 +1177,23 @@ $sql = "SELECT * FROM $table_survey_question
 $result = Database::query($sql);
 $numberofpages = Database::num_rows($result) + 1;
 // Displaying the form with the questions
-if (isset($_GET['show'])) {
+if (isset($_GET['show']) && $_GET['show'] != '') {
     $show = (int) $_GET['show'] + 1;
 } else {
     $show = 0;
 }
 
+$displayFinishButton = true;
+
+if (isset($_GET['show']) && $_GET['show'] != '') {
+    $pagesIndexes = array_keys($paged_questions);
+    $pagesIndexes[] = count($pagesIndexes);
+
+    if (end($pagesIndexes) <= $show - 1 && empty($_POST)) {
+        $displayFinishButton = false;
+    }
+}
+
 // Displaying the form with the questions
 if (isset($_POST['personality'])) {
     $personality = (int) $_POST['personality'] + 1;
@@ -1241,7 +1263,7 @@ $form->addHtml('<div class="start-survey">');
 if ($survey_data['survey_type'] === '0') {
     if ($survey_data['show_form_profile'] == 0) {
         // The normal survey as always
-        if (($show < $numberofpages) || !$_GET['show']) {
+        if (($show < $numberofpages)) {
             if ($show == 0) {
                 $form->addButton(
                     'next_survey_page',
@@ -1258,7 +1280,7 @@ if ($survey_data['survey_type'] === '0') {
                 );
             }
         }
-        if ($show >= $numberofpages && $_GET['show']) {
+        if ($show >= $numberofpages && $displayFinishButton) {
             $form->addButton(
                 'finish_survey',
                 get_lang('FinishSurvey'),
@@ -1270,7 +1292,7 @@ if ($survey_data['survey_type'] === '0') {
         // The normal survey as always but with the form profile
         if (isset($_GET['show'])) {
             $numberofpages = count($paged_questions);
-            if (($show < $numberofpages) || !$_GET['show']) { //$show = $_GET['show'] + 1
+            if (($show < $numberofpages)) { //$show = $_GET['show'] + 1
                 if ($show == 0) {
                     $form->addButton(
                         'next_survey_page',
@@ -1288,7 +1310,7 @@ if ($survey_data['survey_type'] === '0') {
                 }
             }
 
-            if ($show >= $numberofpages && $_GET['show']) {
+            if ($show >= $numberofpages && $displayFinishButton) {
                 $form->addButton(
                     'finish_survey',
                     get_lang('FinishSurvey'),
@@ -1364,11 +1386,14 @@ Display::display_footer();
  */
 function check_time_availability($surveyData)
 {
+    $allowSurveyAvailabilityDatetime = api_get_configuration_value('allow_survey_availability_datetime');
     $utcZone = new DateTimeZone('UTC');
     $startDate = new DateTime($surveyData['start_date'], $utcZone);
     $endDate = new DateTime($surveyData['end_date'], $utcZone);
     $currentDate = new DateTime('now', $utcZone);
-    $currentDate->modify('today');
+    if (!$allowSurveyAvailabilityDatetime) {
+        $currentDate->modify('today');
+    }
     if ($currentDate < $startDate) {
         api_not_allowed(
             true,

+ 26 - 8
main/survey/surveyUtil.class.php

@@ -2638,12 +2638,10 @@ class SurveyUtil
     /**
      * This function displays the form for searching a survey.
      *
-     *
      * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
      *
      * @version January 2007
      *
-     * @todo use quickforms
      * @todo consider moving this to surveymanager.inc.lib.php
      */
     public static function display_survey_search_form()
@@ -2894,10 +2892,10 @@ class SurveyUtil
                     .http_build_query($params + ['action' => 'copy_survey', 'survey_id' => $survey_id])
             );
 
-            $warning = addslashes(api_htmlentities(get_lang("EmptySurvey").'?', ENT_QUOTES));
+            $warning = addslashes(api_htmlentities(get_lang('EmptySurvey').'?', ENT_QUOTES));
             $actions[] = Display::url(
                 Display::return_icon('clean.png', get_lang('EmptySurvey')),
-                $codePath.'survey/survey_list.php'
+                $codePath.'survey/survey_list.php?'
                     .http_build_query($params + ['action' => 'empty', 'survey_id' => $survey_id]),
                 [
                     'onclick' => "javascript: if (!confirm('".$warning."')) return false;",
@@ -3077,6 +3075,8 @@ class SurveyUtil
         $mandatoryAllowed = api_get_configuration_value('allow_mandatory_survey');
         $_user = api_get_user_info();
 
+        $allowSurveyAvailabilityDatetime = api_get_configuration_value('allow_survey_availability_datetime');
+
         // Searching
         $search_restriction = self::survey_search_restriction();
         if ($search_restriction) {
@@ -3147,8 +3147,14 @@ class SurveyUtil
             $array[2] = $survey[2].$session_img;
             $array[3] = $survey[3];
             $array[4] = $survey[4];
-            $array[5] = $survey[5];
-            $array[6] = $survey[6];
+            $array[5] = api_convert_and_format_date(
+                $survey[5],
+                $allowSurveyAvailabilityDatetime ? DATE_TIME_FORMAT_LONG : DATE_FORMAT_LONG
+            );
+            $array[6] = api_convert_and_format_date(
+                $survey[6],
+                $allowSurveyAvailabilityDatetime ? DATE_TIME_FORMAT_LONG : DATE_FORMAT_LONG
+            );
             $array[7] =
                 Display::url(
                     $survey['answered'],
@@ -3198,6 +3204,7 @@ class SurveyUtil
     public static function get_survey_data_for_coach($from, $number_of_items, $column, $direction)
     {
         $mandatoryAllowed = api_get_configuration_value('allow_mandatory_survey');
+        $allowSurveyAvailabilityDatetime = api_get_configuration_value('allow_survey_availability_datetime');
         $survey_tree = new SurveyTree();
         //$last_version_surveys = $survey_tree->get_last_children_from_branch($survey_tree->surveylist);
         $last_version_surveys = $survey_tree->surveylist;
@@ -3253,6 +3260,15 @@ class SurveyUtil
         $res = Database::query($sql);
         $surveys = [];
         while ($survey = Database::fetch_array($res)) {
+            $survey['col5'] = api_convert_and_format_date(
+                $survey['col5'],
+                $allowSurveyAvailabilityDatetime ? DATE_TIME_FORMAT_LONG : DATE_FORMAT_LONG
+            );
+            $survey['col6'] = api_convert_and_format_date(
+                $survey['col6'],
+                $allowSurveyAvailabilityDatetime ? DATE_TIME_FORMAT_LONG : DATE_FORMAT_LONG
+            );
+
             if ($mandatoryAllowed) {
                 $survey['col10'] = $survey['col9'];
                 $efvMandatory = $efv->get_values_by_handler_and_field_variable(
@@ -3283,6 +3299,7 @@ class SurveyUtil
         $user_id = intval($user_id);
         $sessionId = api_get_session_id();
         $mandatoryAllowed = api_get_configuration_value('allow_mandatory_survey');
+        $allowSurveyAvailabilityDatetime = api_get_configuration_value('allow_survey_availability_datetime');
 
         // Database table definitions
         $table_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
@@ -3313,6 +3330,7 @@ class SurveyUtil
 
         /** @var \DateTime $now */
         $now = api_get_utc_datetime(null, false, true);
+        $filterDate = $allowSurveyAvailabilityDatetime ? $now->format('Y-m-d H:i') : $now->format('Y-m-d');
 
         $sql = "SELECT *
                 FROM $table_survey survey 
@@ -3325,8 +3343,8 @@ class SurveyUtil
                 )
 				WHERE
                     survey_invitation.user = $user_id AND                    
-                    survey.avail_from <= '".$now->format('Y-m-d')."' AND
-                    survey.avail_till >= '".$now->format('Y-m-d')."' AND
+                    survey.avail_from <= '$filterDate' AND
+                    survey.avail_till >= '$filterDate' AND
                     survey.c_id = $course_id AND
                     survey.session_id = $sessionId AND
                     survey_invitation.c_id = $course_id

+ 14 - 9
main/ticket/new_ticket.php

@@ -4,16 +4,15 @@
 /**
  * @package chamilo.ticket
  */
-$cidReset = true;
-
 require_once __DIR__.'/../inc/global.inc.php';
 
-if (!api_is_platform_admin() && api_get_setting('ticket_allow_student_add') != 'true') {
-    header('location:'.api_get_path(WEB_CODE_PATH).'ticket/tickets.php');
+if (!api_is_platform_admin() && api_get_setting('ticket_allow_student_add') !== 'true') {
+    header('Location:'.api_get_path(WEB_CODE_PATH).'ticket/tickets.php');
     exit;
 }
 
 api_block_anonymous_users();
+
 $courseId = api_get_course_int_id();
 
 $htmlHeadXtra[] = '<script>
@@ -370,13 +369,19 @@ $form->addElement(
 );
 
 $sessionList = SessionManager::get_sessions_by_user($userId);
-$sessionListToSelect = [get_lang('Select')];
-//Course List
-foreach ($sessionList as $sessionInfo) {
-    $sessionListToSelect[$sessionInfo['session_id']] = $sessionInfo['session_name'];
+
+if (api_is_platform_admin() || !empty($sessionList)) {
+    $sessionListToSelect = [get_lang('Select')];
+    // Course List
+    foreach ($sessionList as $sessionInfo) {
+        $sessionListToSelect[$sessionInfo['session_id']] = $sessionInfo['session_name'];
+    }
+
+    $form->addSelect('session_id', get_lang('Session'), $sessionListToSelect, ['id' => 'session_id']);
+} else {
+    $form->addHidden('session_id', 0);
 }
 
-$form->addSelect('session_id', get_lang('Session'), $sessionListToSelect, ['id' => 'session_id']);
 $form->addSelect('course_id', get_lang('Course'), [], ['id' => 'course_id']);
 
 $courseInfo = api_get_course_info();

+ 3 - 3
main/ticket/tickets.php

@@ -59,8 +59,8 @@ $projectId = isset($_GET['project_id']) ? (int) $_GET['project_id'] : 0;
 
 $table = new SortableTable(
     'Tickets',
-    ['TicketManager', 'get_total_tickets_by_user_id'],
-    ['TicketManager', 'get_tickets_by_user_id'],
+    ['TicketManager', 'getTotalTicketsCurrentUser'],
+    ['TicketManager', 'getTicketsByCurrentUser'],
     2,
     20,
     'DESC'
@@ -180,7 +180,7 @@ if (!empty($projectId)) {
         $selectTypes[$type['category_id']] = $type['name'];
     }
 
-    $admins = UserManager::get_user_list_like(
+    $admins = UserManager::getUserListLike(
         ['status' => '1'],
         ['username'],
         true

+ 1 - 1
main/ticket/tutor.php

@@ -52,7 +52,7 @@ function save() {
 	rs_id = $("#rs_id").val();
 	 $.ajax({
 		contentType: "application/x-www-form-urlencoded",
-		beforeSend: function(objeto) {
+		beforeSend: function(myObject) {
 		$("div#confirmation").html("<img src=\"'.api_get_path(WEB_LIBRARY_PATH).'javascript/indicator.gif\" />"); },
 		type: "POST",
 		url: "update_report.php",

+ 1 - 3
main/upload/form.document.php

@@ -22,9 +22,7 @@ api_display_tool_title($nameTools.$add_group_to_title);
 <div id="dynamic_div" style="display:block;margin-left:40%;margin-top:10px;height:50px;">
 </div>
 <div id="upload_form_div" name="form_div" style="display:block;">
-    <form method="POST" action="upload.php" id="upload_form"
-          enctype="multipart/form-data"
-          onsubmit="javascript: myUpload.start('dynamic_div','progressbar_green.gif','<?php echo get_lang('Uploading', ''); ?>', 'upload_form_div');">
+    <form method="POST" action="upload.php" id="upload_form" enctype="multipart/form-data">
         <input type="hidden" name="curdirpath" value="<?php echo $path; ?>">
         <input type="hidden" name="tool" value="<?php echo $my_tool; ?>">
         <input type="file" name="user_file">

+ 1 - 1
main/upload/form.scorm.php

@@ -41,7 +41,7 @@ function get_zip_files_in_garbage()
  */
 $nameTools = get_lang('FileUpload');
 $interbreadcrumb[] = [
-    "url" => api_get_path(WEB_CODE_PATH)."lp/lp_controller.php?action=list?".api_get_cidreq(),
+    "url" => api_get_path(WEB_CODE_PATH)."lp/lp_controller.php?action=list&".api_get_cidreq(),
     "name" => get_lang("ToolLearnpath"),
 ];
 

+ 1 - 9
main/upload/index.php

@@ -22,7 +22,7 @@ $_course = api_get_course_info();
 
 $htmlHeadXtra[] = "<script>
 function check_unzip() {
-	if(document.upload.unzip.checked){
+	if (document.upload.unzip.checked) {
         document.upload.if_exists[0].disabled=true;
         document.upload.if_exists[1].checked=true;
         document.upload.if_exists[2].disabled=true;
@@ -63,14 +63,6 @@ if (isset($_REQUEST['tool'])) {
  */
 Event::event_access_tool(TOOL_UPLOAD);
 
-/**
- *	Prepare the header.
- */
-$htmlHeadXtra[] = '<script language="javascript" src="../inc/lib/javascript/upload.js" type="text/javascript"></script>';
-$htmlHeadXtra[] = '<script>
-	var myUpload = new upload(0);
-</script>';
-
 /**
  * Now call the corresponding display script, the current script acting like a controller.
  */

+ 1 - 1
main/upload/upload.scorm.php

@@ -38,5 +38,5 @@ if (api_get_setting('search_enabled') === 'true') {
     }
 }
 
-header('location: ../lp/lp_controller.php?action=list?'.api_get_cidreq());
+header('location: ../lp/lp_controller.php?action=list&'.api_get_cidreq());
 exit;

+ 5 - 6
main/upload/upload_ppt.php

@@ -1,5 +1,6 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
 
 /**
@@ -12,16 +13,14 @@ use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
  */
 require_once __DIR__.'/../inc/global.inc.php';
 
-$htmlHeadXtra[] = '<script language="javascript" src="../inc/lib/javascript/upload.js" type="text/javascript"></script>';
-$htmlHeadXtra[] = '<script type="text/javascript">
-	var myUpload = new upload(0);
-</script>';
-
 if (isset($_POST['convert'])) {
     $cwdir = getcwd();
     if (isset($_FILES['user_file'])) {
         $allowed_extensions = ['odp', 'sxi', 'ppt', 'pps', 'sxd', 'pptx'];
-        if (in_array(strtolower(pathinfo($_FILES['user_file']['name'], PATHINFO_EXTENSION)), $allowed_extensions)) {
+        if (in_array(
+            strtolower(pathinfo($_FILES['user_file']['name'], PATHINFO_EXTENSION)),
+            $allowed_extensions
+        )) {
             require_once api_get_path(SYS_CODE_PATH).'lp/lp_upload.php';
             if (isset($o_ppt) && $first_item_id != 0) {
                 if (api_get_setting('search_enabled') == 'true') {

+ 1 - 4
main/upload/upload_word.php

@@ -1,5 +1,6 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
  * Action controller for the upload process. The display scripts (web forms)
  * redirect
@@ -23,10 +24,6 @@ $form_style = '<style>
 #dynamic_div_waiter_container{float:left;}
 </style>';
 
-$htmlHeadXtra[] = '<script language="javascript" src="../inc/lib/javascript/upload.js" type="text/javascript"></script>';
-$htmlHeadXtra[] = '<script type="text/javascript">
-    var myUpload = new upload(0);
-</script>';
 $htmlHeadXtra[] = $form_style;
 
 if (api_get_setting('search_enabled') == 'true') {

+ 8 - 9
main/user/class.php

@@ -15,14 +15,14 @@ if (api_get_setting('allow_user_course_subscription_by_course_admin') == 'false'
     }
 }
 
-$tool_name = get_lang("Classes");
+$tool_name = get_lang('Classes');
 
 $htmlHeadXtra[] = api_get_jqgrid_js();
 
 // Extra entries in breadcrumb
 $interbreadcrumb[] = [
     "url" => "user.php?".api_get_cidreq(),
-    "name" => get_lang("ToolUser"),
+    "name" => get_lang('ToolUser'),
 ];
 
 $type = isset($_GET['type']) ? Security::remove_XSS($_GET['type']) : 'registered';
@@ -43,10 +43,10 @@ $usergroup = new UserGroup();
 if (api_is_allowed_to_edit()) {
     if ($type === 'registered') {
         $actionsLeft .= '<a href="class.php?'.api_get_cidreq().'&type=not_registered">'.
-            Display::return_icon('add-class.png', get_lang("AddClassesToACourse"), [], ICON_SIZE_MEDIUM).'</a>';
+            Display::return_icon('add-class.png', get_lang('AddClassesToACourse'), [], ICON_SIZE_MEDIUM).'</a>';
     } else {
         $actionsLeft .= '<a href="class.php?'.api_get_cidreq().'&type=registered">'.
-            Display::return_icon('back.png', get_lang("Classes"), [], ICON_SIZE_MEDIUM).'</a>';
+            Display::return_icon('back.png', get_lang('Classes'), [], ICON_SIZE_MEDIUM).'</a>';
 
         $form = new FormValidator(
             'groups',
@@ -102,10 +102,10 @@ if (api_is_allowed_to_edit()) {
     }
 }
 
-//jqgrid will use this URL to do the selects
+// jqgrid will use this URL to do the selects
 $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_usergroups_teacher&type='.$type.'&group_filter='.$groupFilter;
 
-//The order is important you need to check the the $column variable in the model.ajax.php file
+// The order is important you need to check the the $column variable in the model.ajax.php file
 $columns = [
     get_lang('Name'),
     get_lang('Users'),
@@ -152,7 +152,7 @@ $extraParams['autowidth'] = 'true';
 // height auto
 $extraParams['height'] = 'auto';
 
-Display :: display_header($tool_name, "User");
+Display::display_header($tool_name, 'User');
 
 ?>
 <script>
@@ -176,6 +176,5 @@ $(function() {
 
 echo $actions;
 echo UserManager::getUserSubscriptionTab(4);
-
 $usergroup->display_teacher_view();
-Display :: display_footer();
+Display::display_footer();

+ 1 - 1
main/user/classes.php

@@ -46,7 +46,7 @@ if (!empty($usergroup_list)) {
     }
 }
 
-Display::display_header($tool_name, 'Classes');
+Display::display_header('', 'Classes');
 
 echo $content;
 

+ 1 - 1
main/webservices/additional_webservices.php

@@ -45,7 +45,7 @@ function wsConvertPpt($pptData)
     //$perms = api_get_permissions_for_new_directories();
     // Set permissions the most permissively possible: these files will
     // be deleted below and we need a parallel process to be able to write them
-    $perms = 0777;
+    $perms = api_get_permissions_for_new_directories();
     pptConverterDirectoriesCreate($tempPath, $tempPathNewFiles, $fileName, $perms);
 
     $file = base64_decode($fileData);

+ 126 - 6
main/webservices/registration.soap.php

@@ -4644,13 +4644,16 @@ function WSSubscribeUserToCourse($params)
             $courseCode = isset($courseInfo['code']) ? $courseInfo['code'] : '';
 
             if (empty($courseCode)) {
+                if ($debug) {
+                    error_log('WSSubscribeUserToCourse course not found');
+                }
                 // Course was not found
                 $resultValue = 0;
             } else {
                 if ($debug) {
                     error_log('WSSubscribeUserToCourse courseCode: '.$courseCode);
                 }
-                $result = CourseManager::add_user_to_course($user_id, $courseCode, $status, false);
+                $result = CourseManager::add_user_to_course($user_id, $courseCode, $status, false, false);
                 if ($result) {
                     $resultValue = 1;
                     if ($debug) {
@@ -4658,7 +4661,7 @@ function WSSubscribeUserToCourse($params)
                     }
                 } else {
                     if ($debug) {
-                        error_log('WSSubscribeUserToCourse NOT subscribed: ');
+                        error_log('WSSubscribeUserToCourse NOT subscribed.');
                     }
                 }
             }
@@ -4764,8 +4767,9 @@ function WSSubscribeUserToCourseSimple($params)
             if ($debug) {
                 error_log('Try to register: user_id= '.$user_id.' to course: '.$course_data['code']);
             }
-            if (!CourseManager::add_user_to_course($user_id, $course_data['code'], $status)) {
-                $result = 'User was not registered possible reasons: User already registered to the course, Course visibility doesnt allow user subscriptions ';
+            if (!CourseManager::add_user_to_course($user_id, $course_data['code'], $status, false, false)) {
+                $result = 'User was not registered possible reasons: User already registered to the course, 
+                           Course visibility doesnt allow user subscriptions ';
                 if ($debug) {
                     error_log($result);
                 }
@@ -4870,11 +4874,27 @@ $server->wsdl->addComplexType(
         'secret_key' => ['name' => 'secret_key', 'type' => 'xsd:string'],
     ]
 );
+
+// Prepare output params, in this case will return an array
+$server->wsdl->addComplexType(
+    'UserWithExtraFields',
+    'complexType',
+    'struct',
+    'all',
+    '',
+    [
+        'user_id' => ['name' => 'user_id', 'type' => 'xsd:string'],
+        'firstname' => ['name' => 'firstname', 'type' => 'xsd:string'],
+        'lastname' => ['name' => 'lastname', 'type' => 'xsd:string'],
+        'extra_fields' => ['name' => 'extra_fields', 'type' => 'xsd:string'],
+    ]
+);
+
 // Register the method to expose
 $server->register(
     'WSGetUserFromUsername', // method name
     ['GetUserFromUsername' => 'tns:GetUserArgUsername'], // input params
-    ['return' => 'tns:User'], // output parameters
+    ['return' => 'tns:UserWithExtraFields'], // output parameters
     'urn:WSRegistration', // namespace
     'urn:WSRegistration#WSGetUserFromUsername', // soapaction
     'rpc', // style
@@ -4897,20 +4917,120 @@ function WSGetUserFromUsername($params)
         return returnError(WS_ERROR_SECRET_KEY);
     }
 
+    // Get user id
+    $user_data = api_get_user_info_from_username($params['username']);
+
+    $result = [];
+    $result['user_id'] = '';
+    $result['firstname'] = '';
+    $result['lastname'] = '';
+    $result['extra_fields'] = '';
+
+    if (empty($user_data)) {
+        // If user was not found, there was a problem
+        if ($debug) {
+            error_log('User not found :(');
+        }
+    } else {
+        $result['user_id'] = $user_data['user_id'];
+        $result['firstname'] = $user_data['firstname'];
+        $result['lastname'] = $user_data['lastname'];
+        $result['email'] = $user_data['email'];
+
+        // Get extra fields
+        $fieldValue = new ExtraFieldValue('user');
+        $extra = $fieldValue->getAllValuesByItem($result['user_id']);
+        $result['extra_fields'] = json_encode($extra);
+
+        if ($debug) {
+            error_log('User found :) return value '.print_r($result, 1));
+        }
+    }
+
+    return $result;
+}
+
+$server->wsdl->addComplexType(
+    'GetUserArgUsernameWithOriginal',
+    'complexType',
+    'struct',
+    'all',
+    '',
+    [
+        'username' => ['name' => 'username', 'type' => 'xsd:string'],
+        'original_user_id_name' => ['name' => 'original_user_id_name', 'type' => 'xsd:string'],
+        'original_user_id_value' => ['name' => 'original_user_id_value', 'type' => 'xsd:string'],
+        'secret_key' => ['name' => 'secret_key', 'type' => 'xsd:string'],
+    ]
+);
+// Register the method to expose
+$server->register(
+    'WSUpdateUserOriginalIdFromUsername', // method name
+    ['WSUpdateUserOriginalIdFromUsername' => 'tns:GetUserArgUsernameWithOriginal'], // input params
+    ['return' => 'tns:User'], // output parameters
+    'urn:WSRegistration', // namespace
+    'urn:WSRegistration#WSGetUserFromUsername', // soapaction
+    'rpc', // style
+    'encoded', // use
+    'This service get user information by username'            // documentation
+);
+
+// define the method WSGetUserFromUsername
+function WSUpdateUserOriginalIdFromUsername($params)
+{
+    global $debug;
+    if ($debug) {
+        error_log('WSUpdateUserOriginalIdFromUsername');
+    }
+    if ($debug) {
+        error_log('$params: '.print_r($params, 1));
+    }
+
+    if (!WSHelperVerifyKey($params)) {
+        return returnError(WS_ERROR_SECRET_KEY);
+    }
+
     $result = [];
 
     // Get user id
-    $user_data = api_get_user_info($params['username']);
+    $user_data = api_get_user_info_from_username($params['username']);
 
     if (empty($user_data)) {
         // If user was not found, there was a problem
         $result['user_id'] = '';
         $result['firstname'] = '';
         $result['lastname'] = '';
+
+        if ($debug) {
+            error_log('User not found :(');
+        }
     } else {
         $result['user_id'] = $user_data['user_id'];
         $result['firstname'] = $user_data['firstname'];
         $result['lastname'] = $user_data['lastname'];
+        $result['email'] = $user_data['email'];
+
+        $resultUpdate = UserManager::update_extra_field_value(
+            $user_data['user_id'],
+            $params['original_user_id_name'],
+            $params['original_user_id_value']
+        );
+
+        $fieldValue = new ExtraFieldValue('user');
+        $extraList = $fieldValue->getAllValuesByItem(
+            $result['user_id']
+        );
+
+        $result['extra'] = $extraList;
+
+        if ($debug) {
+            if ($resultUpdate) {
+                error_log('User updated :) ');
+            } else {
+                error_log('User not updated :(');
+            }
+            error_log('$result: '.print_r($result, 1));
+        }
     }
 
     return $result;

+ 2 - 3
main/work/add_document.php

@@ -6,8 +6,8 @@ require_once 'work.lib.php';
 
 $current_course_tool = TOOL_STUDENTPUBLICATION;
 
-$workId = isset($_GET['id']) ? intval($_GET['id']) : null;
-$docId = isset($_GET['document_id']) ? intval($_GET['document_id']) : null;
+$workId = isset($_GET['id']) ? (int) $_GET['id'] : null;
+$docId = isset($_GET['document_id']) ? (int) $_GET['document_id'] : null;
 $action = isset($_GET['action']) ? $_GET['action'] : null;
 
 if (empty($workId)) {
@@ -51,7 +51,6 @@ switch ($action) {
 
 if (empty($docId)) {
     Display::display_header(null);
-
     $documents = getAllDocumentToWork($workId, api_get_course_int_id());
     if (!empty($documents)) {
         echo Display::page_subheader(get_lang('DocumentsAdded'));

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