Browse Source

Minor - merge with 1.11.x

jmontoyaa 6 years ago
parent
commit
000f93c6ac
83 changed files with 1372 additions and 958 deletions
  1. 3 0
      main/admin/course_list.php
  2. 0 32
      main/admin/user_add.php
  3. 1 1
      main/admin/user_import.php
  4. 9 3
      main/admin/user_list.php
  5. 1 1
      main/admin/user_move_stats.php
  6. 1 1
      main/auth/courses.php
  7. 1 1
      main/auth/inscription.php
  8. 3 3
      main/blog/blog.php
  9. 50 6
      main/course_description/course_description_controller.php
  10. 7 7
      main/course_description/index.php
  11. 0 118
      main/course_description/listing.php
  12. 14 2
      main/course_home/course_home.php
  13. 260 68
      main/course_info/infocours.php
  14. 5 5
      main/dashboard/index.php
  15. 3 2
      main/document/document.php
  16. 1 1
      main/exercise/Draggable.php
  17. 2 2
      main/exercise/MatchingDraggable.php
  18. 1 1
      main/exercise/UniqueAnswerImage.php
  19. 85 77
      main/exercise/exercise.class.php
  20. 2 2
      main/exercise/exercise.php
  21. 2 2
      main/exercise/exercise_report.php
  22. 30 27
      main/exercise/exercise_submit.php
  23. 2 2
      main/exercise/matching.class.php
  24. 1 1
      main/exercise/multiple_answer.class.php
  25. 1 1
      main/exercise/multiple_answer_combination.class.php
  26. 1 1
      main/exercise/multiple_answer_true_false.class.php
  27. 23 4
      main/exercise/showinframes.php
  28. 1 1
      main/exercise/unique_answer.class.php
  29. 1 1
      main/exercise/unique_answer_no_option.class.php
  30. 2 2
      main/group/group.php
  31. 4 3
      main/group/member_settings.php
  32. 84 54
      main/inc/ajax/lp.ajax.php
  33. 14 11
      main/inc/ajax/statistics.ajax.php
  34. 14 6
      main/inc/lib/AnnouncementManager.php
  35. 6 17
      main/inc/lib/CourseChatUtils.php
  36. 0 3
      main/inc/lib/CoursesAndSessionsCatalog.class.php
  37. 10 9
      main/inc/lib/ScheduledAnnouncement.php
  38. 24 58
      main/inc/lib/agenda.lib.php
  39. 37 15
      main/inc/lib/api.lib.php
  40. 2 2
      main/inc/lib/auth.lib.php
  41. 11 7
      main/inc/lib/banner.lib.php
  42. 2 3
      main/inc/lib/certificate.lib.php
  43. 19 10
      main/inc/lib/course.lib.php
  44. 27 8
      main/inc/lib/course_home.lib.php
  45. 6 1
      main/inc/lib/database.constants.inc.php
  46. 2 1
      main/inc/lib/display.lib.php
  47. 1 1
      main/inc/lib/events.lib.php
  48. 4 1
      main/inc/lib/exercise.lib.php
  49. 5 4
      main/inc/lib/glossary.lib.php
  50. 47 4
      main/inc/lib/groupmanager.lib.php
  51. 127 67
      main/inc/lib/message.lib.php
  52. 15 3
      main/inc/lib/online.inc.php
  53. 118 61
      main/inc/lib/sessionmanager.lib.php
  54. 2 2
      main/inc/lib/statistics.lib.php
  55. 2 2
      main/inc/lib/system_announcements.lib.php
  56. 8 12
      main/inc/lib/tracking.lib.php
  57. 2 2
      main/inc/lib/usergroup.lib.php
  58. 8 3
      main/inc/lib/usermanager.lib.php
  59. 9 3
      main/inc/lib/userportal.lib.php
  60. 128 73
      main/lp/learnpath.class.php
  61. 7 3
      main/lp/learnpathItem.class.php
  62. 2 5
      main/lp/lp_add_item.php
  63. 17 19
      main/lp/lp_ajax_save_item.php
  64. 1 1
      main/lp/lp_ajax_switch_item.php
  65. 0 2
      main/lp/lp_build.php
  66. 12 21
      main/lp/lp_controller.php
  67. 1 2
      main/lp/lp_edit.php
  68. 2 7
      main/lp/lp_edit_item.php
  69. 18 3
      main/messages/new_message.php
  70. 1 1
      main/mySpace/myStudents.php
  71. 0 14
      main/portfolio/share.php
  72. 1 1
      main/session/about.php
  73. 2 2
      main/session/add_users_to_session.php
  74. 1 1
      main/session/resume_session.php
  75. 1 1
      main/session/session_user_import.php
  76. 10 2
      main/social/my_skills_report.php
  77. 21 35
      main/survey/fillsurvey.php
  78. 10 11
      main/tracking/courseLog.php
  79. 1 1
      main/user/add_users_to_session.php
  80. 8 0
      main/user/user.php
  81. 1 1
      main/webservices/http-auth.php
  82. 3 3
      main/webservices/registration.soap.php
  83. 1 1
      main/webservices/webservice_session.php

+ 3 - 0
main/admin/course_list.php

@@ -342,6 +342,8 @@ if (isset($_POST['action'])) {
                     $obj_cat->update_category_delete($course_code);
                 }
             }
+
+            Display::addFlash(Display::return_message(get_lang('Deleted')));
             break;
     }
 }
@@ -409,6 +411,7 @@ if (isset($_GET['search']) && $_GET['search'] === 'advanced') {
         CourseManager::delete_course($_GET['delete_course']);
         $obj_cat = new Category();
         $obj_cat->update_category_delete($_GET['delete_course']);
+        Display::addFlash(Display::return_message(get_lang('Deleted')));
     }
     // Create a search-box
     $form = new FormValidator(

+ 0 - 32
main/admin/user_add.php

@@ -19,29 +19,6 @@ $is_platform_admin = api_is_platform_admin() ? 1 : 0;
 
 $message = null;
 $htmlHeadXtra[] = api_get_password_checker_js('#username', '#password');
-
-$checkPass = api_get_setting('allow_strength_pass_checker');
-if ($checkPass == 'true') {
-    $htmlHeadXtra[] = '
-    <script>
-    $(document).ready(function() {
-        $("#password").keypress(function() {
-            $("#password").each(function(index, value) {
-                var value = $(this).attr("value");
-                if (value == 0) {
-                    $("#password_progress").show();
-                    $(".password-verdict").show();
-                    $(".error-list").show();
-                } else {
-                    $("#password_progress").hide();
-                    $(".password-verdict").hide();
-                    $(".error-list").hide();
-                }
-            });
-        });
-    });
-    </script>';
-}
 //$htmlHeadXtra[] = api_get_css_asset('cropper/dist/cropper.min.css');
 //$htmlHeadXtra[] = api_get_asset('cropper/dist/cropper.min.js');
 $htmlHeadXtra[] = '
@@ -247,15 +224,6 @@ $form->addGroup($group, 'password', get_lang('Password'));
 $form->addPasswordRule('password', 'password');
 $form->addGroupRule('password', get_lang('EnterPassword'), 'required', null, 1);
 
-if ($checkPass) {
-    $strengthLabels = '
-        <div id="password-verdict"></div>
-        <div id="password-errors"></div>
-        <div id="password_progress" style="display:none"></div>
-    ';
-    $form->addElement('label', null, $strengthLabels);
-}
-
 // Status
 $status = [];
 $status[COURSEMANAGER] = get_lang('Teacher');

+ 1 - 1
main/admin/user_import.php

@@ -223,7 +223,7 @@ function save_data($users)
                 foreach ($user['Sessions'] as $sessionId) {
                     $sessionInfo = api_get_session_info($sessionId);
                     if (!empty($sessionInfo)) {
-                        SessionManager::subscribe_users_to_session(
+                        SessionManager::subscribeUsersToSession(
                             $sessionId,
                             [$user_id],
                             SESSION_VISIBLE_READ_ONLY,

+ 9 - 3
main/admin/user_list.php

@@ -208,17 +208,17 @@ function trimVariables()
  * Prepares the shared SQL query for the user table.
  * See get_user_data() and get_number_of_users().
  *
- * @param bool $is_count Whether to count, or get data
+ * @param bool $getCount Whether to count, or get data
  *
  * @return string SQL query
  */
-function prepare_user_sql_query($is_count)
+function prepare_user_sql_query($getCount)
 {
     $sql = '';
     $user_table = Database::get_main_table(TABLE_MAIN_USER);
     $admin_table = Database::get_main_table(TABLE_MAIN_ADMIN);
 
-    if ($is_count) {
+    if ($getCount) {
         $sql .= "SELECT COUNT(u.id) AS total_number_of_items FROM $user_table u";
     } else {
         $sql .= "SELECT u.id AS col0, u.official_code AS col2, ";
@@ -325,6 +325,7 @@ function prepare_user_sql_query($is_count)
         if (!empty($keywordListValues['keyword_officialcode'])) {
             $sql .= " AND u.official_code LIKE '".Database::escape_string("%".$keywordListValues['keyword_officialcode']."%")."' ";
         }
+
         $sql .= "
             $keyword_admin
             $keyword_extra_value
@@ -342,6 +343,11 @@ function prepare_user_sql_query($is_count)
         $sql .= " ) ";
     }
 
+    $preventSessionAdminsToManageAllUsers = api_get_setting('prevent_session_admins_to_manage_all_users');
+    if (api_is_session_admin() && $preventSessionAdminsToManageAllUsers === 'true') {
+        $sql .= " AND u.creator_id = ".api_get_user_id();
+    }
+
     $variables = Session::read('variables_to_show', []);
     if (!empty($variables)) {
         $extraField = new ExtraField('user');

+ 1 - 1
main/admin/user_move_stats.php

@@ -115,7 +115,7 @@ if (isset($_REQUEST['load_ajax'])) {
                         echo 'User added to the session';
                     }
                     //Registering user to the new session
-                    SessionManager::subscribe_users_to_session(
+                    SessionManager::subscribeUsersToSession(
                         $new_session_id,
                         [$user_id],
                         false

+ 1 - 1
main/auth/courses.php

@@ -302,7 +302,7 @@ switch ($action) {
                 }
             }
 
-            SessionManager::subscribe_users_to_session(
+            SessionManager::subscribeUsersToSession(
                 $_GET['session_id'],
                 [$userId],
                 SESSION_VISIBLE_READ_ONLY,

+ 1 - 1
main/auth/inscription.php

@@ -710,7 +710,7 @@ if ($form->validate()) {
             if (!empty($sessionToRedirect) && !$sessionPremiumChecker) {
                 $sessionInfo = api_get_session_info($sessionToRedirect);
                 if (!empty($sessionInfo)) {
-                    SessionManager::subscribe_users_to_session(
+                    SessionManager::subscribeUsersToSession(
                         $sessionToRedirect,
                         [$user_id],
                         SESSION_VISIBLE_READ_ONLY,

+ 3 - 3
main/blog/blog.php

@@ -431,13 +431,13 @@ switch ($action) {
         break;
 }
 
-$content = Display::return_introduction_section(TOOL_BLOGS);
-$content .= $tpl->fetch($blogLayout);
+$content = $tpl->fetch($blogLayout);
 
 if ($actionsLeft) {
     $tpl->assign(
         'actions',
-        Display::toolbarAction('toolbar', [$actionsLeft])
+        Display::return_introduction_section(TOOL_BLOGS)
+            .Display::toolbarAction('toolbar', [$actionsLeft])
     );
 }
 

+ 50 - 6
main/course_description/course_description_controller.php

@@ -33,10 +33,11 @@ class CourseDescriptionController
      */
     public function listing($history = false, $messages = [])
     {
+        $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
         $course_description = new CourseDescription();
         $session_id = api_get_session_id();
-        $course_description->set_session_id($session_id);
         $data = [];
+        $course_description->set_session_id($session_id);
         $course_description_data = $course_description->get_description_data();
         $data['descriptions'] = isset($course_description_data['descriptions']) ? $course_description_data['descriptions'] : '';
         $data['default_description_titles'] = $course_description->get_default_description_title();
@@ -45,6 +46,8 @@ class CourseDescriptionController
         $data['messages'] = $messages;
         $browser = api_get_navigator();
 
+        api_protect_course_script(true);
+
         if (!is_array($data['descriptions'])) {
             $data['descriptions'] = [$data['descriptions']];
         }
@@ -57,12 +60,53 @@ class CourseDescriptionController
                 header("X-XSS-Protection: 0");
             }
         }
+        $actions = null;
+        $actionLeft = null;
+        // display actions menu
+        if ($is_allowed_to_edit) {
+            $categories = [];
+            foreach ($data['default_description_titles'] as $id => $title) {
+                $categories[$id] = $title;
+            }
+            $categories[ADD_BLOCK] = get_lang('NewBloc');
+            $i = 1;
+
+            ksort($categories);
+            foreach ($categories as $id => $title) {
+                if ($i == ADD_BLOCK) {
+                    $actionLeft .= '<a href="index.php?'.api_get_cidreq().'&action=add">'.
+                        Display::return_icon(
+                            $data['default_description_icon'][$id],
+                            $title,
+                            '',
+                            ICON_SIZE_MEDIUM
+                        ).
+                        '</a>';
+                    break;
+                } else {
+                    $actionLeft .= '<a href="index.php?action=edit&'.api_get_cidreq().'&description_type='.$id.'">'.
+                        Display::return_icon(
+                            $data['default_description_icon'][$id],
+                            $title,
+                            '',
+                            ICON_SIZE_MEDIUM
+                        ).
+                        '</a>';
+                    $i++;
+                }
+            }
+            $actions = Display::toolbarAction('toolbar', [0 => $actionLeft]);
+        }
 
-        // render to the view
-        $this->view->set_data($data);
-        $this->view->set_layout('layout');
-        $this->view->set_template('listing');
-        $this->view->render();
+        $tpl = new Template(get_lang('CourseProgram'));
+        $tpl->assign('listing', $data);
+        $tpl->assign('is_allowed_to_edit', $is_allowed_to_edit);
+        $tpl->assign('actions', $actions);
+        $tpl->assign('session_id', $session_id);
+        $templateName = $tpl->get_template('course_description/index.tpl');
+        $content = $tpl->fetch($templateName);
+        $tpl->assign('content', $content);
+        $tpl->display_one_col_template();
     }
 
     /**

+ 7 - 7
main/course_description/index.php

@@ -73,7 +73,7 @@ if ($description_type >= 9) {
 }
 
 // course description controller object
-$course_description_controller = new CourseDescriptionController();
+$descriptionController = new CourseDescriptionController();
 
 // block access
 if (in_array($action, ['add', 'edit', 'delete']) &&
@@ -85,20 +85,20 @@ if (in_array($action, ['add', 'edit', 'delete']) &&
 // Actions to controller
 switch ($action) {
     case 'listing':
-        $course_description_controller->listing();
+        $descriptionController->listing();
         break;
     case 'history':
-        $course_description_controller->listing(true);
+        $descriptionController->listing(true);
         break;
     case 'add':
-        $course_description_controller->add();
+        $descriptionController->add();
         break;
     case 'edit':
-        $course_description_controller->edit($id, $description_type);
+        $descriptionController->edit($id, $description_type);
         break;
     case 'delete':
-        $course_description_controller->destroy($id);
+        $descriptionController->destroy($id);
         break;
     default:
-        $course_description_controller->listing();
+        $descriptionController->listing();
 }

+ 0 - 118
main/course_description/listing.php

@@ -1,118 +0,0 @@
-<?php
-/* For licensing terms, see /license.txt */
-
-/**
- * Template (view in MVC pattern) used for listing course descriptions.
- *
- * @author Christian Fasanando <christian1827@gmail.com>
- *
- * @package chamilo.course_description
- */
-
-// protect a course script
-api_protect_course_script(true);
-
-// display actions menu
-if (api_is_allowed_to_edit(null, true)) {
-    $categories = [];
-    foreach ($default_description_titles as $id => $title) {
-        $categories[$id] = $title;
-    }
-    $categories[ADD_BLOCK] = get_lang('NewBloc');
-
-    $i = 1;
-    echo '<div class="actions" style="margin-bottom:30px">';
-    ksort($categories);
-    foreach ($categories as $id => $title) {
-        if ($i == ADD_BLOCK) {
-            echo '<a href="index.php?'.api_get_cidreq().'&action=add">'.
-                Display::return_icon(
-                    $default_description_icon[$id],
-                    $title,
-                    '',
-                    ICON_SIZE_MEDIUM
-                ).
-                '</a>';
-            break;
-        } else {
-            echo '<a href="index.php?action=edit&'.api_get_cidreq().'&description_type='.$id.'">'.
-                Display::return_icon(
-                    $default_description_icon[$id],
-                    $title,
-                    '',
-                    ICON_SIZE_MEDIUM
-                ).
-                '</a>';
-            $i++;
-        }
-    }
-    echo '</div>';
-}
-$history = isset($history) ? $history : null;
-
-// display course description list
-if ($history) {
-    echo '<div>
-        <table width="100%">
-            <tr>
-                <td><h3>'.get_lang('ThematicAdvanceHistory').'</h3></td>
-                <td align="right"><a href="index.php?action=listing">';
-    echo Display::return_icon(
-        'info.png',
-        get_lang('BackToCourseDesriptionList'),
-        ['style' => 'vertical-align:middle;'],
-        ICON_SIZE_SMALL
-    );
-    echo ' '.get_lang('BackToCourseDesriptionList').'</a></td></tr></table></div>';
-}
-
-$user_info = api_get_user_info();
-
-if (isset($descriptions) && count($descriptions) > 0) {
-    foreach ($descriptions as $id => $description) {
-        if (!empty($description)) {
-            $actions = '';
-            if (api_is_allowed_to_edit(null, true) && !$history) {
-                if (api_get_session_id() == $description['session_id']) {
-                    $description['title'] = $description['title'].' '.api_get_session_image(api_get_session_id(), $user_info['status']);
-
-                    // delete
-                    $actions .= '<a href="'.api_get_self().'?id='.$description['id'].'&'.api_get_cidreq_params(api_get_course_id(), $description['session_id']).'&action=delete&description_type='.$description['description_type'].'" onclick="javascript:if(!confirm(\''.addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES, api_get_system_encoding())).'\')) return false;">';
-                    $actions .= Display::return_icon(
-                        'delete.png',
-                        get_lang('Delete'),
-                        ['style' => 'vertical-align:middle;float:right;'],
-                        ICON_SIZE_SMALL
-                    );
-                    $actions .= '</a> ';
-
-                    // edit
-                    $actions .= '<a href="'.api_get_self().'?id='.$description['id'].'&'.api_get_cidreq_params(api_get_course_id(), $description['session_id']).'&action=edit&description_type='.$description['description_type'].'">';
-                    $actions .= Display::return_icon(
-                        'edit.png',
-                        get_lang('Edit'),
-                        ['style' => 'vertical-align:middle;float:right; padding-right:4px;'],
-                        ICON_SIZE_SMALL
-                    );
-                    $actions .= '</a> ';
-                } else {
-                    $actions .= Display::return_icon(
-                        'edit_na.png',
-                        get_lang('EditionNotAvailableFromSession'),
-                        ['style' => 'vertical-align:middle;float:right;'],
-                        ICON_SIZE_SMALL
-                    );
-                }
-            }
-
-            echo Display::panel(
-                Security::remove_XSS($description['content']),
-                "<div class='pull-right'>$actions</div>{$description['title']}",
-                '',
-                'info'
-            );
-        }
-    }
-} else {
-    echo '<em>'.get_lang('ThisCourseDescriptionIsEmpty').'</em>';
-}

+ 14 - 2
main/course_home/course_home.php

@@ -269,9 +269,21 @@ if (api_get_configuration_value('allow_exercise_auto_launch')) {
         } else {
             // Redirecting to an exercise
             $table = Database::get_course_table(TABLE_QUIZ_TEST);
-            $sessionCondition = api_get_session_condition($session_id, true);
+            $condition = '';
+            if (!empty($session_id)) {
+                $condition = api_get_session_condition($session_id);
+                $sql = "SELECT iid FROM $table
+                        WHERE c_id = $course_id AND autolaunch = 1 $condition
+                        LIMIT 1";
+                $result = Database::query($sql);
+                // If we found nothing in the session we just called the session_id = 0 autolaunch
+                if (Database::num_rows($result) == 0) {
+                    $condition = '';
+                }
+            }
+
             $sql = "SELECT iid FROM $table
-                    WHERE c_id = $course_id AND autolaunch = 1 $sessionCondition
+                    WHERE c_id = $course_id AND autolaunch = 1 $condition
                     LIMIT 1";
             $result = Database::query($sql);
             if (Database::num_rows($result) > 0) {

+ 260 - 68
main/course_info/infocours.php

@@ -70,7 +70,8 @@ $form->addHtml('<div class="panel panel-default">');
 $form->addHtml('
     <div class="panel-heading" role="tab" id="heading-course-settings">
         <h4 class="panel-title">
-            <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse-course-settings" aria-expanded="true" aria-controls="collapse-course-settings">
+            <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse-course-settings"
+               aria-expanded="true" aria-controls="collapse-course-settings">
 ');
 $form->addHtml(
     Display::return_icon('settings.png', get_lang('CourseSettings')).' '.get_lang('CourseSettings')
@@ -81,7 +82,8 @@ $form->addHtml('
     </div>
 ');
 $form->addHtml('
-    <div id="collapse-course-settings" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="heading-course-settings">
+    <div id="collapse-course-settings" class="panel-collapse collapse in" role="tabpanel"
+         aria-labelledby="heading-course-settings">
         <div class="panel-body">
 ');
 
@@ -195,7 +197,8 @@ $form->addHtml('<div class="panel panel-default">');
 $form->addHtml('
     <div class="panel-heading" role="tab" id="heading-course-access">
         <h4 class="panel-title">
-            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse-course-access" aria-expanded="false" aria-controls="collapse-course-access">
+            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion"
+               href="#collapse-course-access" aria-expanded="false" aria-controls="collapse-course-access">
 ');
 $form->addElement(
     'html',
@@ -208,18 +211,43 @@ $form->addHtml('
 ');
 
 $form->addHtml('
-    <div id="collapse-course-access" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-course-access">
+    <div id="collapse-course-access" class="panel-collapse collapse" role="tabpanel"
+         aria-labelledby="heading-course-access">
         <div class="panel-body">
 ');
 
 $group = [];
-$group[] = $form->createElement('radio', 'visibility', get_lang("CourseAccess"), get_lang('OpenToTheWorld'), COURSE_VISIBILITY_OPEN_WORLD);
-$group[] = $form->createElement('radio', 'visibility', null, get_lang('OpenToThePlatform'), COURSE_VISIBILITY_OPEN_PLATFORM);
+$group[] = $form->createElement(
+    'radio',
+    'visibility',
+    get_lang("CourseAccess"),
+    get_lang('OpenToTheWorld'),
+    COURSE_VISIBILITY_OPEN_WORLD
+);
+$group[] = $form->createElement(
+    'radio',
+    'visibility',
+    null,
+    get_lang('OpenToThePlatform'),
+    COURSE_VISIBILITY_OPEN_PLATFORM
+);
 $group[] = $form->createElement('radio', 'visibility', null, get_lang('Private'), COURSE_VISIBILITY_REGISTERED);
-$group[] = $form->createElement('radio', 'visibility', null, get_lang('CourseVisibilityClosed'), COURSE_VISIBILITY_CLOSED);
+$group[] = $form->createElement(
+    'radio',
+    'visibility',
+    null,
+    get_lang('CourseVisibilityClosed'),
+    COURSE_VISIBILITY_CLOSED
+);
 // The "hidden" visibility is only available to portal admins
 if (api_is_platform_admin()) {
-    $group[] = $form->createElement('radio', 'visibility', null, get_lang('CourseVisibilityHidden'), COURSE_VISIBILITY_HIDDEN);
+    $group[] = $form->createElement(
+        'radio',
+        'visibility',
+        null,
+        get_lang('CourseVisibilityHidden'),
+        COURSE_VISIBILITY_HIDDEN
+    );
 }
 $form->addGroup($group, '', [get_lang("CourseAccess"), get_lang("CourseAccessConfigTip")]);
 
@@ -233,13 +261,24 @@ $group[] = $form->createElement('radio', 'subscribe', null, get_lang('Denied'),
 $form->addGroup($group, '', [get_lang("Subscription")]);
 
 $group = [];
-$group[] = $form->createElement('radio', 'unsubscribe', get_lang('Unsubscription'), get_lang('AllowedToUnsubscribe'), 1);
+$group[] = $form->createElement(
+    'radio',
+    'unsubscribe',
+    get_lang('Unsubscription'),
+    get_lang('AllowedToUnsubscribe'),
+    1
+);
 $group[] = $form->createElement('radio', 'unsubscribe', null, get_lang('NotAllowedToUnsubscribe'), 0);
 $form->addGroup($group, '', [get_lang("Unsubscription")]);
 
 $form->addText('course_registration_password', get_lang('CourseRegistrationPassword'), false, ['size' => '60']);
 
-$form->addElement('checkbox', 'activate_legal', [null, get_lang('ShowALegalNoticeWhenEnteringTheCourse')], get_lang('ActivateLegal'));
+$form->addElement(
+    'checkbox',
+    'activate_legal',
+    [null, get_lang('ShowALegalNoticeWhenEnteringTheCourse')],
+    get_lang('ActivateLegal')
+);
 $form->addElement('textarea', 'legal', get_lang('CourseLegalAgreement'), ['rows' => 8]);
 $form->addButtonSave(get_lang('SaveSettings'), 'submit_save');
 
@@ -254,7 +293,8 @@ $form->addHtml('<div class="panel panel-default">');
 $form->addHtml('
     <div class="panel-heading" role="tab" id="heading-documents">
         <h4 class="panel-title">
-            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse-documents" aria-expanded="false" aria-controls="collapse-documents">
+            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion"
+               href="#collapse-documents" aria-expanded="false" aria-controls="collapse-documents">
 ');
 $form->addHtml(
     Display::return_icon('folder.png', get_lang('Documents')).' '.get_lang('Documents')
@@ -306,7 +346,8 @@ $form->addHtml('<div class="panel panel-default">');
 $form->addHtml('
     <div class="panel-heading" role="tab" id="heading-email-notifications">
         <h4 class="panel-title">
-            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse-email-notifications" aria-expanded="false" aria-controls="collapse-email-notifications">
+            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion"
+               href="#collapse-email-notifications" aria-expanded="false" aria-controls="collapse-email-notifications">
 ');
 $form->addHtml(
     Display::return_icon('mail.png', get_lang('EmailNotifications')).' '.get_lang('EmailNotifications')
@@ -317,31 +358,104 @@ $form->addHtml('
     </div>
 ');
 $form->addHtml('
-    <div id="collapse-email-notifications" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-email-notifications">
+    <div id="collapse-email-notifications" class="panel-collapse collapse" role="tabpanel"
+         aria-labelledby="heading-email-notifications">
         <div class="panel-body">
 ');
 $group = [];
-$group[] = $form->createElement('radio', 'email_alert_to_teacher_on_new_user_in_course', get_lang('NewUserEmailAlert'), get_lang('NewUserEmailAlertEnable'), 1);
-$group[] = $form->createElement('radio', 'email_alert_to_teacher_on_new_user_in_course', null, get_lang('NewUserEmailAlertToTeacharAndTutor'), 2);
-$group[] = $form->createElement('radio', 'email_alert_to_teacher_on_new_user_in_course', null, get_lang('NewUserEmailAlertDisable'), 0);
+$group[] = $form->createElement(
+    'radio',
+    'email_alert_to_teacher_on_new_user_in_course',
+    get_lang('NewUserEmailAlert'),
+    get_lang('NewUserEmailAlertEnable'),
+    1
+);
+$group[] = $form->createElement(
+    'radio',
+    'email_alert_to_teacher_on_new_user_in_course',
+    null,
+    get_lang('NewUserEmailAlertToTeacharAndTutor'),
+    2
+);
+$group[] = $form->createElement(
+    'radio',
+    'email_alert_to_teacher_on_new_user_in_course',
+    null,
+    get_lang('NewUserEmailAlertDisable'),
+    0
+);
 $form->addGroup($group, '', [get_lang("NewUserEmailAlert")]);
 
 $group = [];
-$group[] = $form->createElement('radio', 'email_alert_students_on_new_homework', get_lang('NewHomeworkEmailAlert'), get_lang('NewHomeworkEmailAlertEnable'), 1);
-$group[] = $form->createElement('radio', 'email_alert_students_on_new_homework', null, get_lang('NewHomeworkEmailAlertToHrmEnable'), 2);
-$group[] = $form->createElement('radio', 'email_alert_students_on_new_homework', null, get_lang('NewHomeworkEmailAlertDisable'), 0);
+$group[] = $form->createElement(
+    'radio',
+    'email_alert_students_on_new_homework',
+    get_lang('NewHomeworkEmailAlert'),
+    get_lang('NewHomeworkEmailAlertEnable'),
+    1
+);
+$group[] = $form->createElement(
+    'radio',
+    'email_alert_students_on_new_homework',
+    null,
+    get_lang('NewHomeworkEmailAlertToHrmEnable'),
+    2
+);
+$group[] = $form->createElement(
+    'radio',
+    'email_alert_students_on_new_homework',
+    null,
+    get_lang('NewHomeworkEmailAlertDisable'),
+    0
+);
 $form->addGroup($group, '', [get_lang("NewHomeworkEmailAlert")]);
 
 $group = [];
-$group[] = $form->createElement('radio', 'email_alert_manager_on_new_doc', get_lang('WorkEmailAlert'), get_lang('WorkEmailAlertActivate'), 1);
-$group[] = $form->createElement('radio', 'email_alert_manager_on_new_doc', null, get_lang('WorkEmailAlertActivateOnlyForTeachers'), 3);
-$group[] = $form->createElement('radio', 'email_alert_manager_on_new_doc', null, get_lang('WorkEmailAlertActivateOnlyForStudents'), 2);
-$group[] = $form->createElement('radio', 'email_alert_manager_on_new_doc', null, get_lang('WorkEmailAlertDeactivate'), 0);
+$group[] = $form->createElement(
+    'radio',
+    'email_alert_manager_on_new_doc',
+    get_lang('WorkEmailAlert'),
+    get_lang('WorkEmailAlertActivate'),
+    1
+);
+$group[] = $form->createElement(
+    'radio',
+    'email_alert_manager_on_new_doc',
+    null,
+    get_lang('WorkEmailAlertActivateOnlyForTeachers'),
+    3
+);
+$group[] = $form->createElement(
+    'radio',
+    'email_alert_manager_on_new_doc',
+    null,
+    get_lang('WorkEmailAlertActivateOnlyForStudents'),
+    2
+);
+$group[] = $form->createElement(
+    'radio',
+    'email_alert_manager_on_new_doc',
+    null,
+    get_lang('WorkEmailAlertDeactivate'),
+    0
+);
 $form->addGroup($group, '', [get_lang("WorkEmailAlert")]);
 
 $group = [];
-$group[] = $form->createElement('radio', 'email_alert_on_new_doc_dropbox', get_lang('DropboxEmailAlert'), get_lang('DropboxEmailAlertActivate'), 1);
-$group[] = $form->createElement('radio', 'email_alert_on_new_doc_dropbox', null, get_lang('DropboxEmailAlertDeactivate'), 0);
+$group[] = $form->createElement(
+    'radio',
+    'email_alert_on_new_doc_dropbox',
+    get_lang('DropboxEmailAlert'),
+    get_lang('DropboxEmailAlertActivate'),
+    1
+);
+$group[] = $form->createElement(
+    'radio',
+    'email_alert_on_new_doc_dropbox',
+    null,
+    get_lang('DropboxEmailAlertDeactivate'),
+    0
+);
 $form->addGroup($group, '', [get_lang("DropboxEmailAlert")]);
 
 // Exercises notifications
@@ -389,7 +503,8 @@ $form->addHtml('<div class="panel panel-default">');
 $form->addHtml('
     <div class="panel-heading" role="tab" id="heading-user-right">
         <h4 class="panel-title">
-            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse-user-right" aria-expanded="false" aria-controls="collapse-user-right">
+            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion"
+               href="#collapse-user-right" aria-expanded="false" aria-controls="collapse-user-right">
 ');
 $form->addHtml(
     Display::return_icon('user.png', get_lang('UserRights')).' '.get_lang('UserRights')
@@ -405,23 +520,59 @@ $form->addHtml('
 ');
 
 $group = [];
-$group[] = $form->createElement('radio', 'allow_user_edit_agenda', get_lang('AllowUserEditAgenda'), get_lang('AllowUserEditAgendaActivate'), 1);
+$group[] = $form->createElement(
+    'radio',
+    'allow_user_edit_agenda',
+    get_lang('AllowUserEditAgenda'),
+    get_lang('AllowUserEditAgendaActivate'),
+    1
+);
 $group[] = $form->createElement('radio', 'allow_user_edit_agenda', null, get_lang('AllowUserEditAgendaDeactivate'), 0);
 $form->addGroup($group, '', [get_lang("AllowUserEditAgenda")]);
 
 $group = [];
-$group[] = $form->createElement('radio', 'allow_user_edit_announcement', get_lang('AllowUserEditAnnouncement'), get_lang('AllowUserEditAnnouncementActivate'), 1);
-$group[] = $form->createElement('radio', 'allow_user_edit_announcement', null, get_lang('AllowUserEditAnnouncementDeactivate'), 0);
+$group[] = $form->createElement(
+    'radio',
+    'allow_user_edit_announcement',
+    get_lang('AllowUserEditAnnouncement'),
+    get_lang('AllowUserEditAnnouncementActivate'),
+    1
+);
+$group[] = $form->createElement(
+    'radio',
+    'allow_user_edit_announcement',
+    null,
+    get_lang('AllowUserEditAnnouncementDeactivate'),
+    0
+);
 $form->addGroup($group, '', [get_lang("AllowUserEditAnnouncement")]);
 
 $group = [];
-$group[] = $form->createElement('radio', 'allow_user_image_forum', get_lang('AllowUserImageForum'), get_lang('AllowUserImageForumActivate'), 1);
+$group[] = $form->createElement(
+    'radio',
+    'allow_user_image_forum',
+    get_lang('AllowUserImageForum'),
+    get_lang('AllowUserImageForumActivate'),
+    1
+);
 $group[] = $form->createElement('radio', 'allow_user_image_forum', null, get_lang('AllowUserImageForumDeactivate'), 0);
 $form->addGroup($group, '', [get_lang("AllowUserImageForum")]);
 
 $group = [];
-$group[] = $form->createElement('radio', 'allow_user_view_user_list', get_lang('AllowUserViewUserList'), get_lang('AllowUserViewUserListActivate'), 1);
-$group[] = $form->createElement('radio', 'allow_user_view_user_list', null, get_lang('AllowUserViewUserListDeactivate'), 0);
+$group[] = $form->createElement(
+    'radio',
+    'allow_user_view_user_list',
+    get_lang('AllowUserViewUserList'),
+    get_lang('AllowUserViewUserListActivate'),
+    1
+);
+$group[] = $form->createElement(
+    'radio',
+    'allow_user_view_user_list',
+    null,
+    get_lang('AllowUserViewUserListDeactivate'),
+    0
+);
 $form->addGroup($group, '', [get_lang("AllowUserViewUserList")]);
 $form->addButtonSave(get_lang('SaveSettings'), 'submit_save');
 $form->addHtml('
@@ -435,7 +586,8 @@ $form->addHtml('<div class="panel panel-default">');
 $form->addHtml('
     <div class="panel-heading" role="tab" id="heading-chat-settings">
         <h4 class="panel-title">
-            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse-chat-settings" aria-expanded="false" aria-controls="collapse-chat-settings">
+            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion"
+               href="#collapse-chat-settings" aria-expanded="false" aria-controls="collapse-chat-settings">
 ');
 $form->addHtml(
     Display::return_icon('chat.png', get_lang('ConfigChat'), '', ICON_SIZE_SMALL).' '.get_lang('ConfigChat')
@@ -446,12 +598,19 @@ $form->addHtml('
     </div>
 ');
 $form->addHtml('
-    <div id="collapse-chat-settings" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-chat-settings">
+    <div id="collapse-chat-settings" class="panel-collapse collapse" role="tabpanel"
+         aria-labelledby="heading-chat-settings">
         <div class="panel-body">
 ');
 
 $group = [];
-$group[] = $form->createElement('radio', 'allow_open_chat_window', get_lang('AllowOpenchatWindow'), get_lang('AllowOpenChatWindowActivate'), 1);
+$group[] = $form->createElement(
+    'radio',
+    'allow_open_chat_window',
+    get_lang('AllowOpenchatWindow'),
+    get_lang('AllowOpenChatWindowActivate'),
+    1
+);
 $group[] = $form->createElement('radio', 'allow_open_chat_window', null, get_lang('AllowOpenChatWindowDeactivate'), 0);
 $form->addGroup($group, '', [get_lang("AllowOpenchatWindow")]);
 $form->addButtonSave(get_lang('SaveSettings'), 'submit_save');
@@ -467,7 +626,8 @@ $form->addHtml('<div class="panel panel-default">');
 $form->addHtml('
     <div class="panel-heading" role="tab" id="heading-learning-path">
         <h4 class="panel-title">
-            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse-learning-path" aria-expanded="false" aria-controls="collapse-learning-path">
+            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion"
+               href="#collapse-learning-path" aria-expanded="false" aria-controls="collapse-learning-path">
 ');
 $form->addHtml(
     Display::return_icon('scorms.png', get_lang('ConfigLearnpath')).' '.get_lang('ConfigLearnpath')
@@ -478,22 +638,47 @@ $form->addHtml('
     </div>
 ');
 $form->addHtml('
-    <div id="collapse-learning-path" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-learning-path">
+    <div id="collapse-learning-path" class="panel-collapse collapse" role="tabpanel"
+         aria-labelledby="heading-learning-path">
         <div class="panel-body">
 ');
 
 // Auto launch LP
 $group = [];
-$group[] = $form->createElement('radio', 'enable_lp_auto_launch', get_lang('LPAutoLaunch'), get_lang('RedirectToALearningPath'), 1);
-$group[] = $form->createElement('radio', 'enable_lp_auto_launch', get_lang('LPAutoLaunch'), get_lang('RedirectToTheLearningPathList'), 2);
+$group[] = $form->createElement(
+    'radio',
+    'enable_lp_auto_launch',
+    get_lang('LPAutoLaunch'),
+    get_lang('RedirectToALearningPath'),
+    1
+);
+$group[] = $form->createElement(
+    'radio',
+    'enable_lp_auto_launch',
+    get_lang('LPAutoLaunch'),
+    get_lang('RedirectToTheLearningPathList'),
+    2
+);
 $group[] = $form->createElement('radio', 'enable_lp_auto_launch', null, get_lang('Deactivate'), 0);
 $form->addGroup($group, '', [get_lang('LPAutoLaunch')]);
 
 if (api_get_setting('allow_course_theme') == 'true') {
     // Allow theme into Learning path
     $group = [];
-    $group[] = $form->createElement('radio', 'allow_learning_path_theme', get_lang('AllowLearningPathTheme'), get_lang('AllowLearningPathThemeAllow'), 1);
-    $group[] = $form->createElement('radio', 'allow_learning_path_theme', null, get_lang('AllowLearningPathThemeDisallow'), 0);
+    $group[] = $form->createElement(
+        'radio',
+        'allow_learning_path_theme',
+        get_lang('AllowLearningPathTheme'),
+        get_lang('AllowLearningPathThemeAllow'),
+        1
+    );
+    $group[] = $form->createElement(
+        'radio',
+        'allow_learning_path_theme',
+        null,
+        get_lang('AllowLearningPathThemeDisallow'),
+        0
+    );
     $form->addGroup($group, '', [get_lang("AllowLearningPathTheme")]);
 }
 
@@ -568,32 +753,26 @@ $form->addHtml('</div>');
 // Exercise
 if (api_get_configuration_value('allow_exercise_auto_launch')) {
     $form->addHtml('<div class="panel panel-default">');
-    $form->addHtml(
-        '
+    $form->addHtml('
         <div class="panel-heading" role="tab" id="heading-exercise">
             <h4 class="panel-title">
                 <a class="collapsed" 
-                role="button" data-toggle="collapse" 
-                data-parent="#accordion" 
-                href="#collapse-exercise" aria-expanded="false" aria-controls="collapse-exercise">
-    '
-    );
+                   role="button" data-toggle="collapse" 
+                   data-parent="#accordion" 
+                   href="#collapse-exercise" aria-expanded="false" aria-controls="collapse-exercise">
+    ');
     $form->addHtml(
         Display::return_icon('quiz.png', get_lang('Exercise')).' '.get_lang('Exercise')
     );
-    $form->addHtml(
-        '
+    $form->addHtml('
                 </a>
             </h4>
         </div>
-    '
-    );
-    $form->addHtml(
-        '
+    ');
+    $form->addHtml('
         <div id="collapse-exercise" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-exercise">
             <div class="panel-body">
-    '
-    );
+    ');
 
     // Auto launch exercise
     $group = [];
@@ -623,12 +802,10 @@ if (api_get_configuration_value('allow_exercise_auto_launch')) {
         }
         $form->freeze();
     }
-    $form->addHtml(
-        '
+    $form->addHtml('
             </div>
         </div>
-    '
-    );
+    ');
     $form->addHtml('</div>');
 }
 
@@ -637,13 +814,16 @@ $form->addHtml('<div class="panel panel-default">');
 $form->addHtml('
     <div class="panel-heading" role="tab" id="heading-advance-settings">
         <h4 class="panel-title">
-            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse-advance-settings" aria-expanded="false" aria-controls="collapse-advance-settings">
+            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion"
+               href="#collapse-advance-settings" aria-expanded="false" aria-controls="collapse-advance-settings">
 ');
 $form->addHtml(
     Display::return_icon(
         'course_progress.png',
         get_lang('ThematicAdvanceConfiguration')
-    ).' '.get_lang('ThematicAdvanceConfiguration')
+    )
+    .' '
+    .get_lang('ThematicAdvanceConfiguration')
 );
 $form->addHtml('
             </a>
@@ -651,7 +831,8 @@ $form->addHtml('
     </div>
 ');
 $form->addHtml('
-    <div id="collapse-advance-settings" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-advance-settings">
+    <div id="collapse-advance-settings" class="panel-collapse collapse" role="tabpanel"
+         aria-labelledby="heading-advance-settings">
         <div class="panel-body">
 ');
 
@@ -698,7 +879,8 @@ if (api_get_setting('allow_public_certificates') == 'true') {
     $form->addHtml('
         <div class="panel-heading" role="tab" id="heading-certificate-settings">
             <h4 class="panel-title">
-                <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse-certificate-settings" aria-expanded="false" aria-controls="collapse-certificate-settings">
+                <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" aria-expanded="false"
+                   href="#collapse-certificate-settings" aria-controls="collapse-certificate-settings">
     ');
     $form->addHtml(
         Display::return_icon('certificate.png', get_lang('Certificates')).' '.get_lang('Certificates')
@@ -709,12 +891,19 @@ if (api_get_setting('allow_public_certificates') == 'true') {
         </div>
     ');
     $form->addHtml('
-        <div id="collapse-certificate-settings" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-certificate-settings">
+        <div id="collapse-certificate-settings" class="panel-collapse collapse" role="tabpanel"
+             aria-labelledby="heading-certificate-settings">
             <div class="panel-body">
     ');
 
     $group = [];
-    $group[] = $form->createElement('radio', 'allow_public_certificates', get_lang('AllowPublicCertificates'), get_lang('Yes'), 1);
+    $group[] = $form->createElement(
+        'radio',
+        'allow_public_certificates',
+        get_lang('AllowPublicCertificates'),
+        get_lang('Yes'),
+        1
+    );
     $group[] = $form->createElement('radio', 'allow_public_certificates', null, get_lang('No'), 0);
     $form->addGroup($group, '', [get_lang('AllowPublicCertificates')]);
     $form->addButtonSave(get_lang('SaveSettings'), 'submit_save');
@@ -741,7 +930,8 @@ $form->addHtml('
     </div>
 ');
 $form->addHtml('
-    <div id="collapse-forum-settings" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-forum-settings">
+    <div id="collapse-forum-settings" class="panel-collapse collapse" role="tabpanel"
+         aria-labelledby="heading-forum-settings">
         <div class="panel-body">
 ');
 
@@ -839,7 +1029,9 @@ if ($form->validate() && is_settings_editable()) {
         }
     }
 
-    $pdf_export_watermark_path = isset($_FILES['pdf_export_watermark_path']) ? $_FILES['pdf_export_watermark_path'] : null;
+    $pdf_export_watermark_path = isset($_FILES['pdf_export_watermark_path'])
+        ? $_FILES['pdf_export_watermark_path']
+        : null;
 
     if (!empty($pdf_export_watermark_path['name'])) {
         $pdf_export_watermark_path_result = PDF::upload_watermark(

+ 5 - 5
main/dashboard/index.php

@@ -36,7 +36,7 @@ if (isset($_GET['action']) && in_array($_GET['action'], $actions)) {
 $htmlHeadXtra[] = DashboardManager::getStyleSheet();
 
 // course description controller object
-$dashboard_controller = new DashboardController();
+$dashboardController = new DashboardController();
 
 if (isset($_GET['path'])) {
     $path = $_GET['path'];
@@ -45,14 +45,14 @@ if (isset($_GET['path'])) {
 // distpacher actions to controller
 switch ($action) {
     case 'listing':
-        $dashboard_controller->display();
+        $dashboardController->display();
         break;
     case 'store_user_block':
-        $dashboard_controller->store_user_block();
+        $dashboardController->store_user_block();
         break;
     case 'disable_block':
-        $dashboard_controller->close_user_block($path);
+        $dashboardController->close_user_block($path);
         break;
     default:
-        $dashboard_controller->display();
+        $dashboardController->display();
 }

+ 3 - 2
main/document/document.php

@@ -328,6 +328,7 @@ switch ($action) {
         }
         // Launch event
         Event::event_download($document_data['url']);
+
         // Check visibility of document and paths
         if (!($isAllowedToEdit || $groupMemberWithUploadRights) &&
             !DocumentManager::is_visible_by_id($document_id, $courseInfo, $sessionId, api_get_user_id())
@@ -393,7 +394,6 @@ switch ($action) {
                 : 'landscape';
 
             $showHeaderAndFooter = true;
-
             if ($is_certificate_mode) {
                 $certificateOrientation = api_get_configuration_value('certificate_pdf_orientation');
                 $orientation = in_array($certificateOrientation, ['landscape', 'portrait'])
@@ -529,7 +529,8 @@ switch ($action) {
                 get_lang('ConversionToSameFileFormat'),
                 'warning'
             ));
-        } elseif (!(in_array($fileInfo['extension'], DocumentManager::getJodconverterExtensionList('from', $formatType))) ||
+        } elseif (
+            !(in_array($fileInfo['extension'], DocumentManager::getJodconverterExtensionList('from', $formatType))) ||
             !(in_array($formatTarget, DocumentManager::getJodconverterExtensionList('to', $formatType)))
         ) {
             Display::addFlash(Display::return_message(

+ 1 - 1
main/exercise/Draggable.php

@@ -55,7 +55,7 @@ class Draggable extends Question
             $answer = new Answer($this->id);
             $answer->read();
 
-            if (count($answer->nbrAnswers) > 0) {
+            if ($answer->nbrAnswers > 0) {
                 $nb_matches = $nb_options = 0;
                 for ($i = 1; $i <= $answer->nbrAnswers; $i++) {
                     if ($answer->isCorrect($i)) {

+ 2 - 2
main/exercise/MatchingDraggable.php

@@ -35,7 +35,7 @@ class MatchingDraggable extends Question
             $answer = new Answer($this->id);
             $answer->read();
 
-            if (!empty($answer->nbrAnswers) && count($answer->nbrAnswers) > 0) {
+            if ($answer->nbrAnswers > 0) {
                 for ($i = 1; $i <= $answer->nbrAnswers; $i++) {
                     $correct = $answer->isCorrect($i);
                     if (empty($correct)) {
@@ -58,7 +58,7 @@ class MatchingDraggable extends Question
                 $nb_options++;
             }
         } elseif (!empty($this->id)) {
-            if (count($answer->nbrAnswers) > 0) {
+            if ($answer->nbrAnswers > 0) {
                 $nb_matches = $nb_options = 0;
                 for ($i = 1; $i <= $answer->nbrAnswers; $i++) {
                     if ($answer->isCorrect($i)) {

+ 1 - 1
main/exercise/UniqueAnswerImage.php

@@ -77,7 +77,7 @@ class UniqueAnswerImage extends UniqueAnswer
             $answer = new Answer($this->id);
             $answer->read();
 
-            if (count($answer->nbrAnswers) > 0 && !$form->isSubmitted()) {
+            if ($answer->nbrAnswers > 0 && !$form->isSubmitted()) {
                 $numberAnswers = $answer->nbrAnswers;
             }
         }

+ 85 - 77
main/exercise/exercise.class.php

@@ -12,7 +12,7 @@ use ChamiloSession as Session;
  *
  * @package chamilo.exercise
  *
- * @todo use doctrine object, use getters and setters correctly
+ * @todo use getters and setters correctly
  *
  * @author Olivier Brouckaert
  * @author Julio Montoya Cleaning exercises
@@ -124,12 +124,12 @@ class Exercise
         $this->notifications = [];
 
         if (!empty($courseId)) {
-            $course_info = api_get_course_info_by_id($courseId);
+            $courseInfo = api_get_course_info_by_id($courseId);
         } else {
-            $course_info = api_get_course_info();
+            $courseInfo = api_get_course_info();
         }
-        $this->course_id = $course_info['real_id'];
-        $this->course = $course_info;
+        $this->course_id = $courseInfo['real_id'];
+        $this->course = $courseInfo;
         $this->sessionId = api_get_session_id();
 
         // ALTER TABLE c_quiz_question ADD COLUMN feedback text;
@@ -454,7 +454,7 @@ class Exercise
      *
      * @return int - quiz random by category
      */
-    public function selectRandomByCat()
+    public function getRandomByCategory()
     {
         return $this->randomByCat;
     }
@@ -520,11 +520,12 @@ class Exercise
      *
      * @author Olivier Brouckaert
      *
-     * @return int - 0 if not random, otherwise the draws
+     * @return bool
      */
     public function isRandom()
     {
         $isRandom = false;
+        // "-1" means all questions will be random
         if ($this->random > 0 || $this->random == -1) {
             $isRandom = true;
         }
@@ -537,7 +538,7 @@ class Exercise
      *
      * @author Juan Carlos Rana
      */
-    public function selectRandomAnswers()
+    public function getRandomAnswers()
     {
         return $this->random_answers;
     }
@@ -1047,7 +1048,7 @@ class Exercise
                     if ($this->random == 0 || $nbQuestions < 2) {
                         $questionList = $this->getQuestionOrderedList();
                     } else {
-                        $questionList = $this->selectRandomList($adminView);
+                        $questionList = $this->getRandomList($adminView);
                     }
                     break;
                 default:
@@ -1107,22 +1108,29 @@ class Exercise
      * @return array - if the exercise is not set to take questions randomly, returns the question list
      *               without randomizing, otherwise, returns the list with questions selected randomly
      */
-    public function selectRandomList($adminView = false)
+    public function getRandomList($adminView = false)
     {
-        $TBL_EXERCISE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
-        $TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
+        $quizRelQuestion = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
+        $question = Database::get_course_table(TABLE_QUIZ_QUESTION);
         $random = isset($this->random) && !empty($this->random) ? $this->random : 0;
 
+        // Random with limit
         $randomLimit = "ORDER BY RAND() LIMIT $random";
-        // Random all questions so no limit
-        if ($random == -1 or $adminView === true) {
+
+        // Random with no limit
+        if ($random == -1) {
+            $randomLimit = "ORDER BY RAND() ";
+        }
+
+        // Admin see the list in default order
+        if ($adminView === true) {
             // If viewing it as admin for edition, don't show it randomly, use title + id
             $randomLimit = 'ORDER BY e.question_order';
         }
 
         $sql = "SELECT e.question_id
-                FROM $TBL_EXERCISE_QUESTION e 
-                INNER JOIN $TBL_QUESTIONS q
+                FROM $quizRelQuestion e 
+                INNER JOIN $question q
                 ON (e.question_id= q.id AND e.c_id = q.c_id)
                 WHERE 
                     e.c_id = {$this->course_id} AND 
@@ -2441,7 +2449,7 @@ class Exercise
                     $defaults['randomQuestions'] = $this->random;
                 }
 
-                $defaults['randomAnswers'] = $this->selectRandomAnswers();
+                $defaults['randomAnswers'] = $this->getRandomAnswers();
                 $defaults['exerciseType'] = $this->selectType();
                 $defaults['exerciseTitle'] = $this->get_formated_title();
                 $defaults['exerciseDescription'] = $this->selectDescription();
@@ -2451,7 +2459,7 @@ class Exercise
                 $defaults['propagate_neg'] = $this->selectPropagateNeg();
                 $defaults['save_correct_answers'] = $this->selectSaveCorrectAnswers();
                 $defaults['review_answers'] = $this->review_answers;
-                $defaults['randomByCat'] = $this->selectRandomByCat();
+                $defaults['randomByCat'] = $this->getRandomByCategory();
                 $defaults['text_when_finished'] = $this->selectTextWhenFinished();
                 $defaults['display_category_name'] = $this->selectDisplayCategoryName();
                 $defaults['pass_percentage'] = $this->selectPassPercentage();
@@ -2816,7 +2824,7 @@ class Exercise
      *
      * @return int quantity of user's exercises deleted
      */
-    public function clean_results($cleanLpTests = false, $cleanResultBeforeDate = null)
+    public function cleanResults($cleanLpTests = false, $cleanResultBeforeDate = null)
     {
         $table_track_e_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
         $table_track_e_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
@@ -2871,7 +2879,7 @@ class Exercise
                 WHERE c_id = ".api_get_course_int_id()."
                 AND exe_exo_id = ".$this->id."
                 $sql_where
-                AND session_id = ".$session_id."";
+                AND session_id = ".$session_id;
         Database::query($sql);
 
         Event::addEvent(
@@ -2912,7 +2920,6 @@ class Exercise
                     $newQuestionObj = Question::read($newQuestionId);
                     if (isset($newQuestionObj) && $newQuestionObj) {
                         $newQuestionObj->addToList($newId);
-
                         if (!empty($oldQuestionObj->category)) {
                             $newQuestionObj->saveCategory($oldQuestionObj->category);
                         }
@@ -5798,7 +5805,7 @@ class Exercise
         }
 
         if ($sendEndOpenQuestion) {
-            $this->send_notification_for_open_questions(
+            $this->sendNotificationForOpenQuestions(
                 $question_list_answers,
                 $origin,
                 $exe_id,
@@ -5809,7 +5816,7 @@ class Exercise
         }
 
         if ($sendEndOralQuestion) {
-            $this->send_notification_for_oral_questions(
+            $this->sendNotificationForOralQuestions(
                 $question_list_answers,
                 $origin,
                 $exe_id,
@@ -6108,11 +6115,10 @@ class Exercise
             }
         }
 
-        //3. We check if the time limits are on
+        // 3. We check if the time limits are on
+        $limitTimeExists = false;
         if (!empty($this->start_time) || !empty($this->end_time)) {
             $limitTimeExists = true;
-        } else {
-            $limitTimeExists = false;
         }
 
         if ($limitTimeExists) {
@@ -6453,7 +6459,7 @@ class Exercise
         $isRandomByCategory = $this->isRandomByCat();
         if ($isRandomByCategory == 0) {
             if ($this->isRandom()) {
-                $result = $this->selectRandomList();
+                $result = $this->getRandomList();
             } else {
                 $result = $this->selectQuestionList();
             }
@@ -6466,7 +6472,7 @@ class Exercise
                 // value is the array of question id of this category
                 $questionList = [];
                 $tabCategoryQuestions = TestCategory::getQuestionsByCat($this->id);
-                $isRandomByCategory = $this->selectRandomByCat();
+                $isRandomByCategory = $this->getRandomByCategory();
                 // We sort categories based on the term between [] in the head
                 // of the category's description
                 /* examples of categories :
@@ -7276,24 +7282,26 @@ class Exercise
                     );
                     break;
                 case ALL_ON_ONE_PAGE:
-                    $button = [
-                        Display::button(
-                            'save_now',
-                            get_lang('SaveForNow'),
-                            ['type' => 'button', 'class' => 'btn btn-primary', 'data-question' => $questionId]
-                        ),
-                        '<span id="save_for_now_'.$questionId.'" class="exercise_save_mini_message"></span>',
-                    ];
-                    $exercise_actions .= Display::div(
-                        implode(PHP_EOL, $button),
-                        ['class' => 'exercise_save_now_button']
-                    );
+                    if (api_is_allowed_to_session_edit()) {
+                        $button = [
+                            Display::button(
+                                'save_now',
+                                get_lang('SaveForNow'),
+                                ['type' => 'button', 'class' => 'btn btn-primary', 'data-question' => $questionId]
+                            ),
+                            '<span id="save_for_now_'.$questionId.'" class="exercise_save_mini_message"></span>',
+                        ];
+                        $exercise_actions .= Display::div(
+                            implode(PHP_EOL, $button),
+                            ['class' => 'exercise_save_now_button']
+                        );
+                    }
                     break;
             }
 
             if (!empty($questions_in_media)) {
                 $count_of_questions_inside_media = count($questions_in_media);
-                if ($count_of_questions_inside_media > 1) {
+                if ($count_of_questions_inside_media > 1 && api_is_allowed_to_session_edit()) {
                     $button = [
                         Display::button(
                             'save_now',
@@ -8021,7 +8029,7 @@ class Exercise
      * @param string $origin
      * @param int    $exe_id
      */
-    private function send_notification_for_open_questions(
+    private function sendNotificationForOpenQuestions(
         $question_list_answers,
         $origin,
         $exe_id,
@@ -8031,7 +8039,7 @@ class Exercise
     ) {
         // Email configuration settings
         $courseCode = api_get_course_id();
-        $course_info = api_get_course_info($courseCode);
+        $courseInfo = api_get_course_info($courseCode);
 
         $msg = get_lang('OpenQuestionsAttempted').'<br /><br />'
                     .get_lang('AttemptDetails').' : <br /><br />'
@@ -8081,7 +8089,7 @@ class Exercise
             $msg = str_replace("#firstName#", $user_info['firstname'], $msg1);
             $msg1 = str_replace("#lastName#", $user_info['lastname'], $msg);
             $msg = str_replace("#mail#", $user_info['email'], $msg1);
-            $msg = str_replace("#course#", $course_info['name'], $msg1);
+            $msg = str_replace("#course#", $courseInfo['name'], $msg1);
 
             if ($origin != 'learnpath') {
                 $msg .= '<br /><a href="#url#">'.get_lang('ClickToCommentAndGiveFeedback').'</a>';
@@ -8112,7 +8120,7 @@ class Exercise
      * @param string $url_email
      * @param array  $teachers
      */
-    private function send_notification_for_oral_questions(
+    private function sendNotificationForOralQuestions(
         $question_list_answers,
         $origin,
         $exe_id,
@@ -8122,8 +8130,7 @@ class Exercise
     ) {
         // Email configuration settings
         $courseCode = api_get_course_id();
-        $course_info = api_get_course_info($courseCode);
-
+        $courseInfo = api_get_course_info($courseCode);
         $oral_question_list = null;
         foreach ($question_list_answers as $item) {
             $question = $item['question'];
@@ -8137,45 +8144,46 @@ class Exercise
                 if (!empty($file)) {
                     $file = Display::url($file, $file);
                 }
-                $oral_question_list .= '<br /><table width="730" height="136" border="0" cellpadding="3" cellspacing="3">'
-                    .'<tr>'
-                        .'<td width="220" valign="top" bgcolor="#E5EDF8">&nbsp;&nbsp;'.get_lang('Question').'</td>'
-                        .'<td width="473" valign="top" bgcolor="#F3F3F3">'.$question.'</td>'
-                    .'</tr>'
-                    .'<tr>'
-                        .'<td width="220" valign="top" bgcolor="#E5EDF8">&nbsp;&nbsp;'.get_lang('Answer').'</td>'
-                        .'<td valign="top" bgcolor="#F3F3F3">'.$answer.$file.'</td>'
-                    .'</tr></table>';
+                $oral_question_list .= '<br />
+                    <table width="730" height="136" border="0" cellpadding="3" cellspacing="3">
+                    <tr>
+                        <td width="220" valign="top" bgcolor="#E5EDF8">&nbsp;&nbsp;'.get_lang('Question').'</td>
+                        <td width="473" valign="top" bgcolor="#F3F3F3">'.$question.'</td>
+                    </tr>
+                    <tr>
+                        <td width="220" valign="top" bgcolor="#E5EDF8">&nbsp;&nbsp;'.get_lang('Answer').'</td>
+                        <td valign="top" bgcolor="#F3F3F3">'.$answer.$file.'</td>
+                    </tr></table>';
             }
         }
 
         if (!empty($oral_question_list)) {
             $msg = get_lang('OralQuestionsAttempted').'<br /><br />
-                    '.get_lang('AttemptDetails').' : <br /><br />'
-                    .'<table>'
-                        .'<tr>'
-                            .'<td><em>'.get_lang('CourseName').'</em></td>'
-                            .'<td>&nbsp;<b>#course#</b></td>'
-                        .'</tr>'
-                        .'<tr>'
-                            .'<td>'.get_lang('TestAttempted').'</td>'
-                            .'<td>&nbsp;#exercise#</td>'
-                        .'</tr>'
-                        .'<tr>'
-                            .'<td>'.get_lang('StudentName').'</td>'
-                            .'<td>&nbsp;#firstName# #lastName#</td>'
-                        .'</tr>'
-                        .'<tr>'
-                            .'<td>'.get_lang('StudentEmail').'</td>'
-                            .'<td>&nbsp;#mail#</td>'
-                        .'</tr>'
-                    .'</table>';
+                    '.get_lang('AttemptDetails').' : <br /><br />
+                    <table>
+                        <tr>
+                            <td><em>'.get_lang('CourseName').'</em></td>
+                            <td>&nbsp;<b>#course#</b></td>
+                        </tr>
+                        <tr>
+                            <td>'.get_lang('TestAttempted').'</td>
+                            <td>&nbsp;#exercise#</td>
+                        </tr>
+                        <tr>
+                            <td>'.get_lang('StudentName').'</td>
+                            <td>&nbsp;#firstName# #lastName#</td>
+                        </tr>
+                        <tr>
+                            <td>'.get_lang('StudentEmail').'</td>
+                            <td>&nbsp;#mail#</td>
+                        </tr>
+                    </table>';
             $msg .= '<br />'.sprintf(get_lang('OralQuestionsAttemptedAreX'), $oral_question_list).'<br />';
             $msg1 = str_replace("#exercise#", $this->exercise, $msg);
             $msg = str_replace("#firstName#", $user_info['firstname'], $msg1);
             $msg1 = str_replace("#lastName#", $user_info['lastname'], $msg);
             $msg = str_replace("#mail#", $user_info['email'], $msg1);
-            $msg = str_replace("#course#", $course_info['name'], $msg1);
+            $msg = str_replace("#course#", $courseInfo['name'], $msg1);
 
             if ($origin != 'learnpath') {
                 $msg .= '<br /><a href="#url#">'.get_lang('ClickToCommentAndGiveFeedback').'</a>';
@@ -8225,7 +8233,7 @@ class Exercise
                 if (isset($objQuestionTmp->parent_id) && $objQuestionTmp->parent_id != 0) {
                     $mediaList[$objQuestionTmp->parent_id][] = $objQuestionTmp->id;
                 } else {
-                    //Always the last item
+                    // Always the last item
                     $mediaList[999][] = $objQuestionTmp->id;
                 }
             }

+ 2 - 2
main/exercise/exercise.php

@@ -184,7 +184,7 @@ if ($is_allowedToEdit) {
                     if ($exercise_action_locked == false) {
                         $objExerciseTmp = new Exercise();
                         if ($objExerciseTmp->read($exeItem['id'])) {
-                            $quantity_results_deleted += $objExerciseTmp->clean_results(true);
+                            $quantity_results_deleted += $objExerciseTmp->cleanResults(true);
                         }
                     }
                 }
@@ -302,7 +302,7 @@ if ($is_allowedToEdit) {
                     case 'clean_results':
                         //clean student results
                         if ($exercise_action_locked == false) {
-                            $quantity_results_deleted = $objExerciseTmp->clean_results(true);
+                            $quantity_results_deleted = $objExerciseTmp->cleanResults(true);
                             $title = $objExerciseTmp->selectTitle();
                             echo Display::return_message(
                                 $title.': '.sprintf(

+ 2 - 2
main/exercise/exercise_report.php

@@ -456,7 +456,7 @@ if (($is_allowedToEdit || $is_tutor || api_is_coach()) &&
     if ($check) {
         $objExerciseTmp = new Exercise();
         if ($objExerciseTmp->read($exercise_id)) {
-            $count = $objExerciseTmp->clean_results(
+            $count = $objExerciseTmp->cleanResults(
                 true,
                 $_GET['delete_before_date'].' 23:59:59'
             );
@@ -812,7 +812,7 @@ $extra_params['height'] = 'auto';
                 // Format the date for confirm box
                 var dateFormat = $( "#datepicker_start" ).datepicker( "option", "dateFormat" );
                 var selectedDate = $.datepicker.formatDate(dateFormat, dateTypeVar);
-                if (confirm("<?php echo convert_double_quote_to_single(get_lang('AreYouSureDeleteTestResultBeforeDateD')); ?>" + selectedDate)) {
+                if (confirm("<?php echo convert_double_quote_to_single(get_lang('AreYouSureDeleteTestResultBeforeDateD')).' '; ?>" + selectedDate)) {
                     self.location.href = "exercise_report.php?<?php echo api_get_cidreq(); ?>&exerciseId=<?php echo $exercise_id; ?>&delete_before_date="+dateForBDD+"&sec_token=<?php echo $token; ?>";
                 }
             }

+ 30 - 27
main/exercise/exercise_submit.php

@@ -434,7 +434,7 @@ if (!isset($questionListInSession)) {
     if ($media_is_activated == false &&
         (
             $objExercise->isRandom() ||
-            !empty($objExercise->selectRandomByCat()) ||
+            !empty($objExercise->getRandomByCategory()) ||
             $objExercise->getQuestionSelectionType() > 2
         ) &&
         isset($exercise_stat_info) &&
@@ -491,7 +491,10 @@ if ($time_control) {
     if ($debug) {
         error_log('7.1. Time control is enabled');
         error_log('7.2. $current_expired_time_key  '.$current_expired_time_key);
-        error_log('7.3. $_SESSION[expired_time][$current_expired_time_key]  '.$_SESSION['expired_time'][$current_expired_time_key]);
+        error_log(
+            '7.3. $_SESSION[expired_time][$current_expired_time_key] '.
+            $_SESSION['expired_time'][$current_expired_time_key]
+        );
     }
 
     if (!isset($_SESSION['expired_time'][$current_expired_time_key])) {
@@ -510,7 +513,9 @@ if ($time_control) {
                the track_et_attempt see #2069 */
             if (empty($last_attempt_date)) {
                 $diff = $current_timestamp - api_strtotime($exercise_stat_info['start_date'], 'UTC');
-                $last_attempt_date = api_get_utc_datetime(api_strtotime($exercise_stat_info['start_date'], 'UTC') + $diff);
+                $last_attempt_date = api_get_utc_datetime(
+                    api_strtotime($exercise_stat_info['start_date'], 'UTC') + $diff
+                );
             } else {
                 //Recalculate the time control due #2069
                 $diff = $current_timestamp - api_strtotime($last_attempt_date, 'UTC');
@@ -756,7 +761,7 @@ if ($question_count != 0) {
                     error_log('12. Exercise ALL_ON_ONE_PAGE -> Redirecting to exercise_result.php');
                 }
 
-                //We check if the user attempts before sending to the exercise_result.php
+                // We check if the user attempts before sending to the exercise_result.php
                 if ($objExercise->selectAttempts() > 0) {
                     $attempt_count = Event::get_attempt_count(
                         api_get_user_id(),
@@ -774,7 +779,7 @@ if ($question_count != 0) {
                         if ($origin != 'learnpath') {
                             //so we are not in learnpath tool
                             echo '</div>'; //End glossary div
-                            Display :: display_footer();
+                            Display::display_footer();
                         } else {
                             echo '</body></html>';
                         }
@@ -790,17 +795,12 @@ if ($question_count != 0) {
                     exit;
                 }
             }
-        } else {
-            if ($debug) {
-                error_log('Redirecting to exercise_submit.php');
-            }
-            exit;
         }
     }
 } else {
     $error = get_lang('ThereAreNoQuestionsForThisExercise');
     // if we are in the case where user select random by category, but didn't choose the number of random question
-    if ($objExercise->selectRandomByCat() > 0 && $objExercise->random <= 0) {
+    if ($objExercise->getRandomByCategory() > 0 && $objExercise->random <= 0) {
         $error .= "<br/>".get_lang('PleaseSelectSomeRandomQuestion');
     }
 }
@@ -1054,12 +1054,13 @@ if (!empty($error)) {
         function addExerciseEvent(elm, evType, fn, useCapture) {
             if (elm.addEventListener) {
                 elm.addEventListener(evType, fn, useCapture);
-                return true;
+                return;
             } else if (elm.attachEvent) {
                 elm.attachEvent(\'on\' + evType, fn);
             } else{
                 elm[\'on\'+evType] = fn;
-            }
+            }            
+            return;
         }
         
         var calledUpdateDuration = false;
@@ -1073,10 +1074,10 @@ if (!empty($error)) {
                     url: saveDurationUrl,
                     success: function (data) {
                         calledUpdateDuration = true;
-                        return 1;
+                        return;
                     }, 
                 });
-                return 1;
+                return;
             }
         }
         
@@ -1428,18 +1429,20 @@ if (!empty($error)) {
                 );
                 break;
             case ALL_ON_ONE_PAGE:
-                $button = [
-                    Display::button(
-                        'save_now',
-                        get_lang('SaveForNow'),
-                        ['type' => 'button', 'class' => 'btn btn-info', 'data-question' => $questionId]
-                    ),
-                    '<span id="save_for_now_'.$questionId.'"></span>&nbsp;',
-                ];
-                $exerciseActions .= Display::div(
-                    implode(PHP_EOL, $button),
-                    ['class' => 'exercise_save_now_button']
-                );
+                if (api_is_allowed_to_session_edit()) {
+                    $button = [
+                        Display::button(
+                            'save_now',
+                            get_lang('SaveForNow'),
+                            ['type' => 'button', 'class' => 'btn btn-info', 'data-question' => $questionId]
+                        ),
+                        '<span id="save_for_now_'.$questionId.'"></span>&nbsp;',
+                    ];
+                    $exerciseActions .= Display::div(
+                        implode(PHP_EOL, $button),
+                        ['class' => 'exercise_save_now_button']
+                    );
+                }
                 break;
         }
 

+ 2 - 2
main/exercise/matching.class.php

@@ -42,7 +42,7 @@ class Matching extends Question
         if (isset($this->id)) {
             $answer = new Answer($this->id);
             $answer->read();
-            if (!empty($answer->nbrAnswers) && count($answer->nbrAnswers) > 0) {
+            if ($answer->nbrAnswers > 0) {
                 for ($i = 1; $i <= $answer->nbrAnswers; $i++) {
                     $correct = $answer->isCorrect($i);
                     if (empty($correct)) {
@@ -65,7 +65,7 @@ class Matching extends Question
                 $nb_options++;
             }
         } elseif (!empty($this->id)) {
-            if (count($answer->nbrAnswers) > 0) {
+            if ($answer->nbrAnswers > 0) {
                 $nb_matches = $nb_options = 0;
                 for ($i = 1; $i <= $answer->nbrAnswers; $i++) {
                     if ($answer->isCorrect($i)) {

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

@@ -67,7 +67,7 @@ class MultipleAnswer extends Question
         if (!empty($this->id)) {
             $answer = new Answer($this->id);
             $answer->read();
-            if (count($answer->nbrAnswers) > 0 && !$form->isSubmitted()) {
+            if ($answer->nbrAnswers > 0 && !$form->isSubmitted()) {
                 $nb_answers = $answer->nbrAnswers;
             }
         }

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

@@ -59,7 +59,7 @@ class MultipleAnswerCombination extends Question
         if (!empty($this->id)) {
             $answer = new Answer($this->id);
             $answer->read();
-            if (count($answer->nbrAnswers) > 0 && !$form->isSubmitted()) {
+            if ($answer->nbrAnswers > 0 && !$form->isSubmitted()) {
                 $nb_answers = $answer->nbrAnswers;
             }
         }

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

@@ -69,7 +69,7 @@ class MultipleAnswerTrueFalse extends Question
             $answer = new Answer($this->id);
             $answer->read();
 
-            if (count($answer->nbrAnswers) > 0 && !$form->isSubmitted()) {
+            if ($answer->nbrAnswers > 0 && !$form->isSubmitted()) {
                 $nb_answers = $answer->nbrAnswers;
             }
         }

+ 23 - 4
main/exercise/showinframes.php

@@ -74,19 +74,38 @@ if ($title == '') {
     $title = basename($my_file);
 }
 $nameTools = $title;
-$htmlHeadXtra[] = /** @lang HTML */<<<HTML
+$htmlHeadXtra[] = <<<HTML
     <script>
+        function setHeight()
+        {
+            var iframe = document.getElementById('hotpotatoe');
+            iframe.height = 800;
+            var maxheight = $(iframe.contentDocument.body).outerHeight(true);
+            iframe.height = maxheight
+            $(iframe.contentDocument.body).children().each(function() {
+                // If this elements height is bigger than the biggestHeight
+                var tempheight = $(this)["0"].offsetHeight + $(this)["0"].offsetTop;
+                if (tempheight > maxheight) {
+                    // Set the maxheight to this Height
+                    maxheight = tempheight;
+                }
+            });
+            iframe.height = maxheight;
+        }
+        
         $(document).on('ready', function () {
             var iframe = document.getElementById('hotpotatoe');
-
             iframe.onload = function () {
-                this.height = $(this.contentDocument.body).outerHeight(true)
+                // this.height = $(this.contentDocument.body).outerHeight(true)
+                setTimeout(function(){
+                   setHeight();
+                }, 1750);
             };
         });
     </script>
 HTML;
 
-$interbreadcrumb[] = ["url" => "./exercise.php", "name" => get_lang('Exercises')];
+$interbreadcrumb[] = ["url" => './exercise.php?'.api_get_cidreq(), 'name' => get_lang('Exercises')];
 if ($origin == 'learnpath') {
     Display::display_reduced_header($nameTools, "Exercise");
 } else {

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

@@ -87,7 +87,7 @@ class UniqueAnswer extends Question
         if (!empty($this->id)) {
             $answer = new Answer($this->id);
             $answer->read();
-            if (count($answer->nbrAnswers) > 0 && !$form->isSubmitted()) {
+            if ($answer->nbrAnswers > 0 && !$form->isSubmitted()) {
                 $nb_answers = $answer->nbrAnswers;
             }
         }

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

@@ -84,7 +84,7 @@ class UniqueAnswerNoOption extends Question
         if (!empty($this->id)) {
             $answer = new Answer($this->id);
             $answer->read();
-            if (count($answer->nbrAnswers) > 0 && !$form->isSubmitted()) {
+            if ($answer->nbrAnswers > 0 && !$form->isSubmitted()) {
                 $nb_answers = $answer->nbrAnswers;
             }
         }

+ 2 - 2
main/group/group.php

@@ -105,7 +105,7 @@ if (api_is_allowed_to_edit(false, true)) {
                 if (is_array($_POST['group'])) {
                     foreach ($_POST['group'] as $myGroupId) {
                         $groupInfo = GroupManager::get_group_properties($myGroupId);
-                        GroupManager::delete_groups($groupInfo);
+                        GroupManager::deleteGroup($groupInfo);
                     }
 
                     Display::addFlash(Display::return_message(get_lang('SelectedGroupsDeleted')));
@@ -150,7 +150,7 @@ if (api_is_allowed_to_edit(false, true)) {
                 break;
             case 'delete_one':
                 $groupInfo = GroupManager::get_group_properties($my_get_id);
-                GroupManager::delete_groups($groupInfo);
+                GroupManager::deleteGroup($groupInfo);
                 Display::addFlash(Display::return_message(get_lang('GroupDel')));
                 header("Location: $currentUrl");
                 exit;

+ 4 - 3
main/group/member_settings.php

@@ -197,17 +197,18 @@ $form->addButtonSave(get_lang('SaveSettings'));
 
 if ($form->validate()) {
     $values = $form->exportValues();
+
     // Storing the users (we first remove all users and then add only those who were selected)
-    GroupManager:: unsubscribe_all_users($current_group);
+    GroupManager::unsubscribe_all_users($current_group);
     if (isset($_POST['group_members']) && count($_POST['group_members']) > 0) {
-        GroupManager:: subscribe_users(
+        GroupManager::subscribe_users(
             $values['group_members'],
             $current_group
         );
     }
 
     // Returning to the group area (note: this is inconsistent with the rest of chamilo)
-    $cat = GroupManager :: get_category_from_group($current_group['iid']);
+    $cat = GroupManager::get_category_from_group($current_group['iid']);
     if (isset($_POST['group_members']) &&
         count($_POST['group_members']) > $max_member &&
         $max_member != GroupManager::MEMBER_PER_GROUP_NO_LIMIT

+ 84 - 54
main/inc/ajax/lp.ajax.php

@@ -12,7 +12,7 @@ api_protect_course_script(true);
 $debug = false;
 $action = isset($_REQUEST['a']) ? $_REQUEST['a'] : '';
 
-$course_id = api_get_course_int_id();
+$courseId = api_get_course_int_id();
 $sessionId = api_get_session_id();
 
 if ($debug) {
@@ -57,7 +57,7 @@ switch ($action) {
                 $parentId = isset($_REQUEST['parent_id']) ? $_REQUEST['parent_id'] : '';
                 $previousId = isset($_REQUEST['previous_id']) ? $_REQUEST['previous_id'] : '';
 
-                echo $learningPath->add_item(
+                $itemId = $learningPath->add_item(
                     $parentId,
                     $previousId,
                     $_REQUEST['type'],
@@ -65,6 +65,12 @@ switch ($action) {
                     $title,
                     null
                 );
+
+                /** @var learnpath $learningPath */
+                $learningPath = Session::read('oLP');
+                if ($learningPath) {
+                    echo $learningPath->returnLpItemList(null);
+                }
             }
         }
         break;
@@ -75,53 +81,52 @@ switch ($action) {
             $new_array = [];
 
             // We have to update parent_item_id, previous_item_id, next_item_id, display_order in the database
-            $LP_item_list = new LP_item_order_list();
+            $itemList = new LpItemOrderList();
             foreach ($sections as $items) {
                 if (!empty($items)) {
                     list($id, $parent_id) = explode('|', $items);
-                    $item = new LP_item_order_item($id, $parent_id);
-                    $LP_item_list->add($item);
+                    $item = new LpOrderItem($id, $parent_id);
+                    $itemList->add($item);
                 }
             }
 
-            $tab_parents_id = $LP_item_list->get_list_of_parents();
-
-            foreach ($tab_parents_id as $parent_id) {
-                $Same_parent_LP_item_list = $LP_item_list->get_item_with_same_parent($parent_id);
+            $parents = $itemList->getListOfParents();
+            foreach ($parents as $parentId) {
+                $sameParentLpItemList = $itemList->getItemWithSameParent($parentId);
                 $previous_item_id = 0;
-                for ($i = 0; $i < count($Same_parent_LP_item_list->list); $i++) {
-                    $item_id = $Same_parent_LP_item_list->list[$i]->id;
+                for ($i = 0; $i < count($sameParentLpItemList->list); $i++) {
+                    $item_id = $sameParentLpItemList->list[$i]->id;
                     // display_order
                     $display_order = $i + 1;
-                    $LP_item_list->set_parameters_for_id($item_id, $display_order, "display_order");
+                    $itemList->setParametersForId($item_id, $display_order, 'display_order');
                     // previous_item_id
-                    $LP_item_list->set_parameters_for_id($item_id, $previous_item_id, "previous_item_id");
+                    $itemList->setParametersForId($item_id, $previous_item_id, 'previous_item_id');
                     $previous_item_id = $item_id;
                     // next_item_id
                     $next_item_id = 0;
-                    if ($i < count($Same_parent_LP_item_list->list) - 1) {
-                        $next_item_id = $Same_parent_LP_item_list->list[$i + 1]->id;
+                    if ($i < count($sameParentLpItemList->list) - 1) {
+                        $next_item_id = $sameParentLpItemList->list[$i + 1]->id;
                     }
-                    $LP_item_list->set_parameters_for_id($item_id, $next_item_id, "next_item_id");
+                    $itemList->setParametersForId($item_id, $next_item_id, 'next_item_id');
                 }
             }
 
             $table = Database::get_course_table(TABLE_LP_ITEM);
 
-            foreach ($LP_item_list->list as $LP_item) {
+            foreach ($itemList->list as $item) {
                 $params = [];
-                $params['display_order'] = $LP_item->display_order;
-                $params['previous_item_id'] = $LP_item->previous_item_id;
-                $params['next_item_id'] = $LP_item->next_item_id;
-                $params['parent_item_id'] = $LP_item->parent_item_id;
+                $params['display_order'] = $item->display_order;
+                $params['previous_item_id'] = $item->previous_item_id;
+                $params['next_item_id'] = $item->next_item_id;
+                $params['parent_item_id'] = $item->parent_item_id;
 
                 Database::update(
                     $table,
                     $params,
                     [
-                        'id = ? AND c_id = ? ' => [
-                            intval($LP_item->id),
-                            $course_id,
+                        'iid = ? AND c_id = ? ' => [
+                            intval($item->id),
+                            $courseId,
                         ],
                     ]
                 );
@@ -148,7 +153,6 @@ switch ($action) {
                 $fileName = $_POST["${type}-filename"];
                 //$file = $_FILES["${type}-blob"]["tmp_name"];
                 $file = $_FILES["${type}-blob"];
-
                 $fileInfo = pathinfo($fileName);
 
                 $file['name'] = 'rec_'.date('Y-m-d_His').'_'.uniqid().'.'.$fileInfo['extension'];
@@ -223,7 +227,7 @@ switch ($action) {
             require_once '../../forum/forumfunction.inc.php';
             $forumCategory = getForumCategoryByTitle(
                 get_lang('LearningPaths'),
-                $course_id,
+                $courseId,
                 $sessionId
             );
 
@@ -246,7 +250,7 @@ switch ($action) {
             $forumId = $forum['forum_id'];
         }
 
-        $lpItemHasThread = $lpItem->lpItemHasThread($course_id);
+        $lpItemHasThread = $lpItem->lpItemHasThread($courseId);
 
         if (!$lpItemHasThread) {
             echo json_encode([
@@ -255,10 +259,10 @@ switch ($action) {
             break;
         }
 
-        $forumThread = $lpItem->getForumThread($course_id, $sessionId);
+        $forumThread = $lpItem->getForumThread($courseId, $sessionId);
         if (empty($forumThread)) {
             $lpItem->createForumThread($forumId);
-            $forumThread = $lpItem->getForumThread($course_id, $sessionId);
+            $forumThread = $lpItem->getForumThread($courseId, $sessionId);
         }
 
         $forumThreadId = $forumThread['thread_id'];
@@ -279,7 +283,6 @@ switch ($action) {
 
         if ($lp) {
             $score = $lp->getCalculateScore($sessionId);
-
             $jsonGamification['stars'] = $lp->getCalculateStars($sessionId);
             $jsonGamification['score'] = sprintf(get_lang('XPoints'), $score);
         }
@@ -337,14 +340,15 @@ switch ($action) {
 }
 exit;
 
-/*
+/**
+ * Class LpItemOrderList
  * Classes to create a special data structure to manipulate LP Items
- * used only in this file
+ * used only in this file.
+ *
  * @todo move in a file
  * @todo use PSR
  */
-
-class LP_item_order_list
+class LpItemOrderList
 {
     public $list = [];
 
@@ -353,46 +357,66 @@ class LP_item_order_list
         $this->list = [];
     }
 
-    public function add($in_LP_item_order_item)
+    /**
+     * @param array $list
+     */
+    public function add($list)
     {
-        $this->list[] = $in_LP_item_order_item;
+        $this->list[] = $list;
     }
 
-    public function get_item_with_same_parent($in_parent_id)
+    /**
+     * @param int $parentId
+     *
+     * @return LpItemOrderList
+     */
+    public function getItemWithSameParent($parentId)
     {
-        $out_res = new LP_item_order_list();
+        $list = new LpItemOrderList();
         for ($i = 0; $i < count($this->list); $i++) {
-            if ($this->list[$i]->parent_item_id == $in_parent_id) {
-                $out_res->add($this->list[$i]);
+            if ($this->list[$i]->parent_item_id == $parentId) {
+                $list->add($this->list[$i]);
             }
         }
 
-        return $out_res;
+        return $list;
     }
 
-    public function get_list_of_parents()
+    /**
+     * @return array
+     */
+    public function getListOfParents()
     {
-        $tab_out_res = [];
-        foreach ($this->list as $LP_item) {
-            if (!in_array($LP_item->parent_item_id, $tab_out_res)) {
-                $tab_out_res[] = $LP_item->parent_item_id;
+        $result = [];
+        foreach ($this->list as $item) {
+            if (!in_array($item->parent_item_id, $result)) {
+                $result[] = $item->parent_item_id;
             }
         }
 
-        return $tab_out_res;
+        return $result;
     }
 
-    public function set_parameters_for_id($in_id, $in_value, $in_parameters)
+    /**
+     * @param int    $id
+     * @param int    $value
+     * @param string $parameter
+     */
+    public function setParametersForId($id, $value, $parameter)
     {
         for ($i = 0; $i < count($this->list); $i++) {
-            if ($this->list[$i]->id == $in_id) {
-                $this->list[$i]->$in_parameters = $in_value;
+            if ($this->list[$i]->id == $id) {
+                $this->list[$i]->$parameter = $value;
                 break;
             }
         }
     }
 }
-class LP_item_order_item
+
+/**
+ * Class LpOrderItem.
+ */
+class LpOrderItem
 {
     public $id = 0;
     public $parent_item_id = 0;
@@ -400,9 +424,15 @@ class LP_item_order_item
     public $next_item_id = 0;
     public $display_order = 0;
 
-    public function __construct($in_id = 0, $in_parent_id = 0)
+    /**
+     * LpOrderItem constructor.
+     *
+     * @param int $id
+     * @param int $parentId
+     */
+    public function __construct($id = 0, $parentId = 0)
     {
-        $this->id = $in_id;
-        $this->parent_item_id = $in_parent_id;
+        $this->id = $id;
+        $this->parent_item_id = $parentId;
     }
 }

+ 14 - 11
main/inc/ajax/statistics.ajax.php

@@ -51,29 +51,32 @@ switch ($action) {
                 }
 
                 $courseList = SessionManager::getCoursesInSession($sessionId);
+                $courseTitleList = [];
+                $courseListInString = '';
                 foreach ($courseList as $courseId) {
                     if (!isset($courseListInfo[$courseId])) {
                         $courseListInfo[$courseId] = $courseInfo = api_get_course_info_by_id($courseId);
                     } else {
                         $courseInfo = $courseListInfo[$courseId];
                     }
+                    $courseTitleList[] = $courseInfo['title'];
+                }
+                $courseListInString = implode(', ', $courseTitleList);
 
-                    $row['course'] = $courseInfo['title'];
-
-                    $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
-                    $sql = "SELECT
+                $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
+                $sql = "SELECT
                             count(DISTINCT user_id) count
                             FROM $table
                             WHERE
-                                login_course_date >= '$start' AND  
-                                logout_course_date <= '$end' AND     
-                                c_id = $courseId AND
+                                relation_type = 0 AND
+                                registered_at >= '$start' AND  
+                                registered_at <= '$end' AND
                                 session_id = '$sessionId' ";
+                $result = Database::query($sql);
+                $result = Database::fetch_array($result);
 
-                    $result = Database::query($sql);
-                    $result = Database::fetch_array($result);
-                    $row['count'] = $result['count'];
-                }
+                $row['course'] = $courseListInString;
+                $row['count'] = $result['count'];
                 $list[] = $row;
             }
         }

+ 14 - 6
main/inc/lib/AnnouncementManager.php

@@ -506,18 +506,22 @@ class AnnouncementManager
         if (empty($courseInfo)) {
             return 0;
         }
-        $tbl_announcement = Database::get_course_table(TABLE_ANNOUNCEMENT);
+
+        if (!isset($courseInfo['real_id'])) {
+            return false;
+        }
 
         $courseId = $courseInfo['real_id'];
+        $table = Database::get_course_table(TABLE_ANNOUNCEMENT);
         $sql = "SELECT MAX(display_order)
-                FROM $tbl_announcement
+                FROM $table
                 WHERE c_id = $courseId ";
-        $res_max = Database::query($sql);
+        $result = Database::query($sql);
 
         $order = 0;
-        if (Database::num_rows($res_max)) {
-            $row_max = Database::fetch_array($res_max);
-            $order = intval($row_max[0]) + 1;
+        if (Database::num_rows($result)) {
+            $row = Database::fetch_array($result);
+            $order = (int) $row[0] + 1;
         }
 
         return $order;
@@ -555,6 +559,10 @@ class AnnouncementManager
             return false;
         }
 
+        if (!isset($courseInfo['real_id'])) {
+            return false;
+        }
+
         $courseId = $courseInfo['real_id'];
         $tbl_announcement = Database::get_course_table(TABLE_ANNOUNCEMENT);
 

+ 6 - 17
main/inc/lib/CourseChatUtils.php

@@ -2,6 +2,7 @@
 /* For licensing terms, see /license.txt */
 
 use Chamilo\CoreBundle\Entity\Course;
+use Chamilo\CoreBundle\Entity\CourseRelUser;
 use Chamilo\CoreBundle\Entity\Session;
 use Chamilo\CourseBundle\Entity\CChatConnected;
 use Doctrine\Common\Collections\Criteria;
@@ -77,12 +78,8 @@ class CourseChatUtils
     /**
      * Save a chat message in a HTML file.
      *
-     * @param string$message
-     * @param int $friendId
-     *
-     * @throws \Doctrine\ORM\ORMException
-     * @throws \Doctrine\ORM\OptimisticLockException
-     * @throws \Doctrine\ORM\TransactionRequiredException
+     * @param string $message
+     * @param int    $friendId
      *
      * @return bool
      */
@@ -210,7 +207,7 @@ class CourseChatUtils
     /**
      * Disconnect a user from course chats.
      *
-     * @param $userId
+     * @param int $userId
      */
     public static function exitChat($userId)
     {
@@ -236,7 +233,6 @@ class CourseChatUtils
     {
         $em = Database::getManager();
         $extraCondition = "AND ccc.toGroupId = {$this->groupId}";
-
         if (empty($this->groupId)) {
             $extraCondition = "AND ccc.sessionId = {$this->sessionId}";
         }
@@ -251,10 +247,9 @@ class CourseChatUtils
 
         $now = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
         $cd_count_time_seconds = $now->getTimestamp();
-
+        /** @var CChatConnected $connection */
         foreach ($connectedUsers as $connection) {
             $date_count_time_seconds = $connection->getLastConnection()->getTimestamp();
-
             if (strcmp($now->format('Y-m-d'), $connection->getLastConnection()->format('Y-m-d')) !== 0) {
                 continue;
             }
@@ -439,7 +434,6 @@ class CourseChatUtils
 
         $courseInfo = api_get_course_info_by_id($this->courseId);
         $document_path = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/document';
-
         $chatPath = $document_path.'/chat_files/';
 
         if ($this->groupId) {
@@ -690,8 +684,6 @@ class CourseChatUtils
         $date = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
         $date->modify('-5 seconds');
 
-        $extraCondition = null;
-
         if ($this->groupId) {
             $extraCondition = 'AND ccc.toGroupId = '.intval($this->groupId);
         } else {
@@ -721,10 +713,9 @@ class CourseChatUtils
     {
         $subscriptions = $this->getUsersSubscriptions();
         $usersInfo = [];
-
+        /** @var CourseRelUser $subscription */
         foreach ($subscriptions as $subscription) {
             $user = $subscription->getUser();
-
             $usersInfo[] = [
                 'id' => $user->getId(),
                 'firstname' => $user->getFirstname(),
@@ -797,8 +788,6 @@ class CourseChatUtils
         $date = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
         $date->modify('-5 seconds');
 
-        $extraCondition = null;
-
         if ($this->groupId) {
             $extraCondition = 'AND ccc.toGroupId = '.intval($this->groupId);
         } else {

+ 0 - 3
main/inc/lib/CoursesAndSessionsCatalog.class.php

@@ -131,7 +131,6 @@ class CoursesAndSessionsCatalog
         $tableCourse = Database::get_main_table(TABLE_MAIN_COURSE);
         $tableCourseRelAccessUrl = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
         $courseToAvoidCondition = self::getAvoidCourseCondition();
-
         $visibilityCondition = CourseManager::getCourseVisibilitySQLCondition('course', true);
 
         $accessUrlId = (int) $accessUrlId;
@@ -396,7 +395,6 @@ class CoursesAndSessionsCatalog
         $limitFilter = self::getLimitFilterFromArray($limit);
         $avoidCoursesCondition = self::getAvoidCourseCondition();
         $visibilityCondition = $justVisible ? CourseManager::getCourseVisibilitySQLCondition('course', true) : '';
-
         $search_term_safe = Database::escape_string($search_term);
         $sql_find = "SELECT * FROM $courseTable course
                       WHERE (
@@ -477,7 +475,6 @@ class CoursesAndSessionsCatalog
     {
         $em = Database::getManager();
         $urlId = api_get_current_access_url_id();
-
         $sql = "SELECT s.id FROM session s ";
         $sql .= "
             INNER JOIN access_url_rel_session ars

+ 10 - 9
main/inc/lib/ScheduledAnnouncement.php

@@ -317,17 +317,17 @@ class ScheduledAnnouncement extends Model
                         $urlId
                     );
 
-                    if (empty($users)) {
+                    $coachId = $sessionInfo['id_coach'];
+
+                    if (empty($users) || empty($coachId)) {
                         continue;
                     }
 
-                    $attachments = $this->getAttachmentToString($result['id']);
-
-                    self::update(['id' => $result['id'], 'sent' => 1]);
-
-                    $subject = $result['subject'];
-
                     if ($users) {
+                        self::update(['id' => $result['id'], 'sent' => 1]);
+                        $attachments = $this->getAttachmentToString($result['id']);
+                        $subject = $result['subject'];
+
                         foreach ($users as $user) {
                             // Take original message
                             $message = $result['message'];
@@ -393,10 +393,11 @@ class ScheduledAnnouncement extends Model
                             $message = str_replace(array_keys($tags), $tags, $message);
                             $message .= $attachments;
 
-                            MessageManager::send_message(
+                            MessageManager::send_message_simple(
                                 $userInfo['user_id'],
                                 $subject,
-                                $message
+                                $message,
+                                $coachId
                             );
                         }
                     }

+ 24 - 58
main/inc/lib/agenda.lib.php

@@ -1330,7 +1330,7 @@ class Agenda
     public function resizeEvent($id, $minute_delta)
     {
         $id = (int) $id;
-        $delta = intval($minute_delta);
+        $delta = (int) $minute_delta;
         $event = $this->get_event($id);
         if (!empty($event)) {
             switch ($this->type) {
@@ -1377,8 +1377,8 @@ class Agenda
         }
 
         // we convert the hour delta into minutes and add the minute delta
-        $delta = intval($minute_delta);
-        $allDay = intval($allDay);
+        $delta = (int) $minute_delta;
+        $allDay = (int) $allDay;
 
         if (!empty($event)) {
             switch ($this->type) {
@@ -1423,7 +1423,7 @@ class Agenda
     public function get_event($id)
     {
         // make sure events of the personal agenda can only be seen by the user himself
-        $id = intval($id);
+        $id = (int) $id;
         $event = null;
         switch ($this->type) {
             case 'personal':
@@ -1571,9 +1571,9 @@ class Agenda
         $courseId,
         $sessionId
     ) {
-        $eventId = intval($eventId);
-        $courseId = intval($courseId);
-        $sessionId = intval($sessionId);
+        $eventId = (int) $eventId;
+        $courseId = (int) $courseId;
+        $sessionId = (int) $sessionId;
 
         $sessionCondition = "ip.session_id = $sessionId";
         if (empty($sessionId)) {
@@ -1664,7 +1664,7 @@ class Agenda
      * @param int    $end
      * @param array  $courseInfo
      * @param int    $groupId
-     * @param int    $session_id
+     * @param int    $sessionId
      * @param int    $user_id
      * @param string $color
      *
@@ -1691,8 +1691,8 @@ class Agenda
             return [];
         }
 
-        $sessionId = intval($sessionId);
-        $user_id = intval($user_id);
+        $sessionId = (int) $sessionId;
+        $user_id = (int) $user_id;
 
         $groupList = GroupManager::get_group_list(
             null,
@@ -2506,7 +2506,6 @@ class Agenda
         }
 
         $form->setDefaults($params);
-
         $form->addRule(
             'date_range',
             get_lang('ThisFieldIsRequired'),
@@ -2633,8 +2632,8 @@ class Agenda
     public function getAttachmentList($eventId, $courseInfo)
     {
         $tableAttachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
-        $courseId = intval($courseInfo['real_id']);
-        $eventId = intval($eventId);
+        $courseId = (int) $courseInfo['real_id'];
+        $eventId = (int) $eventId;
 
         $sql = "SELECT id, path, filename, comment
                 FROM $tableAttachment
@@ -2698,9 +2697,7 @@ class Agenda
         $comment,
         $courseInfo
     ) {
-        $agenda_table_attachment = Database::get_course_table(
-            TABLE_AGENDA_ATTACHMENT
-        );
+        $agenda_table_attachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
         $eventId = intval($eventId);
 
         // Storing the attachments
@@ -2801,17 +2798,15 @@ class Agenda
      */
     public function deleteAttachmentFile($attachmentId, $courseInfo)
     {
-        $agenda_table_attachment = Database::get_course_table(
-            TABLE_AGENDA_ATTACHMENT
-        );
-        $attachmentId = intval($attachmentId);
+        $table = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
+        $attachmentId = (int) $attachmentId;
         $courseId = $courseInfo['real_id'];
 
         if (empty($courseId) || empty($attachmentId)) {
             return false;
         }
 
-        $sql = "DELETE FROM $agenda_table_attachment
+        $sql = "DELETE FROM $table
                 WHERE c_id = $courseId AND id = ".$attachmentId;
         $result = Database::query($sql);
 
@@ -2835,9 +2830,8 @@ class Agenda
     /**
      * Adds x weeks to a UNIX timestamp.
      *
-     * @param   int     The timestamp
-     * @param   int     The number of weeks to add
-     * @param int $timestamp
+     * @param int $timestamp The timestamp
+     * @param int $num       The number of weeks to add
      *
      * @return int The new timestamp
      */
@@ -2849,9 +2843,8 @@ class Agenda
     /**
      * Adds x months to a UNIX timestamp.
      *
-     * @param   int     The timestamp
-     * @param   int     The number of years to add
-     * @param int $timestamp
+     * @param int $timestamp The timestamp
+     * @param int $num       The number of years to add
      *
      * @return int The new timestamp
      */
@@ -2874,9 +2867,8 @@ class Agenda
     /**
      * Adds x years to a UNIX timestamp.
      *
-     * @param   int     The timestamp
-     * @param   int     The number of years to add
-     * @param int $timestamp
+     * @param int $timestamp The timestamp
+     * @param int $num       The number of years to add
      *
      * @return int The new timestamp
      */
@@ -2928,8 +2920,8 @@ class Agenda
      */
     public function hasChildren($eventId, $courseId)
     {
-        $eventId = intval($eventId);
-        $courseId = intval($courseId);
+        $eventId = (int) $eventId;
+        $courseId = (int) $courseId;
 
         $sql = "SELECT count(DISTINCT(id)) as count
                 FROM ".$this->tbl_course_agenda."
@@ -4156,32 +4148,6 @@ class Agenda
         $this->isAllowedToEdit = $isAllowedToEdit;
     }
 
-    /**
-     * @param int   $userId
-     * @param array $event
-     *
-     * @return bool
-     */
-    public function sendEmail($userId, $event)
-    {
-        $userInfo = api_get_user_info($userId);
-
-        if (!empty($this->sessionInfo)) {
-            $courseTitle = $this->course['name'].' ('.$this->sessionInfo['title'].')';
-        } else {
-            $courseTitle = $this->course['name'];
-        }
-
-        api_mail_html(
-            $userInfo['complete_name'],
-            $userInfo['mail'],
-            $subject,
-            $emailBody
-        );
-
-        return true;
-    }
-
     /**
      * Format needed for the Fullcalendar js lib.
      *

+ 37 - 15
main/inc/lib/api.lib.php

@@ -1280,7 +1280,10 @@ function api_block_anonymous_users($printHeaders = true)
 }
 
 /**
- * @return array with the navigator name and version
+ * Returns a rough evaluation of the browser's name and version based on very
+ * simple regexp.
+ *
+ * @return array with the navigator name and version ['name' => '...', 'version' => '...']
  */
 function api_get_navigator()
 {
@@ -1294,29 +1297,49 @@ function api_get_navigator()
     if (strpos($_SERVER['HTTP_USER_AGENT'], 'Opera') !== false) {
         $navigator = 'Opera';
         list(, $version) = explode('Opera', $_SERVER['HTTP_USER_AGENT']);
+    } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Edge') !== false) {
+        $navigator = 'Edge';
+        list(, $version) = explode('Edge', $_SERVER['HTTP_USER_AGENT']);
     } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false) {
         $navigator = 'Internet Explorer';
-        list(, $version) = explode('MSIE', $_SERVER['HTTP_USER_AGENT']);
+        list(, $version) = explode('MSIE ', $_SERVER['HTTP_USER_AGENT']);
     } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Chrome') !== false) {
         $navigator = 'Chrome';
         list(, $version) = explode('Chrome', $_SERVER['HTTP_USER_AGENT']);
-    } elseif (stripos($_SERVER['HTTP_USER_AGENT'], 'safari') !== false) {
+    } elseif (stripos($_SERVER['HTTP_USER_AGENT'], 'Safari') !== false) {
         $navigator = 'Safari';
-        list(, $version) = explode('Version/', $_SERVER['HTTP_USER_AGENT']);
-    } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Gecko') !== false) {
-        $navigator = 'Mozilla';
-        list(, $version) = explode('; rv:', $_SERVER['HTTP_USER_AGENT']);
+        if (stripos($_SERVER['HTTP_USER_AGENT'], 'Version/') !== false) {
+            // If this Safari does have the "Version/" string in its user agent
+            // then use that as a version indicator rather than what's after
+            // "Safari/" which is rather a "build number" or something
+            list(, $version) = explode('Version/', $_SERVER['HTTP_USER_AGENT']);
+        } else {
+            list(, $version) = explode('Safari/', $_SERVER['HTTP_USER_AGENT']);
+        }
+    } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Firefox') !== false) {
+        $navigator = 'Firefox';
+        list(, $version) = explode('Firefox', $_SERVER['HTTP_USER_AGENT']);
     } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Netscape') !== false) {
         $navigator = 'Netscape';
-        list(, $version) = explode('Netscape', $_SERVER['HTTP_USER_AGENT']);
+        if (stripos($_SERVER['HTTP_USER_AGENT'], 'Netscape/') !== false) {
+            list(, $version) = explode('Netscape', $_SERVER['HTTP_USER_AGENT']);
+        } else {
+            list(, $version) = explode('Navigator', $_SERVER['HTTP_USER_AGENT']);
+        }
     } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Konqueror') !== false) {
         $navigator = 'Konqueror';
         list(, $version) = explode('Konqueror', $_SERVER['HTTP_USER_AGENT']);
     } elseif (stripos($_SERVER['HTTP_USER_AGENT'], 'applewebkit') !== false) {
         $navigator = 'AppleWebKit';
         list(, $version) = explode('Version/', $_SERVER['HTTP_USER_AGENT']);
+    } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Gecko') !== false) {
+        $navigator = 'Mozilla';
+        list(, $version) = explode('; rv:', $_SERVER['HTTP_USER_AGENT']);
     }
-    $version = str_replace('/', '', $version);
+
+    // Now cut extra stuff around (mostly *after*) the version number
+    $version = preg_replace('/^([\/\s])?([\d\.]+)?.*/', '\2', $version);
+
     if (strpos($version, '.') === false) {
         $version = number_format(doubleval($version), 1);
     }
@@ -1361,10 +1384,10 @@ function api_get_user_id()
  *
  * @deprecated use CourseManager::get_courses_list_by_user_id()
  */
-function api_get_user_courses($userid, $fetch_session = true)
+function api_get_user_courses($userId, $fetch_session = true)
 {
     // Get out if not integer
-    if ($userid != strval(intval($userid))) {
+    if ($userId != strval(intval($userId))) {
         return [];
     }
 
@@ -1372,12 +1395,11 @@ function api_get_user_courses($userid, $fetch_session = true)
     $t_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
 
     $sql = "SELECT cc.id as real_id, cc.code code, cc.directory dir, cu.status status
-            FROM    $t_course       cc,
-                    $t_course_user   cu
+            FROM $t_course cc, $t_course_user cu
             WHERE
                 cc.id = cu.c_id AND
-                cu.user_id = '".$userid."' AND
-                cu.relation_type<>".COURSE_RELATION_TYPE_RRHH." ";
+                cu.user_id = $userId AND
+                cu.relation_type <> ".COURSE_RELATION_TYPE_RRHH;
     $result = Database::query($sql);
     if ($result === false) {
         return [];

+ 2 - 2
main/inc/lib/auth.lib.php

@@ -286,8 +286,8 @@ class Auth
         $title = Database::escape_string($title);
         $category_id = intval($category_id);
         $result = false;
-        $tucc = Database::get_main_table(TABLE_USER_COURSE_CATEGORY);
-        $sql = "UPDATE $tucc
+        $table = Database::get_main_table(TABLE_USER_COURSE_CATEGORY);
+        $sql = "UPDATE $table
                 SET title='".api_htmlentities($title, ENT_QUOTES, api_get_system_encoding())."'
                 WHERE id='".$category_id."'";
         $resultQuery = Database::query($sql);

+ 11 - 7
main/inc/lib/banner.lib.php

@@ -248,13 +248,17 @@ function returnNotificationMenu()
                 .' '.$number_online_in_course.' </a></li>';
         }
 
-        if (isset($user_id) && $sessionId != 0) {
-            $numberOnlineInSession = getOnlineUsersInSessionCount($sessionId);
-
-            $html .= '<li class="user-online-session"><a href="'.api_get_path(WEB_PATH).'whoisonlinesession.php?id_coach='.$user_id.'" target="_self">'
-                .Display::return_icon('session.png', get_lang('UsersConnectedToMySessions'), [], ICON_SIZE_TINY)
-                .' '.$numberOnlineInSession
-                .'</a></li>';
+        if (!empty($sessionId)) {
+            $allow = api_is_platform_admin(true) ||
+                api_is_coach($sessionId, null, false) ||
+                SessionManager::isUserSubscribedAsStudent($sessionId, api_get_user_id());
+            if ($allow) {
+                $numberOnlineInSession = getOnlineUsersInSessionCount($sessionId);
+                $html .= '<li class="user-online-session">
+                            <a href="'.api_get_path(WEB_PATH).'whoisonlinesession.php" target="_self">'
+                            .Display::return_icon('session.png', get_lang('UsersConnectedToMySessions'), [], ICON_SIZE_TINY)
+                            .' '.$numberOnlineInSession.'</a></li>';
+            }
         }
     }
 

+ 2 - 3
main/inc/lib/certificate.lib.php

@@ -508,7 +508,7 @@ class Certificate extends Model
      */
     public function generateQRImage($text, $path)
     {
-        //Make sure HTML certificate is generated
+        // Make sure HTML certificate is generated
         if (!empty($text) && !empty($path)) {
             //L low, M - Medium, L large error correction
             return PHPQRCode\QRcode::png($text, $path, 'M', 2, 2);
@@ -692,7 +692,6 @@ class Certificate extends Model
         }
 
         $userInfo = api_get_user_info($this->user_id);
-
         $extraFieldValue = new ExtraFieldValue('user');
         $value = $extraFieldValue->get_values_by_handler_and_field_variable($this->user_id, 'legal_accept');
         $termsValidationDate = '';
@@ -700,7 +699,7 @@ class Certificate extends Model
             list($id, $id2, $termsValidationDate) = explode(':', $value['value']);
         }
 
-        $sessions = SessionManager::get_sessions_by_user($this->user_id);
+        $sessions = SessionManager::get_sessions_by_user($this->user_id, false, true);
         $sessionsApproved = [];
         if ($sessions) {
             foreach ($sessions as $session) {

+ 19 - 10
main/inc/lib/course.lib.php

@@ -375,7 +375,7 @@ class CourseManager
     }
 
     /**
-     * @param int $user_id
+     * @param int $userId
      * @param int $courseId
      *
      * @return mixed
@@ -2240,19 +2240,21 @@ class CourseManager
         $table_stats_links = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LINKS);
         $table_stats_uploads = Database::get_main_table(TABLE_STATISTIC_TRACK_E_UPLOADS);
 
+        if (empty($code)) {
+            return false;
+        }
+
         $codeFiltered = Database::escape_string($code);
-        $sql = "SELECT * FROM $table_course WHERE code='".$codeFiltered."'";
+        $sql = "SELECT * FROM $table_course
+                WHERE code = '$codeFiltered'";
         $res = Database::query($sql);
 
         if (Database::num_rows($res) == 0) {
             return;
         }
 
-        $sql = "SELECT * FROM $table_course
-                WHERE code = '$codeFiltered'";
-        $res = Database::query($sql);
         $course = Database::fetch_array($res);
-        $courseId = $course['id']; //int
+        $courseId = $course['id']; // int
 
         $count = 0;
         if (api_is_multiple_url_enabled()) {
@@ -2271,7 +2273,6 @@ class CourseManager
 
             // Cleaning group categories
             $groupCategories = GroupManager::get_categories($course['code']);
-
             if (!empty($groupCategories)) {
                 foreach ($groupCategories as $category) {
                     GroupManager::delete_category($category['id'], $course['code']);
@@ -2282,7 +2283,7 @@ class CourseManager
             $groups = GroupManager::get_groups($courseId);
             if (!empty($groups)) {
                 foreach ($groups as $group) {
-                    GroupManager::delete_groups($group, $course['code']);
+                    GroupManager::deleteGroup($group, $course['code']);
                 }
             }
 
@@ -2367,11 +2368,19 @@ class CourseManager
             // Skills
             $table = Database::get_main_table(TABLE_MAIN_SKILL_REL_USER);
             $argumentation = Database::escape_string(sprintf(get_lang('SkillFromCourseXDeletedSinceThen'), $course['code']));
-            $sql = "UPDATE $table SET course_id = NULL, session_id = NULL, argumentation = '$argumentation' WHERE course_id = $courseId";
+            $sql = "UPDATE $table SET course_id = NULL, session_id = NULL, argumentation = '$argumentation' 
+                    WHERE course_id = $courseId";
+            Database::query($sql);
+
+            $sql = "DELETE FROM skill_rel_course WHERE c_id = $courseId";
             Database::query($sql);
+            
+            // Deletes all groups, group-users, group-tutors information
+            // To prevent fK mix up on some tables
+            GroupManager::deleteAllGroupsFromCourse($courseId);
 
             // Delete the course from the database
-            $sql = "DELETE FROM $table_course WHERE code = '$codeFiltered'";
+            $sql = "DELETE FROM $table_course WHERE id = $courseId";
             Database::query($sql);
 
             // delete extra course fields

+ 27 - 8
main/inc/lib/course_home.lib.php

@@ -508,30 +508,49 @@ class CourseHome
             't.session_id'
         );
 
+        $lpTable = Database::get_course_table(TABLE_LP_MAIN);
+
+        $orderBy = ' ORDER BY id ';
         switch ($course_tool_category) {
             case TOOL_STUDENT_VIEW:
                 $conditions = ' WHERE visibility = 1 AND 
                                 (category = "authoring" OR category = "interaction" OR category = "plugin") AND 
-                                name <> "notebookteacher" ';
+                                t.name <> "notebookteacher" ';
                 if ((api_is_coach() || api_is_course_tutor()) && $_SESSION['studentview'] != 'studentview') {
                     $conditions = ' WHERE (
                         visibility = 1 AND (
                             category = "authoring" OR 
                             category = "interaction" OR 
                             category = "plugin"
-                        ) OR (name = "'.TOOL_TRACKING.'") 
+                        ) OR (t.name = "'.TOOL_TRACKING.'") 
                     )';
                 }
-                $sql = "SELECT *
+
+                /*$sql = "SELECT *
                         FROM $course_tool_table t
                         $conditions AND
                         c_id = $course_id $condition_session
-                        ";
+                        ";*/
+                // Add order if there are LPs
+                $sql = "SELECT t.* FROM $course_tool_table t
+                        LEFT JOIN $lpTable l 
+                        ON (t.c_id = l.c_id AND link LIKE concat('%/lp_controller.php?action=view&lp_id=', l.id, '&%'))
+                        $conditions AND
+                        t.c_id = $course_id $condition_session 
+                        ORDER BY CASE WHEN l.display_order IS NULL THEN 0 ELSE 1 END, l.display_order, t.id";
+                $orderBy = '';
                 break;
             case TOOL_AUTHORING:
-                $sql = "SELECT * FROM $course_tool_table t
+                /*$sql = "SELECT * FROM $course_tool_table t
                         WHERE category = 'authoring' AND c_id = $course_id $condition_session
-                        ";
+                        ";*/
+                $sql = "SELECT t.* FROM $course_tool_table t
+                        LEFT JOIN $lpTable l 
+                        ON (t.c_id = l.c_id AND link LIKE concat('%/lp_controller.php?action=view&lp_id=', l.id, '&%'))
+                        WHERE 
+                            category = 'authoring' AND t.c_id = $course_id $condition_session
+                        ORDER BY CASE WHEN l.display_order IS NULL THEN 0 ELSE 1 END, l.display_order, t.id";
+                $orderBy = '';
                 break;
             case TOOL_INTERACTION:
                 $sql = "SELECT * FROM $course_tool_table t
@@ -550,7 +569,7 @@ class CourseHome
                 break;
             case TOOL_DRH:
                 $sql = "SELECT * FROM $course_tool_table t
-                        WHERE name IN ('tracking') AND c_id = $course_id $condition_session
+                        WHERE t.name IN ('tracking') AND c_id = $course_id $condition_session
                         ";
                 break;
             case TOOL_COURSE_PLUGIN:
@@ -561,7 +580,7 @@ class CourseHome
                         ";
                 break;
         }
-        $sql .= " ORDER BY id ";
+        $sql .= $orderBy;
         $result = Database::query($sql);
         $tools = [];
         while ($row = Database::fetch_assoc($result)) {

+ 6 - 1
main/inc/lib/database.constants.inc.php

@@ -57,7 +57,6 @@ define('TABLE_MAIN_GRADEBOOK_CERTIFICATE', 'gradebook_certificate');
 define('TABLE_MAIN_GRADEBOOK_SCORE_LOG', 'gradebook_score_log');
 
 // Profiling
-
 define('TABLE_EXTRA_FIELD', 'extra_field');
 define('TABLE_EXTRA_FIELD_OPTIONS', 'extra_field_options');
 define('TABLE_EXTRA_FIELD_VALUES', 'extra_field_values');
@@ -339,3 +338,9 @@ define('TABLE_TICKET_MESSAGE_ATTACHMENTS', 'ticket_message_attachments');
 define('TABLE_BRANCH', 'branch_sync');
 define('TABLE_BRANCH_TRANSACTION', 'branch_transaction');
 define('TABLE_BRANCH_TRANSACTION_STATUS', 'branch_transaction_status');
+
+// main/extra @todo after code is finished remove constants not used
+define('TABLE_CAL_DATE', 'cal_dates');
+define('TABLE_CAL_HORAIRE', 'cal_horaire');
+define('TABLE_CAL_TEMP', 'cal_temp');
+define('TABLE_STATISTIC_TRACK_E_EXERCICES_TEMP', 'track_e_exercices_temp');

+ 2 - 1
main/inc/lib/display.lib.php

@@ -164,7 +164,8 @@ class Display
         $tpl = '@ChamiloTheme/Layout/layout_one_col.html.twig';
         $response = new Response();
         $params['content'] = $contents;
-        global $interbreadcrumb;
+        global $interbreadcrumb, $htmlHeadXtra;
+        $params['legacy_javascript'] = $htmlHeadXtra;
         $params['legacy_breadcrumb'] = $interbreadcrumb;
         $content = Container::getTemplating()->render($tpl, $params);
         $response->setContent($content);

+ 1 - 1
main/inc/lib/events.lib.php

@@ -41,7 +41,7 @@ class Event
             } // don't change this
             $reallyNow = api_get_utc_datetime();
             $params = [
-                'open_remote_host' => $remhost,
+                'open_remote_host' => Database::escape_string($remhost),
                 'open_agent' => $_SERVER['HTTP_USER_AGENT'],
                 'open_referer' => $referer,
                 'open_date' => $reallyNow,

+ 4 - 1
main/inc/lib/exercise.lib.php

@@ -1093,7 +1093,10 @@ HTML;
                         $s .= $isVertical ? '<div class="row">' : '';
                         $s .= '
                             <div class="'.($isVertical ? 'col-md-12' : 'col-xs-12 col-sm-4 col-md-3 col-lg-2').'">
-                                <div id="drop_'.$windowId.'" class="droppable">&nbsp;</div>
+                                <div class="droppable-item">
+                                    <span class="number">'.$counterAnswer.'.</span>
+                                    <div id="drop_'.$windowId.'" class="droppable">&nbsp;</div>
+                                 </div>
                             </div>
                         ';
                         $s .= $isVertical ? '</div>' : '';

+ 5 - 4
main/inc/lib/glossary.lib.php

@@ -276,7 +276,7 @@ class GlossaryManager
     /**
      * Get one specific glossary term data.
      *
-     * @param int $glossary_id ID of the flossary term
+     * @param int $glossary_id ID of the glossary term
      *
      * @return mixed Array(glossary_id,name,description,glossary_display_order) or false on error
      */
@@ -296,9 +296,10 @@ class GlossaryManager
                     ip.insert_date      as insert_date,
                     ip.lastedit_date    as update_date,
                     g.session_id
-                FROM $t_glossary g, $t_item_propery ip
-                WHERE
-                    g.glossary_id = ip.ref AND
+                FROM $t_glossary g 
+                INNER JOIN $t_item_propery ip
+                ON (g.glossary_id = ip.ref AND g.c_id = ip.c_id)
+                WHERE                    
                     tool = '".TOOL_GLOSSARY."' AND
                     g.glossary_id = '".intval($glossary_id)."' AND
                     g.c_id = ".api_get_course_int_id()." AND

+ 47 - 4
main/inc/lib/groupmanager.lib.php

@@ -428,12 +428,16 @@ class GroupManager
      *
      * @return int - number of groups deleted
      */
-    public static function delete_groups($groupInfo, $course_code = null)
+    public static function deleteGroup($groupInfo, $course_code = null)
     {
         if (empty($groupInfo['iid'])) {
             return false;
         }
         $course_info = api_get_course_info($course_code);
+        if (empty($course_info)) {
+            return false;
+        }
+
         $course_id = $course_info['real_id'];
 
         // Database table definitions
@@ -491,6 +495,45 @@ class GroupManager
         return true;
     }
 
+    /**
+     * Function needed only when deleting a course, in order to be sure that all group ids are deleted.
+     *
+     * @param int $courseId
+     *
+     * @return bool
+     */
+    public static function deleteAllGroupsFromCourse($courseId)
+    {
+        $courseId = (int) $courseId;
+
+        if (empty($courseId)) {
+            return false;
+        }
+
+        $table = Database::get_course_table(TABLE_GROUP_CATEGORY);
+        $sql = "SELECT iid FROM $table
+                WHERE c_id = $courseId ";
+        Database::query($sql);
+
+        // Database table definitions
+        $table = Database::get_course_table(TABLE_GROUP_USER);
+        $sql = "DELETE FROM $table
+                WHERE c_id = $courseId";
+        Database::query($sql);
+
+        $table = Database::get_course_table(TABLE_GROUP_TUTOR);
+        $sql = "DELETE FROM $table
+                WHERE c_id = $courseId";
+        Database::query($sql);
+
+        $groupTable = Database::get_course_table(TABLE_GROUP);
+        $sql = "DELETE FROM $groupTable
+                WHERE c_id = $courseId";
+        Database::query($sql);
+
+        return true;
+    }
+
     /**
      * Get group properties.
      *
@@ -874,7 +917,7 @@ class GroupManager
             while ($group = Database::fetch_object($res)) {
                 // Delete all groups in category
                 /*$groupInfo = self::get_group_properties($group->iid, true);
-                self::delete_groups($groupInfo, $course_code);
+                self::deleteGroup($groupInfo, $course_code);
                 */
                 // Set the category to NULL to avoid losing groups in sessions.
                 $sql = "UPDATE $table_group SET category_id = NULL WHERE iid = ".$group->iid;
@@ -2689,7 +2732,7 @@ class GroupManager
             $groups = self::get_groups();
             foreach ($groups as $group) {
                 if (!in_array($group['iid'], $elementsFound['groups'])) {
-                    self::delete_groups($group);
+                    self::deleteGroup($group);
                     $group['group'] = $group['name'];
                     $result['deleted']['group'][] = $group;
                 }
@@ -3020,7 +3063,7 @@ class GroupManager
         $blockPage = false
     ) {
         // Admin and teachers can make any change no matter what
-        if (api_is_platform_admin() || api_is_allowed_to_edit()) {
+        if (api_is_platform_admin() || api_is_allowed_to_edit(false, true)) {
             return true;
         }
 

+ 127 - 67
main/inc/lib/message.lib.php

@@ -272,8 +272,8 @@ class MessageManager
      * @param int    $receiver_user_id
      * @param string $subject
      * @param string $content
-     * @param array  $file_attachments files array($_FILES) (optional)
-     * @param array  $file_comments    about attachment files (optional)
+     * @param array  $attachments      files array($_FILES) (optional)
+     * @param array  $fileCommentList  about attachment files (optional)
      * @param int    $group_id         (optional)
      * @param int    $parent_id        (optional)
      * @param int    $editMessageId    id for updating the message (optional)
@@ -289,8 +289,8 @@ class MessageManager
         $receiver_user_id,
         $subject,
         $content,
-        array $file_attachments = [],
-        array $file_comments = [],
+        array $attachments = [],
+        array $fileCommentList = [],
         $group_id = 0,
         $parent_id = 0,
         $editMessageId = 0,
@@ -324,9 +324,12 @@ class MessageManager
         }
 
         $totalFileSize = 0;
-        if (is_array($file_attachments)) {
-            foreach ($file_attachments as $file_attach) {
-                $fileSize = isset($file_attach['size']) ? $file_attach['size'] : 0;
+        $attachmentList = [];
+        if (is_array($attachments)) {
+            $counter = 0;
+            foreach ($attachments as $attachment) {
+                $attachment['comment'] = isset($fileCommentList[$counter]) ? $fileCommentList[$counter] : '';
+                $fileSize = isset($attachment['size']) ? $attachment['size'] : 0;
                 if (is_array($fileSize)) {
                     foreach ($fileSize as $size) {
                         $totalFileSize += $size;
@@ -334,6 +337,8 @@ class MessageManager
                 } else {
                     $totalFileSize += $fileSize;
                 }
+                $attachmentList[] = $attachment;
+                $counter++;
             }
         }
 
@@ -386,21 +391,39 @@ class MessageManager
                 $messageId = Database::insert($table, $params);
             }
 
+            // Forward also message attachments
+            if (!empty($forwardId)) {
+                $attachments = MessageManager::getAttachmentList($forwardId);
+                foreach ($attachments as $attachment) {
+                    if (!empty($attachment['file_source'])) {
+                        $file = [
+                            'name' => $attachment['filename'],
+                            'tmp_name' => $attachment['file_source'],
+                            'size' => $attachment['size'],
+                            'error' => 0,
+                            'comment' => $attachment['comment'],
+                        ];
+
+                        // Inject this array so files can be added when sending and email with the mailer
+                        $attachmentList[] = $file;
+                    }
+                }
+            }
+
             // Save attachment file for inbox messages
-            if (is_array($file_attachments)) {
-                $i = 0;
-                foreach ($file_attachments as $file_attach) {
-                    if ($file_attach['error'] == 0) {
+            if (is_array($attachmentList)) {
+                foreach ($attachmentList as $attachment) {
+                    if ($attachment['error'] == 0) {
+                        $comment = $attachment['comment'];
                         self::saveMessageAttachmentFile(
-                            $file_attach,
-                            isset($file_comments[$i]) ? $file_comments[$i] : null,
+                            $attachment,
+                            $comment,
                             $messageId,
                             null,
                             $receiver_user_id,
                             $group_id
                         );
                     }
-                    $i++;
                 }
             }
 
@@ -420,19 +443,17 @@ class MessageManager
                 $outbox_last_id = Database::insert($table, $params);
 
                 // save attachment file for outbox messages
-                if (is_array($file_attachments)) {
-                    $o = 0;
-                    foreach ($file_attachments as $file_attach) {
-                        if ($file_attach['error'] == 0) {
-                            $comment = isset($file_comments[$o]) ? $file_comments[$o] : '';
+                if (is_array($attachmentList)) {
+                    foreach ($attachmentList as $attachment) {
+                        if ($attachment['error'] == 0) {
+                            $comment = $attachment['comment'];
                             self::saveMessageAttachmentFile(
-                                $file_attach,
+                                $attachment,
                                 $comment,
                                 $outbox_last_id,
                                 $user_sender_id
                             );
                         }
-                        $o++;
                     }
                 }
             }
@@ -442,9 +463,12 @@ class MessageManager
             $sender_info = api_get_user_info($user_sender_id);
 
             // add file attachment additional attributes
-            foreach ($file_attachments as $index => $file_attach) {
-                $file_attachments[$index]['path'] = $file_attach['tmp_name'];
-                $file_attachments[$index]['filename'] = $file_attach['name'];
+            $attachmentAddedByMail = [];
+            foreach ($attachmentList as $attachment) {
+                $attachmentAddedByMail[] = [
+                    'path' => $attachment['tmp_name'],
+                    'filename' => $attachment['name'],
+                ];
             }
 
             if (empty($group_id)) {
@@ -459,7 +483,7 @@ class MessageManager
                     $subject,
                     $content,
                     $sender_info,
-                    $file_attachments,
+                    $attachmentAddedByMail,
                     $smsParameters
                 );
             } else {
@@ -493,7 +517,7 @@ class MessageManager
                     $subject,
                     $content,
                     $group_info,
-                    $file_attachments,
+                    $attachmentAddedByMail,
                     $smsParameters
                 );
             }
@@ -710,7 +734,7 @@ class MessageManager
         $sender_user_id = 0,
         $group_id = 0
     ) {
-        $tbl_message_attach = Database::get_main_table(TABLE_MESSAGE_ATTACHMENT);
+        $table = Database::get_main_table(TABLE_MESSAGE_ATTACHMENT);
 
         // Try to add an extension to the file if it hasn't one
         $type = isset($file_attach['type']) ? $file_attach['type'] : '';
@@ -750,25 +774,31 @@ class MessageManager
             }
 
             $new_path = $path_message_attach.$new_file_name;
-
-            if (is_uploaded_file($file_attach['tmp_name'])) {
-                @copy($file_attach['tmp_name'], $new_path);
-            } else {
-                // 'tmp_name' can be set by the ticket
-                if (file_exists($file_attach['tmp_name'])) {
+            $fileCopied = false;
+            if (isset($file_attach['tmp_name']) && !empty($file_attach['tmp_name'])) {
+                if (is_uploaded_file($file_attach['tmp_name'])) {
                     @copy($file_attach['tmp_name'], $new_path);
+                    $fileCopied = true;
+                } else {
+                    // 'tmp_name' can be set by the ticket or when forwarding a message
+                    if (file_exists($file_attach['tmp_name'])) {
+                        @copy($file_attach['tmp_name'], $new_path);
+                        $fileCopied = true;
+                    }
                 }
             }
 
-            // Storing the attachments if any
-            $params = [
-                'filename' => $file_name,
-                'comment' => $file_comment,
-                'path' => $new_file_name,
-                'message_id' => $message_id,
-                'size' => $file_attach['size'],
-            ];
-            Database::insert($tbl_message_attach, $params);
+            if ($fileCopied) {
+                // Storing the attachments if any
+                $params = [
+                    'filename' => $file_name,
+                    'comment' => $file_comment,
+                    'path' => $new_file_name,
+                    'message_id' => $message_id,
+                    'size' => $file_attach['size'],
+                ];
+                Database::insert($table, $params);
+            }
         }
     }
 
@@ -1183,7 +1213,7 @@ class MessageManager
         $user_sender_id = $row['user_sender_id'];
 
         // get file attachments by message id
-        $files_attachments = self::get_links_message_attachment_files(
+        $files_attachments = self::getAttachmentLinkList(
             $messageId,
             $source
         );
@@ -1474,7 +1504,7 @@ class MessageManager
         $items_page_nr = null;
 
         $user_sender_info = api_get_user_info($main_message['user_sender_id']);
-        $files_attachments = self::get_links_message_attachment_files($main_message['id']);
+        $files_attachments = self::getAttachmentLinkList($main_message['id']);
         $name = $user_sender_info['complete_name'];
 
         $topic_page_nr = isset($_GET['topics_page_nr']) ? intval($_GET['topics_page_nr']) : null;
@@ -1614,7 +1644,7 @@ class MessageManager
                 $links .= '<div class="pull-right">';
                 $html_items = '';
                 $user_sender_info = api_get_user_info($topic['user_sender_id']);
-                $files_attachments = self::get_links_message_attachment_files($topic['id']);
+                $files_attachments = self::getAttachmentLinkList($topic['id']);
                 $name = $user_sender_info['complete_name'];
 
                 $links .= '<div class="btn-group btn-group-sm">';
@@ -1778,6 +1808,44 @@ class MessageManager
         return strcmp($array2['send_date'], $array1['send_date']);
     }
 
+    /**
+     * @param int $messageId
+     *
+     * @return array
+     */
+    public static function getAttachmentList($messageId)
+    {
+        $table = Database::get_main_table(TABLE_MESSAGE_ATTACHMENT);
+        $messageId = (int) $messageId;
+
+        if (empty($messageId)) {
+            return [];
+        }
+
+        $messageInfo = MessageManager::get_message_by_id($messageId);
+
+        if (empty($messageInfo)) {
+            return [];
+        }
+
+        $attachmentDir = UserManager::getUserPathById($messageInfo['user_receiver_id'], 'system');
+        $attachmentDir .= 'message_attachments/';
+
+        $sql = "SELECT * FROM $table
+                WHERE message_id = '$messageId'";
+        $result = Database::query($sql);
+        $files = [];
+        while ($row = Database::fetch_array($result, 'ASSOC')) {
+            $row['file_source'] = '';
+            if (file_exists($attachmentDir.$row['path'])) {
+                $row['file_source'] = $attachmentDir.$row['path'];
+            }
+            $files[] = $row;
+        }
+
+        return $files;
+    }
+
     /**
      * Get array of links (download) for message attachment files.
      *
@@ -1788,32 +1856,24 @@ class MessageManager
      */
     public static function get_links_message_attachment_files($messageId, $type = '')
     {
-        $table = Database::get_main_table(TABLE_MESSAGE_ATTACHMENT);
-        $messageId = intval($messageId);
-
+        $files = self::getAttachmentList($messageId);
         // get file attachments by message id
-        $links_attach_file = [];
-        if (!empty($messageId)) {
-            $sql = "SELECT * FROM $table
-                    WHERE message_id = '$messageId'";
-
-            $rs_file = Database::query($sql);
-            if (Database::num_rows($rs_file) > 0) {
-                $attach_icon = Display::return_icon('attachment.gif', '');
-                $archiveURL = api_get_path(WEB_CODE_PATH).'messages/download.php?type='.$type.'&file=';
-                while ($row_file = Database::fetch_array($rs_file)) {
-                    $archiveFile = $row_file['path'];
-                    $filename = $row_file['filename'];
-                    $filesize = format_file_size($row_file['size']);
-                    $filecomment = Security::remove_XSS($row_file['comment']);
-                    $filename = Security::remove_XSS($filename);
-                    $links_attach_file[] = $attach_icon.'&nbsp;<a href="'.$archiveURL.$archiveFile.'">'.$filename.'</a>
-                        &nbsp;('.$filesize.')'.(!empty($filecomment) ? '&nbsp;-&nbsp;<i>'.$filecomment.'</i>' : '');
-                }
+        $list = [];
+        if ($files) {
+            $attach_icon = Display::return_icon('attachment.gif', '');
+            $archiveURL = api_get_path(WEB_CODE_PATH).'messages/download.php?type='.$type.'&file=';
+            foreach ($files as $row_file) {
+                $archiveFile = $row_file['path'];
+                $filename = $row_file['filename'];
+                $filesize = format_file_size($row_file['size']);
+                $filecomment = Security::remove_XSS($row_file['comment']);
+                $filename = Security::remove_XSS($filename);
+                $list[] = $attach_icon.'&nbsp;<a href="'.$archiveURL.$archiveFile.'">'.$filename.'</a>
+                    &nbsp;('.$filesize.')'.(!empty($filecomment) ? '&nbsp;-&nbsp;<i>'.$filecomment.'</i>' : '');
             }
         }
 
-        return $links_attach_file;
+        return $list;
     }
 
     /**

+ 15 - 3
main/inc/lib/online.inc.php

@@ -536,17 +536,29 @@ function whoIsOnlineInThisSessionCount($timeLimit, $sessionId)
     $tableUser = Database::get_main_table(TABLE_MAIN_USER);
 
     $timeLimit = Database::escape_string($timeLimit);
-
     $online_time = time() - $timeLimit * 60;
     $current_date = api_get_utc_datetime($online_time);
 
+    $urlCondition = '';
+    $urlJoin = '';
+    if (api_is_multiple_url_enabled()) {
+        $accessUrlUser = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
+        $urlId = api_get_current_access_url_id();
+        $urlJoin = " INNER JOIN $accessUrlUser a ON (a.user_id = u.id) ";
+        $urlCondition = " AND a.access_url_id = $urlId ";
+    }
+
     $query = "SELECT count(login_user_id) as count
-              FROM $tblTrackOnline o INNER JOIN $tableUser u 
+              FROM $tblTrackOnline o 
+              INNER JOIN $tableUser u 
               ON (login_user_id = u.id)
+              $urlJoin
               WHERE 
                     u.status <> '".ANONYMOUS."' AND 
                     session_id = $sessionId AND 
-                    login_date >= '$current_date' ";
+                    login_date >= '$current_date' 
+                    $urlCondition
+            ";
     $result = Database::query($query);
 
     if (Database::num_rows($result) > 0) {

+ 118 - 61
main/inc/lib/sessionmanager.lib.php

@@ -10,6 +10,7 @@ use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser;
 use Chamilo\CoreBundle\Entity\SessionRelUser;
 use Chamilo\UserBundle\Entity\User;
 use ExtraField as ExtraFieldModel;
+use Monolog\Logger;
 
 /**
  * Class SessionManager.
@@ -1857,24 +1858,24 @@ class SessionManager
      * @author Carlos Vargas from existing code
      * @author Julio Montoya. Cleaning code.
      *
-     * @param int   $id_session
-     * @param array $user_list
+     * @param int   $sessionId
+     * @param array $userList
      * @param int   $session_visibility
      * @param bool  $empty_users
      *
      * @return bool
      */
-    public static function subscribe_users_to_session(
-        $id_session,
-        $user_list,
+    public static function subscribeUsersToSession(
+        $sessionId,
+        $userList,
         $session_visibility = SESSION_VISIBLE_READ_ONLY,
         $empty_users = true
     ) {
-        if ($id_session != strval(intval($id_session))) {
+        if ($sessionId != strval(intval($sessionId))) {
             return false;
         }
 
-        foreach ($user_list as $intUser) {
+        foreach ($userList as $intUser) {
             if ($intUser != strval(intval($intUser))) {
                 return false;
             }
@@ -1885,8 +1886,7 @@ class SessionManager
         $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
         $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
 
-        $entityManager = Database::getManager();
-        $session = $entityManager->find('ChamiloCoreBundle:Session', $id_session);
+        $session = api_get_session_entity($sessionId);
 
         // from function parameter
         if (empty($session_visibility)) {
@@ -1903,7 +1903,7 @@ class SessionManager
         }
 
         $sql = "SELECT user_id FROM $tbl_session_rel_course_rel_user
-                WHERE session_id = $id_session AND status = 0";
+                WHERE session_id = $sessionId AND status = 0";
         $result = Database::query($sql);
         $existingUsers = [];
         while ($row = Database::fetch_array($result)) {
@@ -1911,7 +1911,7 @@ class SessionManager
         }
 
         $sql = "SELECT c_id FROM $tbl_session_rel_course
-                WHERE session_id = $id_session";
+                WHERE session_id = $sessionId";
         $result = Database::query($sql);
         $course_list = [];
         while ($row = Database::fetch_array($result)) {
@@ -1919,10 +1919,10 @@ class SessionManager
         }
 
         if ($session->getSendSubscriptionNotification() &&
-            is_array($user_list)
+            is_array($userList)
         ) {
             // Sending emails only
-            foreach ($user_list as $user_id) {
+            foreach ($userList as $user_id) {
                 if (in_array($user_id, $existingUsers)) {
                     continue;
                 }
@@ -1981,12 +1981,12 @@ class SessionManager
         foreach ($course_list as $courseId) {
             // for each course in the session
             $nbr_users = 0;
-            $courseId = intval($courseId);
+            $courseId = (int) $courseId;
 
             $sql = "SELECT DISTINCT user_id
                     FROM $tbl_session_rel_course_rel_user
                     WHERE
-                        session_id = $id_session AND
+                        session_id = $sessionId AND
                         c_id = $courseId AND
                         status = 0
                     ";
@@ -1999,10 +1999,10 @@ class SessionManager
             // Delete existing users
             if ($empty_users) {
                 foreach ($existingUsers as $existing_user) {
-                    if (!in_array($existing_user, $user_list)) {
+                    if (!in_array($existing_user, $userList)) {
                         $sql = "DELETE FROM $tbl_session_rel_course_rel_user
                                 WHERE
-                                    session_id = $id_session AND
+                                    session_id = $sessionId AND
                                     c_id = $courseId AND
                                     user_id = $existing_user AND
                                     status = 0 ";
@@ -2015,7 +2015,7 @@ class SessionManager
                             api_get_utc_datetime(),
                             api_get_user_id(),
                             $courseId,
-                            $id_session
+                            $sessionId
                         );
 
                         if (Database::affected_rows($result)) {
@@ -2027,18 +2027,19 @@ class SessionManager
 
             // Replace with this new function
             // insert new users into session_rel_course_rel_user and ignore if they already exist
-            foreach ($user_list as $enreg_user) {
+            foreach ($userList as $enreg_user) {
                 if (!in_array($enreg_user, $existingUsers)) {
                     $status = self::get_user_status_in_course_session(
                         $enreg_user,
                         $courseId,
-                        $id_session
+                        $sessionId
                     );
+
                     // Avoid duplicate entries.
                     if ($status === false || ($status !== false && $status != 0)) {
                         $enreg_user = (int) $enreg_user;
                         $sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user (session_id, c_id, user_id, visibility, status)
-                                VALUES($id_session, $courseId, $enreg_user, $session_visibility, 0)";
+                                VALUES($sessionId, $courseId, $enreg_user, $session_visibility, 0)";
                         $result = Database::query($sql);
                         if (Database::affected_rows($result)) {
                             $nbr_users++;
@@ -2051,7 +2052,7 @@ class SessionManager
                             api_get_utc_datetime(),
                             api_get_user_id(),
                             $courseId,
-                            $id_session
+                            $sessionId
                         );
                     }
                 }
@@ -2060,45 +2061,50 @@ class SessionManager
             // Count users in this session-course relation
             $sql = "SELECT COUNT(user_id) as nbUsers
                     FROM $tbl_session_rel_course_rel_user
-                    WHERE session_id = $id_session AND c_id = $courseId AND status<>2";
+                    WHERE session_id = $sessionId AND c_id = $courseId AND status<>2";
             $rs = Database::query($sql);
             list($nbr_users) = Database::fetch_array($rs);
             // update the session-course relation to add the users total
             $sql = "UPDATE $tbl_session_rel_course SET nbr_users = $nbr_users
-                    WHERE session_id = $id_session AND c_id = $courseId";
+                    WHERE session_id = $sessionId AND c_id = $courseId";
             Database::query($sql);
         }
 
         // Delete users from the session
         if ($empty_users === true) {
             $sql = "DELETE FROM $tbl_session_rel_user
-                    WHERE session_id = $id_session AND relation_type<>".SESSION_RELATION_TYPE_RRHH."";
+                    WHERE 
+                      session_id = $sessionId AND 
+                      relation_type <> ".SESSION_RELATION_TYPE_RRHH;
+            // Don't reset session_rel_user.registered_at of users that will be registered later anyways.
+            if (!empty($userList)) {
+                $avoidDeleteThisUsers = " AND user_id NOT IN ('".implode("','", $userList)."')";
+                $sql .= $avoidDeleteThisUsers;
+            }
             Database::query($sql);
         }
 
         // Insert missing users into session
-        $nbr_users = 0;
-        foreach ($user_list as $enreg_user) {
-            $isUserSubscribed = self::isUserSubscribedAsStudent($id_session, $enreg_user);
+        foreach ($userList as $enreg_user) {
+            $isUserSubscribed = self::isUserSubscribedAsStudent($sessionId, $enreg_user);
             if ($isUserSubscribed === false) {
                 $enreg_user = (int) $enreg_user;
-                $nbr_users++;
                 $sql = "INSERT IGNORE INTO $tbl_session_rel_user (relation_type, session_id, user_id, registered_at)
-                        VALUES (0, $id_session, $enreg_user, '".api_get_utc_datetime()."')";
+                        VALUES (0, $sessionId, $enreg_user, '".api_get_utc_datetime()."')";
                 Database::query($sql);
             }
         }
 
         // update number of users in the session
-        $nbr_users = count($user_list);
+        $nbr_users = count($userList);
         if ($empty_users) {
             // update number of users in the session
             $sql = "UPDATE $tbl_session SET nbr_users= $nbr_users
-                    WHERE id = $id_session ";
+                    WHERE id = $sessionId ";
             Database::query($sql);
         } else {
             $sql = "UPDATE $tbl_session SET nbr_users = nbr_users + $nbr_users
-                    WHERE id = $id_session";
+                    WHERE id = $sessionId";
             Database::query($sql);
         }
     }
@@ -2844,7 +2850,7 @@ class SessionManager
      * @param string $name
      *
      * @return mixed false if the session does not exist, array if the session exist
-     * */
+     */
     public static function get_session_by_name($name)
     {
         $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
@@ -2865,6 +2871,32 @@ class SessionManager
         }
     }
 
+    /**
+     * @param int $sessionId
+     * @param int $name
+     *
+     * @return bool
+     */
+    public static function sessionNameExistBesidesMySession($sessionId, $name)
+    {
+        $table = Database::get_main_table(TABLE_MAIN_SESSION);
+        $name = Database::escape_string(trim($name));
+        if (empty($name)) {
+            return false;
+        }
+
+        $sql = "SELECT *
+		        FROM $table
+		        WHERE name = '$name' AND id <> $sessionId ";
+        $result = Database::query($sql);
+        $num = Database::num_rows($result);
+        if ($num > 0) {
+            return true;
+        }
+
+        return false;
+    }
+
     /**
      * Create a session category.
      *
@@ -4462,7 +4494,7 @@ class SessionManager
             }
             $users = null;
             //Subscribing in read only mode
-            self::subscribe_users_to_session(
+            self::subscribeUsersToSession(
                 $sid,
                 $short_users,
                 SESSION_VISIBLE_READ_ONLY,
@@ -4706,11 +4738,10 @@ SQL;
 
     /**
      * @param string $file
-     * @param bool   $updateSession                                   options:
-     *                                                                true: if the session exists it will be updated.
+     * @param bool   $updateSession                                   true: if the session exists it will be updated.
      *                                                                false: if session exists a new session will be created adding a counter session1, session2, etc
      * @param int    $defaultUserId
-     * @param mixed  $logger
+     * @param Logger $logger
      * @param array  $extraFields                                     convert a file row to an extra field. Example in CSV file there's a SessionID
      *                                                                then it will converted to extra_external_session_id if you set: array('SessionId' => 'extra_external_session_id')
      * @param string $extraFieldId
@@ -4810,6 +4841,13 @@ SQL;
                 }
 
                 $session_name = $enreg['SessionName'];
+
+                if ($debug) {
+                    $logger->addInfo('---------------------------------------');
+                    $logger->addInfo("Sessions - Start process of session: $session_name");
+                    $logger->addInfo('---------------------------------------');
+                }
+
                 // Default visibility
                 $visibilityAfterExpirationPerSession = $sessionVisibility;
 
@@ -4958,9 +4996,11 @@ SQL;
                                     self::update_session_extra_field_value($session_id, substr($key, 6), $value);
                                 }
                             }
-                            $logger->addInfo("Sessions - Session created: #$session_id - $session_name");
+                            $logger->addInfo("Session created: #$session_id - $session_name");
                         } else {
-                            $logger->addError("Sessions - Session NOT created: $session_name");
+                            $message = "Sessions - Session NOT created: $session_name";
+                            $logger->addError($message);
+                            $report[] = $message;
                         }
                     }
                     $session_counter++;
@@ -4980,12 +5020,11 @@ SQL;
                     if ($my_session_result === false) {
                         // One more check
                         $sessionExistsWithName = self::get_session_by_name($session_name);
-
                         if ($sessionExistsWithName) {
                             if ($debug) {
-                                $logger->addError(
-                                    "Sessions - Trying to update a session, but name already exists: $session_name"
-                                );
+                                $message = "Skip Session - Trying to update a session, but name already exists: $session_name";
+                                $logger->addError($message);
+                                $report[] = $message;
                             }
                             continue;
                         }
@@ -5053,8 +5092,6 @@ SQL;
                             'id_coach' => $coach_id,
                             'access_start_date' => $dateStart,
                             'access_end_date' => $dateEnd,
-                            'display_start_date' => $dateStart,
-                            'display_end_date' => $dateEnd,
                             'display_start_date' => $displayAccessStartDate,
                             'display_end_date' => $displayAccessEndDate,
                             'coach_access_start_date' => $coachAccessStartDate,
@@ -5081,11 +5118,28 @@ SQL;
                                     $sessionName = Database::escape_string($enreg['SessionName']);
                                     $sql = "UPDATE $tbl_session SET name = '$sessionName' WHERE id = $session_id";
                                     Database::query($sql);
+                                    $logger->addInfo(
+                                        "Session #$session_id name IS updated with: '$session_name' External id: ".$enreg['extra_'.$extraFieldId]
+                                    );
                                 } else {
-                                    if ($debug) {
-                                        $report[] = "Error when update session: Name already exists: Session #$session_id Name: '$session_name' External id: ".$enreg['extra_'.$extraFieldId];
+                                    $sessionExistsBesidesMe = self::sessionNameExistBesidesMySession(
+                                        $session_id,
+                                        $session_name
+                                    );
+                                    if ($sessionExistsBesidesMe === true) {
+                                        if ($debug) {
+                                            $message = "Skip Session. Error when update session Session #$session_id Name: '$session_name'. Other session has the same name. External id: ".$enreg['extra_'.$extraFieldId];
+                                            $logger->addError($message);
+                                            $report[] = $message;
+                                        }
+                                        continue;
+                                    } else {
+                                        if ($debug) {
+                                            $logger->addInfo(
+                                                "Session #$session_id name is not updated because it didn't change (but update of other session values will continue) Name: '$session_name' External id: ".$enreg['extra_'.$extraFieldId]
+                                            );
+                                        }
                                     }
-                                    continue;
                                 }
                             }
                         } else {
@@ -5094,14 +5148,10 @@ SQL;
                         }
 
                         if ($debug) {
-                            $logger->addError("Sessions - Session #$session_id to be updated: '$session_name'");
+                            $logger->addInfo("Session #$session_id to be updated: '$session_name'");
                         }
 
                         if ($session_id) {
-                            if ($debug) {
-                                $logger->addError("Sessions - Session to be updated #$session_id");
-                            }
-
                             $sessionInfo = api_get_session_info($session_id);
                             $params['show_description'] = isset($sessionInfo['show_description']) ? $sessionInfo['show_description'] : intval($showDescription);
 
@@ -5122,13 +5172,16 @@ SQL;
                             }
 
                             Database::update($tbl_session, $params, ['id = ?' => $session_id]);
-
                             foreach ($enreg as $key => $value) {
                                 if (substr($key, 0, 6) == 'extra_') { //an extra field
                                     self::update_session_extra_field_value($session_id, substr($key, 6), $value);
                                 }
                             }
 
+                            if ($debug) {
+                                $logger->addInfo("Session updated #$session_id");
+                            }
+
                             // Delete session-user relation only for students
                             $sql = "DELETE FROM $tbl_session_user
                                     WHERE session_id = '$session_id' AND relation_type <> ".SESSION_RELATION_TYPE_RRHH;
@@ -5181,7 +5234,7 @@ SQL;
                                     registered_at = '".api_get_utc_datetime()."'";
                             Database::query($sql);
                             if ($debug) {
-                                $logger->addInfo("Sessions - Adding User #$user_id ($user) to session #$session_id");
+                                $logger->addInfo("Adding User #$user_id ($user) to session #$session_id");
                             }
                             $user_counter++;
                         }
@@ -5233,7 +5286,7 @@ SQL;
                         self::installCourse($session_id, $courseInfo['real_id']);
 
                         if ($debug) {
-                            $logger->addInfo("Sessions - Adding course '$course_code' to session #$session_id");
+                            $logger->addInfo("Adding course '$course_code' to session #$session_id");
                         }
 
                         $course_counter++;
@@ -5258,7 +5311,7 @@ SQL;
                                     $course_code
                                 );
                                 if ($debug) {
-                                    $msg = "Sessions - Adding student list ".implode(', #', $userList)." to course: '$course_code' and session #$session_id";
+                                    $msg = "Adding student list ".implode(', #', $userList)." to course: '$course_code' and session #$session_id";
                                     $logger->addInfo($msg);
                                 }
                             }
@@ -5299,7 +5352,7 @@ SQL;
                                         );
 
                                         if ($debug) {
-                                            $logger->addInfo("Sessions - Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
+                                            $logger->addInfo("Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
                                         }
                                         $savedCoaches[] = $coach_id;
                                     } else {
@@ -5607,7 +5660,7 @@ SQL;
                                         $course_code
                                     );
                                     if ($debug) {
-                                        $logger->addInfo("Sessions - Adding student: user #$user_id ($user) to course: '$course_code' and session #$session_id");
+                                        $logger->addInfo("Adding student: user #$user_id ($user) to course: '$course_code' and session #$session_id");
                                     }
                                 } else {
                                     $error_message .= get_lang('UserDoesNotExist').': '.$user.$eol;
@@ -5624,6 +5677,10 @@ SQL;
                 Database::query($sql);
 
                 self::addClassesByName($session_id, $classes, false);
+
+                if ($debug) {
+                    $logger->addInfo("End process session #$session_id -------------------- ");
+                }
             }
 
             if (!empty($report)) {
@@ -6069,7 +6126,7 @@ SQL;
                                 continue;
                             }
                             $messages[] = Display::return_message(get_lang('StudentList').'<br />'.$userToString, 'info', false);
-                            self::subscribe_users_to_session(
+                            self::subscribeUsersToSession(
                                 $sessionDestinationId,
                                 $newUserList,
                                 SESSION_VISIBLE_READ_ONLY,

+ 2 - 2
main/inc/lib/statistics.lib.php

@@ -102,8 +102,8 @@ class Statistics
     /**
      * Count users.
      *
-     * @param int    $status                optional user status (COURSEMANAGER or STUDENT), if it's not setted it'll count all users
-     * @param string $categoryCode          Optional, code of a course category. Default: count only users without filtering category
+     * @param int    $status                user status (COURSEMANAGER or STUDENT) if not setted it'll count all users
+     * @param string $categoryCode          course category code. Default: count only users without filtering category
      * @param bool   $countInvisibleCourses Count invisible courses (todo)
      * @param bool   $onlyActive            Count only active users (false to only return currently active users)
      *

+ 2 - 2
main/inc/lib/system_announcements.lib.php

@@ -688,9 +688,9 @@ class SystemAnnouncementManager
      */
     public static function get_announcement($id)
     {
-        $db_table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
+        $table = Database::get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
         $id = intval($id);
-        $sql = "SELECT * FROM ".$db_table." WHERE id = ".$id;
+        $sql = "SELECT * FROM ".$table." WHERE id = ".$id;
         $announcement = Database::fetch_object(Database::query($sql));
 
         return $announcement;

+ 8 - 12
main/inc/lib/tracking.lib.php

@@ -7497,10 +7497,9 @@ class TrackingCourseLog
         $urlBase = api_get_path(WEB_CODE_PATH).'mySpace/myStudents.php?details=true&cidReq='.$course_code.
             '&course='.$course_code.'&origin=tracking_course&id_session='.$session_id;
 
+        $sortByFirstName = api_sort_by_first_name();
         while ($user = Database::fetch_array($res, 'ASSOC')) {
             $user['official_code'] = $user['col0'];
-            $user['lastname'] = $user['col1'];
-            $user['firstname'] = $user['col2'];
             $user['username'] = $user['col3'];
 
             $user['time'] = api_time_to_hms(
@@ -7587,15 +7586,14 @@ class TrackingCourseLog
                              </a></center>';
 
             // store columns in array $users
-            $is_western_name_order = api_is_western_name_order();
             $user_row = [];
             $user_row['official_code'] = $user['official_code']; //0
-            if ($is_western_name_order) {
-                $user_row['firstname'] = $user['firstname'];
-                $user_row['lastname'] = $user['lastname'];
+            if ($sortByFirstName) {
+                $user_row['firstname'] = $user['col2'];
+                $user_row['lastname'] = $user['col1'];
             } else {
-                $user_row['lastname'] = $user['lastname'];
-                $user_row['firstname'] = $user['firstname'];
+                $user_row['lastname'] = $user['col1'];
+                $user_row['firstname'] = $user['col2'];
             }
             $user_row['username'] = $user['username'];
             $user_row['time'] = $user['time'];
@@ -7649,7 +7647,6 @@ class TrackingCourseLog
 
                 $csv_content[] = $user_row;
             }
-
             $users[] = array_values($user_row);
         }
 
@@ -7728,7 +7725,7 @@ class TrackingCourseLog
         $users = [];
 
         $course_info = api_get_course_info($course_code);
-
+        $sortByFirstName = api_sort_by_first_name();
         while ($user = Database::fetch_array($res, 'ASSOC')) {
             $courseInfo = api_get_course_info($course_code);
             $courseId = $courseInfo['real_id'];
@@ -7779,10 +7776,9 @@ class TrackingCourseLog
                          </center>';
 
             // store columns in array $users
-            $is_western_name_order = api_is_western_name_order();
             $user_row = [];
             $user_row['official_code'] = $user['official_code']; //0
-            if ($is_western_name_order) {
+            if ($sortByFirstName) {
                 $user_row['firstname'] = $user['firstname'];
                 $user_row['lastname'] = $user['lastname'];
             } else {

+ 2 - 2
main/inc/lib/usergroup.lib.php

@@ -695,7 +695,7 @@ class UserGroup extends Model
                 Database::insert($this->usergroup_rel_session_table, $params);
 
                 if (!empty($user_list)) {
-                    SessionManager::subscribe_users_to_session(
+                    SessionManager::subscribeUsersToSession(
                         $session_id,
                         $user_list,
                         null,
@@ -887,7 +887,7 @@ class UserGroup extends Model
             // Adding sessions
             if (!empty($session_list)) {
                 foreach ($session_list as $session_id) {
-                    SessionManager::subscribe_users_to_session($session_id, $new_items, null, false);
+                    SessionManager::subscribeUsersToSession($session_id, $new_items, null, false);
                 }
             }
 

+ 8 - 3
main/inc/lib/usermanager.lib.php

@@ -2940,13 +2940,18 @@ class UserManager
         $orderBySettings = api_get_configuration_value('my_courses_session_order');
         if (!empty($orderBySettings) && isset($orderBySettings['field']) && isset($orderBySettings['order'])) {
             $field = $orderBySettings['field'];
-            $order = $orderBySettings['order'];
+            $orderSetting = $orderBySettings['order'];
             switch ($field) {
                 case 'start_date':
-                    $order = " ORDER BY s.accessStartDate $order";
+                    $order = " ORDER BY s.accessStartDate $orderSetting";
                     break;
                 case 'end_date':
-                    $order = " ORDER BY s.accessEndDate $order";
+                    $order = " ORDER BY s.accessEndDate $orderSetting ";
+                    if ($orderSetting == 'asc') {
+                        // Put null values at the end
+                        // https://stackoverflow.com/questions/12652034/how-can-i-order-by-null-in-dql
+                        $order = " ORDER BY _isFieldNull asc, s.accessEndDate asc";
+                    }
                     break;
             }
         }

+ 9 - 3
main/inc/lib/userportal.lib.php

@@ -87,7 +87,9 @@ class IndexManager
                 $my_exercise = $exercise_list[0];
                 $url = Display::url(
                     $my_exercise['title'],
-                    api_get_path(WEB_CODE_PATH).'exercise/overview.php?exerciseId='.$my_exercise['id'].'&cidReq='.$my_exercise['course_code'].'&id_session='.$my_exercise['session_id']
+                    api_get_path(
+                        WEB_CODE_PATH
+                    ).'exercise/overview.php?exerciseId='.$my_exercise['id'].'&cidReq='.$my_exercise['course_code'].'&id_session='.$my_exercise['session_id']
                 );
                 $this->tpl->assign('exercise_url', $url);
                 $this->tpl->assign(
@@ -228,7 +230,9 @@ class IndexManager
             if ($show_create_link) {
                 $html .= '<li class="add-course"><a href="'.api_get_path(WEB_CODE_PATH).'create_course/add_course.php">'
                     .Display::return_icon('new-course.png', get_lang('CourseCreate'))
-                    .(api_get_setting('course_validation') == 'true' ? get_lang('CreateCourseRequest') : get_lang('CourseCreate'))
+                    .(api_get_setting('course_validation') == 'true' ? get_lang('CreateCourseRequest') : get_lang(
+                        'CourseCreate'
+                    ))
                     .'</a></li>';
             }
 
@@ -239,7 +243,9 @@ class IndexManager
                         .get_lang('CourseCatalog')
                         .'</a></li>';
                 } else {
-                    $html .= '<li><a href="'.api_get_path(WEB_CODE_PATH).'dashboard/index.php">'.get_lang('Dashboard').'</a></li>';
+                    $html .= '<li><a href="'.api_get_path(WEB_CODE_PATH).'dashboard/index.php">'.get_lang(
+                            'Dashboard'
+                        ).'</a></li>';
                 }
             }
             $html .= '</ul>';

+ 128 - 73
main/lp/learnpath.class.php

@@ -2359,9 +2359,9 @@ class learnpath
         $allow = api_get_configuration_value('allow_teachers_to_access_blocked_lp_by_prerequisite');
         if ($allow) {
             if (api_is_allowed_to_edit() ||
-                api_is_platform_admin() ||
+                api_is_platform_admin(true) ||
                 api_is_drh() ||
-                api_is_coach($sessionId, $courseInfo['real_id'])
+                api_is_coach($sessionId, $courseInfo['real_id'], false)
             ) {
                 return false;
             }
@@ -4337,7 +4337,7 @@ class learnpath
         $allow = api_get_configuration_value('allow_teachers_to_access_blocked_lp_by_prerequisite');
         if ($allow) {
             if (api_is_allowed_to_edit() ||
-                api_is_platform_admin() ||
+                api_is_platform_admin(true) ||
                 api_is_drh() ||
                 api_is_coach(api_get_session_id(), api_get_course_int_id())
             ) {
@@ -5091,7 +5091,6 @@ class learnpath
             error_log('In learnpath::set_jslib()', 0);
         }
         $lp = $this->get_id();
-        $course_id = api_get_course_int_id();
 
         if ($lp != 0) {
             $tbl_lp = Database::get_course_table(TABLE_LP_MAIN);
@@ -5791,7 +5790,8 @@ class learnpath
         $course_id = api_get_course_int_id();
         $table = Database::get_course_table(TABLE_LP_MAIN);
         $sql = "SELECT * FROM $table 
-                WHERE c_id = $course_id ORDER BY display_order";
+                WHERE c_id = $course_id 
+                ORDER BY display_order";
         $res = Database::query($sql);
         if ($res === false) {
             return false;
@@ -5823,7 +5823,6 @@ class learnpath
      */
     public function update_reinit()
     {
-        $course_id = api_get_course_int_id();
         if ($this->debug > 0) {
             error_log('In learnpath::update_reinit()', 0);
         }
@@ -6193,18 +6192,16 @@ class learnpath
 
     /**
      * @param string $update_audio
-     * @param bool   $drop_element_here
      *
-     * @return string
+     * @return array
      */
-    public function return_new_tree($update_audio = 'false', $drop_element_here = false)
+    public function processBuildMenuElements($update_audio = 'false')
     {
-        $return = '';
         $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
         $course_id = api_get_course_int_id();
-        $tbl_lp_item = Database::get_course_table(TABLE_LP_ITEM);
+        $table = Database::get_course_table(TABLE_LP_ITEM);
 
-        $sql = "SELECT * FROM $tbl_lp_item
+        $sql = "SELECT * FROM $table
                 WHERE c_id = $course_id AND lp_id = ".$this->lp_id;
 
         $result = Database::query($sql);
@@ -6237,6 +6234,8 @@ class learnpath
         $default_content = null;
         $elements = [];
         $return_audio = null;
+        $iconPath = api_get_path(SYS_CODE_PATH).'img/';
+        $mainUrl = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.api_get_cidreq();
 
         for ($i = 0; $i < count($arrLP); $i++) {
             $title = $arrLP[$i]['title'];
@@ -6244,7 +6243,7 @@ class learnpath
 
             // Link for the documents
             if ($arrLP[$i]['item_type'] == 'document') {
-                $url = api_get_self().'?'.api_get_cidreq().'&action=view_item&mode=preview_document&id='.$arrLP[$i]['id'].'&lp_id='.$this->lp_id;
+                $url = $mainUrl.'&action=view_item&mode=preview_document&id='.$arrLP[$i]['id'].'&lp_id='.$this->lp_id;
                 $title_cut = Display::url(
                     $title_cut,
                     $url,
@@ -6269,10 +6268,10 @@ class learnpath
             $return_audio .= '<tr id ="lp_item_'.$arrLP[$i]['id'].'" class="'.$oddClass.'">';
             $icon_name = str_replace(' ', '', $arrLP[$i]['item_type']);
 
-            if (file_exists('../img/lp_'.$icon_name.'.png')) {
+            if (file_exists($iconPath.'lp_'.$icon_name.'.png')) {
                 $icon = Display::return_icon('lp_'.$icon_name.'.png');
             } else {
-                if (file_exists('../img/lp_'.$icon_name.'.gif')) {
+                if (file_exists($iconPath.'lp_'.$icon_name.'.gif')) {
                     $icon = Display::return_icon('lp_'.$icon_name.'.gif');
                 } else {
                     if ($arrLP[$i]['item_type'] === TOOL_LP_FINAL_ITEM) {
@@ -6302,11 +6301,11 @@ class learnpath
             }
 
             $return_audio .= Display::span($icon.' '.$title).
-            Display::tag(
-                'td',
-                $audio,
-                ['style' => '']
-            );
+                Display::tag(
+                    'td',
+                    $audio,
+                    ['style' => '']
+                );
             $return_audio .= '</td>';
             $move_icon = '';
             $move_item_icon = '';
@@ -6334,7 +6333,7 @@ class learnpath
                 // No edit for this item types
                 if (!in_array($arrLP[$i]['item_type'], ['sco', 'asset', 'final_item'])) {
                     if ($arrLP[$i]['item_type'] != 'dir') {
-                        $edit_icon .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=edit_item&view=build&id='.$arrLP[$i]['id'].'&lp_id='.$this->lp_id.'&path_item='.$arrLP[$i]['path'].'" class="btn btn-default">';
+                        $edit_icon .= '<a href="'.$mainUrl.'&action=edit_item&view=build&id='.$arrLP[$i]['id'].'&lp_id='.$this->lp_id.'&path_item='.$arrLP[$i]['path'].'" class="btn btn-default">';
                         $edit_icon .= Display::return_icon(
                             'edit.png',
                             get_lang('LearnpathEditModule'),
@@ -6352,11 +6351,11 @@ class learnpath
                                 );
                             }
                             if ($forumThread) {
-                                $forumIconUrl = api_get_self().'?'.api_get_cidreq().'&'.http_build_query([
-                                    'action' => 'dissociate_forum',
-                                    'id' => $arrLP[$i]['id'],
-                                    'lp_id' => $this->lp_id,
-                                ]);
+                                $forumIconUrl = $mainUrl.'&'.http_build_query([
+                                        'action' => 'dissociate_forum',
+                                        'id' => $arrLP[$i]['id'],
+                                        'lp_id' => $this->lp_id,
+                                    ]);
                                 $forumIcon = Display::url(
                                     Display::return_icon(
                                         'forum.png',
@@ -6368,11 +6367,11 @@ class learnpath
                                     ['class' => 'btn btn-default lp-btn-dissociate-forum']
                                 );
                             } else {
-                                $forumIconUrl = api_get_self().'?'.api_get_cidreq().'&'.http_build_query([
-                                    'action' => 'create_forum',
-                                    'id' => $arrLP[$i]['id'],
-                                    'lp_id' => $this->lp_id,
-                                ]);
+                                $forumIconUrl = $mainUrl.'&'.http_build_query([
+                                        'action' => 'create_forum',
+                                        'id' => $arrLP[$i]['id'],
+                                        'lp_id' => $this->lp_id,
+                                    ]);
                                 $forumIcon = Display::url(
                                     Display::return_icon(
                                         'forum.png',
@@ -6386,7 +6385,7 @@ class learnpath
                             }
                         }
                     } else {
-                        $edit_icon .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=edit_item&id='.$arrLP[$i]['id'].'&lp_id='.$this->lp_id.'&path_item='.$arrLP[$i]['path'].'" class="btn btn-default">';
+                        $edit_icon .= '<a href="'.$mainUrl.'&action=edit_item&id='.$arrLP[$i]['id'].'&lp_id='.$this->lp_id.'&path_item='.$arrLP[$i]['path'].'" class="btn btn-default">';
                         $edit_icon .= Display::return_icon(
                             'edit.png',
                             get_lang('LearnpathEditModule'),
@@ -6397,7 +6396,7 @@ class learnpath
                     }
                 } else {
                     if ($arrLP[$i]['item_type'] == TOOL_LP_FINAL_ITEM) {
-                        $edit_icon .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=edit_item&id='.$arrLP[$i]['id'].'&lp_id='.$this->lp_id.'" class="btn btn-default">';
+                        $edit_icon .= '<a href="'.$mainUrl.'&action=edit_item&id='.$arrLP[$i]['id'].'&lp_id='.$this->lp_id.'" class="btn btn-default">';
                         $edit_icon .= Display::return_icon(
                             'edit.png',
                             get_lang('Edit'),
@@ -6409,7 +6408,7 @@ class learnpath
                 }
 
                 $delete_icon .= ' <a 
-                    href="'.api_get_self().'?'.api_get_cidreq().'&action=delete_item&id='.$arrLP[$i]['id'].'&lp_id='.$this->lp_id.'" 
+                    href="'.$mainUrl.'&action=delete_item&id='.$arrLP[$i]['id'].'&lp_id='.$this->lp_id.'" 
                     onclick="return confirmation(\''.addslashes($title).'\');" 
                     class="btn btn-default">';
                 $delete_icon .= Display::return_icon(
@@ -6420,7 +6419,7 @@ class learnpath
                 );
                 $delete_icon .= '</a>';
 
-                $url = api_get_self().'?'.api_get_cidreq().'&view=build&id='.$arrLP[$i]['id'].'&lp_id='.$this->lp_id;
+                $url = $mainUrl.'&view=build&id='.$arrLP[$i]['id'].'&lp_id='.$this->lp_id;
                 $previewImage = Display::return_icon(
                     'preview_view.png',
                     get_lang('Preview'),
@@ -6431,7 +6430,7 @@ class learnpath
                 switch ($arrLP[$i]['item_type']) {
                     case TOOL_DOCUMENT:
                     case TOOL_LP_FINAL_ITEM:
-                        $urlPreviewLink = api_get_self().'?'.api_get_cidreq().'&action=view_item&mode=preview_document&id='.$arrLP[$i]['id'].'&lp_id='.$this->lp_id;
+                        $urlPreviewLink = $mainUrl.'&action=view_item&mode=preview_document&id='.$arrLP[$i]['id'].'&lp_id='.$this->lp_id;
                         $previewIcon = Display::url(
                             $previewImage,
                             $urlPreviewLink,
@@ -6460,8 +6459,7 @@ class learnpath
                             $this->course_int_id,
                             $this->lp_id,
                             $arrLP[$i]['id'],
-                            0,
-                            ''
+                            0
                         );
                         $previewIcon = Display::url(
                             $previewImage,
@@ -6523,11 +6521,22 @@ class learnpath
                     Display::span($title_cut).
                     Display::tag(
                         'div',
-                        "<div class=\"btn-group btn-group-xs\">$previewIcon $audio $edit_icon $forumIcon $prerequisities_icon $move_item_icon $audio_icon $delete_icon</div>",
+                        "<div class=\"btn-group btn-group-xs\">
+                                    $previewIcon 
+                                    $audio 
+                                    $edit_icon 
+                                    $forumIcon 
+                                    $prerequisities_icon 
+                                    $move_item_icon 
+                                    $audio_icon 
+                                    $delete_icon
+                                </div>",
                         ['class' => 'btn-toolbar button_actions']
                     );
             } else {
-                $row = Display::span($title.$icon).Display::span($audio, ['class' => 'button_actions']);
+                $row =
+                    Display::span($title.$icon).
+                    Display::span($audio, ['class' => 'button_actions']);
             }
 
             $parent_id = $arrLP[$i]['parent_item_id'];
@@ -6582,18 +6591,59 @@ class learnpath
             }
         }
 
+        return [
+            'elements' => $elements,
+            'default_data' => $default_data,
+            'default_content' => $default_content,
+            'return_audio' => $return_audio,
+        ];
+    }
+
+    /**
+     * @param string $updateAudio true/false strings
+     *
+     * @return string
+     */
+    public function returnLpItemList($updateAudio)
+    {
+        $result = $this->processBuildMenuElements($updateAudio);
+
+        $html = self::print_recursive(
+            $result['elements'],
+            $result['default_data'],
+            $result['default_content']
+        );
+
+        if (!empty($html)) {
+            $html .= Display::return_message(get_lang('DragAndDropAnElementHere'));
+        }
+
+        return $html;
+    }
+
+    /**
+     * @param string $update_audio
+     * @param bool   $drop_element_here
+     *
+     * @return string
+     */
+    public function return_new_tree($update_audio = 'false', $drop_element_here = false)
+    {
+        $return = '';
+        $result = $this->processBuildMenuElements($update_audio);
+
         $list = '<ul id="lp_item_list">';
         $tree = self::print_recursive(
-            $elements,
-            $default_data,
-            $default_content
+            $result['elements'],
+            $result['default_data'],
+            $result['default_content']
         );
 
         if (!empty($tree)) {
             $list .= $tree;
         } else {
             if ($drop_element_here) {
-                $list .= Display::return_message(get_lang("DragAndDropAnElementHere"));
+                $list .= Display::return_message(get_lang('DragAndDropAnElementHere'));
             }
         }
         $list .= '</ul>';
@@ -6608,7 +6658,7 @@ class learnpath
         );
 
         if ($update_audio == 'true') {
-            $return = $return_audio;
+            $return = $result['return_audio'];
         }
 
         return $return;
@@ -6647,6 +6697,7 @@ class learnpath
                 );
             } else {
                 // Sections
+                $data = '';
                 if (isset($item['children'])) {
                     $data = self::print_recursive($item['children'], $default_data, $default_content);
                 }
@@ -6680,7 +6731,6 @@ class learnpath
     ) {
         $actionsLeft = '';
         $actionsRight = '';
-
         $actionsLeft .= Display::url(
             Display::return_icon(
                 'preview_view.png',
@@ -6694,6 +6744,7 @@ class learnpath
                 'isStudentView' => 'true',
             ])
         );
+
         $actionsLeft .= Display::url(
             Display::return_icon(
                 'upload_audio.png',
@@ -6854,7 +6905,6 @@ class learnpath
 
         // Creating LP folder
         $documentId = null;
-
         if ($folder) {
             $filepath = api_get_path(SYS_COURSE_PATH).$course['path'].'/document';
             if (!is_dir($filepath.'/'.$dir)) {
@@ -10326,7 +10376,6 @@ class learnpath
      */
     public function get_student_publications()
     {
-        $sessionId = api_get_session_id();
         $return = '<ul class="lp_resource">';
         $return .= '<li class="lp_resource_element">';
         $return .= Display::return_icon('works_new.gif');
@@ -10334,34 +10383,32 @@ class learnpath
             get_lang('AddAssignmentPage').'</a>';
         $return .= '</li>';
 
-        if (empty($sessionId)) {
-            require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
-            $works = getWorkListTeacher(0, 100, null, null, null);
-            if (!empty($works)) {
-                foreach ($works as $work) {
-                    $link = Display::url(
-                        Display::return_icon('preview_view.png', get_lang('Preview')),
-                        api_get_path(WEB_CODE_PATH).'work/work_list_all.php?'.api_get_cidreq().'&id='.$work['iid'],
-                        ['target' => '_blank']
-                    );
+        require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
+        $works = getWorkListTeacher(0, 100, null, null, null);
+        if (!empty($works)) {
+            foreach ($works as $work) {
+                $link = Display::url(
+                    Display::return_icon('preview_view.png', get_lang('Preview')),
+                    api_get_path(WEB_CODE_PATH).'work/work_list_all.php?'.api_get_cidreq().'&id='.$work['iid'],
+                    ['target' => '_blank']
+                );
 
-                    $return .= '<li class="lp_resource_element" data_id="'.$work['iid'].'" data_type="'.TOOL_STUDENTPUBLICATION.'" title="'.Security::remove_XSS(cut(strip_tags($work['title']), 80)).'">';
-                    $return .= '<a class="moved" href="#">';
-                    $return .= Display::return_icon(
-                        'move_everywhere.png',
-                        get_lang('Move'),
-                        [],
-                        ICON_SIZE_TINY
-                    );
-                    $return .= '</a> ';
+                $return .= '<li class="lp_resource_element" data_id="'.$work['iid'].'" data_type="'.TOOL_STUDENTPUBLICATION.'" title="'.Security::remove_XSS(cut(strip_tags($work['title']), 80)).'">';
+                $return .= '<a class="moved" href="#">';
+                $return .= Display::return_icon(
+                    'move_everywhere.png',
+                    get_lang('Move'),
+                    [],
+                    ICON_SIZE_TINY
+                );
+                $return .= '</a> ';
 
-                    $return .= Display::return_icon('works.png', '', [], ICON_SIZE_TINY);
-                    $return .= ' <a class="moved" href="'.api_get_self().'?'.api_get_cidreq().'&action=add_item&type='.TOOL_STUDENTPUBLICATION.'&file='.$work['iid'].'&lp_id='.$this->lp_id.'">'.
-                        Security::remove_XSS(cut(strip_tags($work['title']), 80)).' '.$link.'
-                    </a>';
+                $return .= Display::return_icon('works.png', '', [], ICON_SIZE_TINY);
+                $return .= ' <a class="moved" href="'.api_get_self().'?'.api_get_cidreq().'&action=add_item&type='.TOOL_STUDENTPUBLICATION.'&file='.$work['iid'].'&lp_id='.$this->lp_id.'">'.
+                    Security::remove_XSS(cut(strip_tags($work['title']), 80)).' '.$link.'
+                </a>';
 
-                    $return .= '</li>';
-                }
+                $return .= '</li>';
             }
         }
 
@@ -11811,6 +11858,14 @@ EOD;
         $item->setCId($params['c_id']);
         $em->persist($item);
         $em->flush();
+
+        api_item_property_update(
+            api_get_course_info(),
+            TOOL_LEARNPATH_CATEGORY,
+            $item->getId(),
+            'visible',
+            api_get_user_id()
+        );
     }
 
     /**

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

@@ -2487,7 +2487,8 @@ class learnpathItem
                                                             exe_user_id = '.$user_id.' AND
                                                             orig_lp_id = '.$this->lp_id.' AND
                                                             orig_lp_item_id = '.$prereqs_string.' AND
-                                                            status <> "incomplete"
+                                                            status <> "incomplete" AND
+                                                            c_id = '.$course_id.'
                                                         ORDER BY exe_date DESC
                                                         LIMIT 0, 1';
                                                 $rs_quiz = Database::query($sql);
@@ -2530,11 +2531,12 @@ class learnpathItem
                                                 }
                                             }
                                         } else {
-                                            // 3. for multiple attempts we check that there are minimum 1 item completed.
+                                            // 3. For multiple attempts we check that there are minimum 1 item completed
                                             // Checking in the database.
                                             $sql = 'SELECT exe_result, exe_weighting
                                                     FROM '.Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES).'
                                                     WHERE
+                                                        c_id = '.$course_id.' AND 
                                                         exe_exo_id = '.$items[$refs_list[$prereqs_string]]->path.' AND
                                                         exe_user_id = '.$user_id.' AND
                                                         orig_lp_id = '.$this->lp_id.' AND
@@ -2560,7 +2562,9 @@ class learnpathItem
                                                             $returnstatus = false;
                                                         }
                                                     } else {
-                                                        if ($quiz['exe_result'] >= $items[$refs_list[$prereqs_string]]->get_mastery_score()) {
+                                                        if ($quiz['exe_result'] >=
+                                                            $items[$refs_list[$prereqs_string]]->get_mastery_score()
+                                                        ) {
                                                             $returnstatus = true;
                                                             break;
                                                         } else {

+ 2 - 5
main/lp/lp_add_item.php

@@ -159,15 +159,12 @@ function confirmation(name) {
     }
 }
 
-jQuery(document).ready(function(){
+$(document).ready(function() {
     jQuery('.scrollbar-inner').scrollbar();
 
     $('#subtab ').on('click', 'a:first', function() {
         window.location.reload();
     });
-});
-
-$(document).ready(function() {
     expandColumnToogle('#hide_bar_template', {
         selector: '#lp_sidebar'
     }, {
@@ -195,7 +192,7 @@ $(document).ready(function() {
 });
 
 // document template for new document tab handler
-$(document).on( 'shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
+$(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
     var id = e.target.id;
     if (id == 'subtab2') {
         $('#frmModel').show();

+ 17 - 19
main/lp/lp_ajax_save_item.php

@@ -137,14 +137,12 @@ function save_item(
         // set_score function used to save the status, but this is not the case anymore
         if (isset($score) && $score != -1) {
             if ($debug > 1) {
-                error_log('Calling set_score('.$score.')', 0);
-                error_log('set_score changes the status to failed/passed if mastery score is provided', 0);
+                error_log('Calling set_score('.$score.')');
+                error_log('set_score changes the status to failed/passed if mastery score is provided');
             }
-
             $myLPI->set_score($score);
-
             if ($debug > 1) {
-                error_log('Done calling set_score '.$myLPI->get_score(), 0);
+                error_log('Done calling set_score '.$myLPI->get_score());
             }
         } else {
             if ($debug > 1) {
@@ -156,13 +154,13 @@ function save_item(
         // Default behaviour.
         if (isset($status) && $status != '' && $status != 'undefined') {
             if ($debug > 1) {
-                error_log('Calling set_status('.$status.')', 0);
+                error_log('Calling set_status('.$status.')');
             }
 
             $myLPI->set_status($status);
             $statusIsSet = true;
             if ($debug > 1) {
-                error_log('Done calling set_status: checking from memory: '.$myLPI->get_status(false), 0);
+                error_log('Done calling set_status: checking from memory: '.$myLPI->get_status(false));
             }
         } else {
             if ($debug > 1) {
@@ -177,23 +175,23 @@ function save_item(
                 if (($score / $max) > 0.8) {
                     $myStatus = 'completed';
                     if ($debug > 1) {
-                        error_log('Calling set_status('.$myStatus.') for hotpotatoes', 0);
+                        error_log('Calling set_status('.$myStatus.') for hotpotatoes');
                     }
                     $myLPI->set_status($myStatus);
                     $statusIsSet = true;
                     if ($debug > 1) {
-                        error_log('Done calling set_status for hotpotatoes - now '.$myLPI->get_status(false), 0);
+                        error_log('Done calling set_status for hotpotatoes - now '.$myLPI->get_status(false));
                     }
                 }
             } elseif ($status == 'completed' && $max > 0 && ($score / $max) < 0.8) {
                 $myStatus = 'failed';
                 if ($debug > 1) {
-                    error_log('Calling set_status('.$myStatus.') for hotpotatoes', 0);
+                    error_log('Calling set_status('.$myStatus.') for hotpotatoes');
                 }
                 $myLPI->set_status($myStatus);
                 $statusIsSet = true;
                 if ($debug > 1) {
-                    error_log('Done calling set_status for hotpotatoes - now '.$myLPI->get_status(false), 0);
+                    error_log('Done calling set_status for hotpotatoes - now '.$myLPI->get_status(false));
                 }
             }
         } elseif ($my_type == 'sco') {
@@ -334,13 +332,13 @@ function save_item(
             // Default behaviour
             if (isset($status) && $status != '' && $status != 'undefined') {
                 if ($debug > 1) {
-                    error_log('Calling set_status('.$status.')', 0);
+                    error_log('Calling set_status('.$status.')');
                 }
 
                 $myLPI->set_status($status);
 
                 if ($debug > 1) {
-                    error_log('Done calling set_status: checking from memory: '.$myLPI->get_status(false), 0);
+                    error_log('Done calling set_status: checking from memory: '.$myLPI->get_status(false));
                 }
             } else {
                 if ($debug > 1) {
@@ -352,7 +350,7 @@ function save_item(
         if (isset($time) && $time != '' && $time != 'undefined') {
             // If big integer, then it's a timestamp, otherwise it's normal scorm time.
             if ($debug > 1) {
-                error_log('Calling set_time('.$time.') ', 0);
+                error_log('Calling set_time('.$time.') ');
             }
             if ($time == intval(strval($time)) && $time > 1000000) {
                 if ($debug > 1) {
@@ -360,7 +358,7 @@ function save_item(
                 }
                 $real_time = time() - $time;
                 if ($debug > 1) {
-                    error_log('Calling $real_time '.$real_time.' ', 0);
+                    error_log('Calling $real_time '.$real_time.' ');
                 }
                 $myLPI->set_time($real_time, 'int');
             } else {
@@ -368,7 +366,7 @@ function save_item(
                     error_log("Time is in SCORM format");
                 }
                 if ($debug > 1) {
-                    error_log('Calling $time '.$time.' ', 0);
+                    error_log('Calling $time '.$time.' ');
                 }
                 $myLPI->set_time($time, 'scorm');
             }
@@ -427,9 +425,9 @@ function save_item(
     $myProgressMode = $myProgressMode == '' ? '%' : $myProgressMode;
 
     if ($debug > 1) {
-        error_log("mystatus: $myStatus", 0);
-        error_log("myprogress_mode: $myProgressMode", 0);
-        error_log("progress: $myComplete / $myTotal", 0);
+        error_log("mystatus: $myStatus");
+        error_log("myprogress_mode: $myProgressMode");
+        error_log("progress: $myComplete / $myTotal");
     }
 
     if ($myLPI->get_type() != 'sco') {

+ 1 - 1
main/lp/lp_ajax_switch_item.php

@@ -190,7 +190,7 @@ function switch_item_details($lp_id, $user_id, $view_id, $current_item, $next_it
     $mycredit = $mylpi->get_credit();
     $mylaunch_data = $mylpi->get_launch_data();
     $myinteractions_count = $mylpi->get_interactions_count();
-    $myobjectives_count = $mylpi->get_objectives_count();
+    //$myobjectives_count = $mylpi->get_objectives_count();
     $mycore_exit = $mylpi->get_core_exit();
 
     $return .=

+ 0 - 2
main/lp/lp_build.php

@@ -125,6 +125,4 @@ function show_block($link, $title, $subtitle, $icon)
     return $html;
 }
 
-/* FOOTER */
-
 Display::display_footer();

+ 12 - 21
main/lp/lp_controller.php

@@ -50,7 +50,7 @@ $(window).on("load", function () {
     setFocus();
 });
 </script>';
-$ajax_url = api_get_path(WEB_AJAX_PATH).'lp.ajax.php';
+$ajax_url = api_get_path(WEB_AJAX_PATH).'lp.ajax.php?'.api_get_cidreq();
 $htmlHeadXtra[] = '
 <script>
     /*
@@ -112,14 +112,13 @@ $htmlHeadXtra[] = '
         return in_parent_integer_id;
     }
 
-    $(function() {
+    $(function() {        
         $(".lp_resource").sortable({
             items: ".lp_resource_element ",
             handle: ".moved", //only the class "moved"
             cursor: "move",
             connectWith: "#lp_item_list",
             placeholder: "ui-state-highlight", //defines the yellow highlight
-
             start: function(event, ui) {
                 $(ui.item).css("width", "160px");
                 $(ui.item).find(".item_data").attr("style", "");
@@ -137,11 +136,10 @@ $htmlHeadXtra[] = '
             update: function(event, ui) {
                 buildLPtree($("#lp_item_list"), 0);
                 var order = "new_order="+ newOrderData + "&a=update_lp_item_order";
-
                 $.post(
                     "'.$ajax_url.'",
                     order,
-                    function(reponse){
+                    function(reponse) {
                         $("#message").html(reponse);
                         order = "";
                         newOrderData = "";
@@ -168,27 +166,19 @@ $htmlHeadXtra[] = '
                             "type": type,
                             "title" : title
                         };
+                        
                         $.ajax({
                             type: "GET",
                             url: "'.$ajax_url.'",
                             data: params,
                             async: false,
                             success: function(data) {
-                                if (data == -1) {
-                                } else {
-                                    $(".normal-message").hide();
-                                    $(ui.item).attr("id", data);
-                                    $(ui.item).addClass("lp_resource_element_new");
-                                    $(ui.item).find(".item_data").attr("style", "");
-                                    $(ui.item).addClass("record li_container");
-                                    $(ui.item).removeClass("lp_resource_element");
-                                    $(ui.item).removeClass("doc_resource");
-                                }
+                                $("#lp_item_list").html(data);
                             }
-                        });
+                        });                        
                     }
-                }//
-            }//end receive
+                }
+            } // End receive
         });
         processReceive = false;
     });
@@ -883,9 +873,7 @@ switch ($action) {
         } else {
             Session::write('refresh', 1);
             $_SESSION['oLP']->delete(null, $_GET['lp_id'], 'remove');
-
             Skill::deleteSkillsFromItem($_GET['lp_id'], ITEM_TYPE_LEARNPATH);
-
             Display::addFlash(Display::return_message(get_lang('Deleted')));
             Session::erase('oLP');
             require 'lp_list.php';
@@ -897,7 +885,7 @@ switch ($action) {
         }
 
         learnpath::toggleCategoryVisibility($_REQUEST['id'], $_REQUEST['new_status']);
-
+        Display::addFlash(Display::return_message(get_lang('Updated')));
         header('Location: '.api_get_self().'?'.api_get_cidreq());
         exit;
     case 'toggle_visible':
@@ -910,6 +898,7 @@ switch ($action) {
             require 'lp_list.php';
         } else {
             learnpath::toggle_visibility($_REQUEST['lp_id'], $_REQUEST['new_status']);
+            Display::addFlash(Display::return_message(get_lang('Updated')));
             require 'lp_list.php';
         }
         break;
@@ -919,6 +908,7 @@ switch ($action) {
         }
 
         learnpath::toggleCategoryPublish($_REQUEST['id'], $_REQUEST['new_status']);
+        Display::addFlash(Display::return_message(get_lang('Updated')));
         require 'lp_list.php';
         break;
     case 'toggle_publish':
@@ -930,6 +920,7 @@ switch ($action) {
             require 'lp_list.php';
         } else {
             learnpath::toggle_publish($_REQUEST['lp_id'], $_REQUEST['new_status']);
+            Display::addFlash(Display::return_message(get_lang('Updated')));
             require 'lp_list.php';
         }
         break;

+ 1 - 2
main/lp/lp_edit.php

@@ -82,13 +82,13 @@ $hide_toc_frame = $form->addElement(
     null,
     get_lang('HideTocFrame')
 );
+
 if (api_get_setting('allow_course_theme') === 'true') {
     $mycourselptheme = api_get_course_setting('allow_learning_path_theme');
     if (!empty($mycourselptheme) && $mycourselptheme != -1 && $mycourselptheme == 1) {
         //LP theme picker
         $theme_select = $form->addElement('SelectTheme', 'lp_theme', get_lang('Theme'));
         $form->applyFilter('lp_theme', 'trim');
-
         $s_theme = $learnPath->get_theme();
         $theme_select->setSelected($s_theme); //default
     }
@@ -113,7 +113,6 @@ if (strlen($learnPath->get_preview_image()) > 0) {
 }
 $label = ($learnPath->get_preview_image() != '' ? get_lang('UpdateImage') : get_lang('AddImage'));
 $form->addElement('file', 'lp_preview_image', [$label, get_lang('ImageWillResizeMsg')]);
-
 $form->addRule('lp_preview_image', get_lang('OnlyImagesAllowed'), 'filetype', ['jpg', 'jpeg', 'png', 'gif']);
 
 // Search terms (only if search is activated).

+ 2 - 7
main/lp/lp_edit_item.php

@@ -58,7 +58,6 @@ $(document).on("ready", function() {
 </script>';
 
 /* Constants and variables */
-
 $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
 $tbl_lp = Database::get_course_table(TABLE_LP_MAIN);
 
@@ -66,9 +65,7 @@ $isStudentView = isset($_REQUEST['isStudentView']) ? intval($_REQUEST['isStudent
 $learnpath_id = (int) $_REQUEST['lp_id'];
 $submit = isset($_POST['submit_button']) ? $_POST['submit_button'] : null;
 
-/* MAIN CODE */
-
-if ((!$is_allowed_to_edit) || ($isStudentView)) {
+if (!$is_allowed_to_edit || $isStudentView) {
     error_log('New LP - User not authorized in lp_edit_item.php');
     header('location:lp_controller.php?action=view&lp_id='.$learnpath_id);
     exit;
@@ -127,11 +124,9 @@ function confirmation(name) {
         return false;
     }
 }
-jQuery(document).ready(function(){
-    jQuery('.scrollbar-inner').scrollbar();
-});
 
 $(document).ready(function() {
+    jQuery('.scrollbar-inner').scrollbar();
     expandColumnToogle('#hide_bar_template', {
         selector: '#lp_sidebar'
     }, {

+ 18 - 3
main/messages/new_message.php

@@ -186,6 +186,11 @@ function manageForm($default, $select_from_user_list = null, $sent_to = '')
     if (isset($_GET['forward_id'])) {
         $forwardId = (int) $_GET['forward_id'];
         $message_reply_info = MessageManager::get_message_by_id($forwardId);
+        $attachments = MessageManager::getAttachmentLinkList($forwardId);
+        if (!empty($attachments)) {
+            $fileListToString = !empty($attachments) ? implode('<br />', $attachments) : '';
+            $form->addLabel('', $fileListToString);
+        }
         $default['title'] = '['.get_lang('MailSubjectForwardShort').": ".$message_reply_info['title'].']';
         $form->addHidden('forward_id', $forwardId);
         $form->addHidden('save_form', 'save_form');
@@ -222,7 +227,12 @@ function manageForm($default, $select_from_user_list = null, $sent_to = '')
 
         $form->addLabel(
             '',
-            '<span id="link-more-attach"><a href="javascript://" onclick="return add_image_form()">'.get_lang('AddOneMoreFile').'</a></span>&nbsp;('.sprintf(get_lang('MaximunFileSizeX'), format_file_size(api_get_setting('message_max_upload_filesize'))).')'
+            '<span id="link-more-attach"><a href="javascript://" onclick="return add_image_form()">'.
+            get_lang('AddOneMoreFile').'</a></span>&nbsp;('.
+            sprintf(
+                get_lang('MaximunFileSizeX'),
+                format_file_size(api_get_setting('message_max_upload_filesize'))
+            ).')'
         );
     }
 
@@ -237,6 +247,11 @@ function manageForm($default, $select_from_user_list = null, $sent_to = '')
     $html = '';
     if ($form->validate()) {
         $check = Security::check_token('post');
+        $disabled = api_get_configuration_value('disable_token_in_new_message');
+        if ($disabled) {
+            $check = true;
+        }
+
         if ($check) {
             $user_list = $default['users'];
             $file_comments = $_POST['legend'];
@@ -263,6 +278,7 @@ function manageForm($default, $select_from_user_list = null, $sent_to = '')
                         false,
                         $forwardId
                     );
+
                     if ($res) {
                         $userInfo = api_get_user_info($userId);
                         Display::addFlash(Display::return_message(
@@ -289,7 +305,6 @@ function manageForm($default, $select_from_user_list = null, $sent_to = '')
     return $html;
 }
 
-/* MAIN SECTION */
 if ($allowSocial) {
     $this_section = SECTION_SOCIAL;
     $interbreadcrumb[] = [
@@ -309,7 +324,7 @@ $interbreadcrumb[] = [
     'name' => get_lang('Messages'),
 ];
 
-$group_id = isset($_REQUEST['group_id']) ? intval($_REQUEST['group_id']) : null;
+$group_id = isset($_REQUEST['group_id']) ? (int) $_REQUEST['group_id'] : 0;
 $social_right_content = null;
 if ($group_id != 0) {
     $social_right_content .= '<div class=actions>';

+ 1 - 1
main/mySpace/myStudents.php

@@ -1701,7 +1701,7 @@ if ($allowMessages === true) {
 }
 
 $allow = api_get_configuration_value('allow_user_message_tracking');
-if ($allow && api_is_drh() || api_is_platform_admin()) {
+if ($allow && (api_is_drh() || api_is_platform_admin())) {
     $users = MessageManager::getUsersThatHadConversationWithUser($student_id);
 
     echo Display::page_subheader2(get_lang('MessageTracking'));

+ 0 - 14
main/portfolio/share.php

@@ -1,14 +0,0 @@
-<?php
-
-/**
- * @license see /license.txt
- * @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva
- */
-require_once __DIR__.'/../inc/global.inc.php';
-
-$has_access = api_protect_course_script();
-if (!$has_access) {
-    exit;
-}
-
-Portfolio::controller()->run();

+ 1 - 1
main/session/about.php

@@ -233,6 +233,6 @@ $template->assign('sequences', $sessionRequirements);
 $template->assign('is_premiun', $sessionIsPremium);
 $layout = $template->get_template('session/about.tpl');
 $content = $template->fetch($layout);
-$template->assign('header', $session->getName());
+//$template->assign('header', $session->getName());
 $template->assign('content', $content);
 $template->display_one_col_template();

+ 2 - 2
main/session/add_users_to_session.php

@@ -269,7 +269,7 @@ function search_users($needle, $type)
 $xajax->processRequests();
 $htmlHeadXtra[] = $xajax->getJavascript('../inc/lib/xajax/');
 $htmlHeadXtra[] = '
-<script type="text/javascript">
+<script>
 function add_user_to_session (code, content) {
 	document.getElementById("user_to_add").value = "";
 	document.getElementById("ajax_list_users_single").innerHTML = "";
@@ -330,7 +330,7 @@ if (isset($_POST['form_sent']) && $_POST['form_sent']) {
         $notEmptyList = api_get_configuration_value('session_multiple_subscription_students_list_avoid_emptying');
 
         // Added a parameter to send emails when registering a user
-        SessionManager::subscribe_users_to_session(
+        SessionManager::subscribeUsersToSession(
             $id_session,
             $UserList,
             null,

+ 1 - 1
main/session/resume_session.php

@@ -265,7 +265,7 @@ if (!empty($userList)) {
     );
     $table->setHeaderContents(0, 0, get_lang('User'));
     $table->setHeaderContents(0, 1, get_lang('Status'));
-    $table->setHeaderContents(0, 2, get_lang('Registered'));
+    $table->setHeaderContents(0, 2, get_lang('RegistrationDate'));
     $table->setHeaderContents(0, 3, get_lang('Actions'));
 
     $row = 1;

+ 1 - 1
main/session/session_user_import.php

@@ -43,7 +43,7 @@ if (isset($_POST['formSent']) && $_POST['formSent']) {
         }
 
         if (!empty($user_list)) {
-            SessionManager::subscribe_users_to_session(
+            SessionManager::subscribeUsersToSession(
                 $session_id,
                 $user_list,
                 null,

+ 10 - 2
main/social/my_skills_report.php

@@ -86,8 +86,16 @@ if ($isStudent) {
             $imageSysPath = sprintf("%s%s/course-pic.png", api_get_path(SYS_COURSE_PATH), $resultData['directory']);
 
             if (file_exists($imageSysPath)) {
-                $thumbSysPath = sprintf("%s%s/course-pic32.png", api_get_path(SYS_COURSE_PATH), $resultData['directory']);
-                $thumbWebPath = sprintf("%s%s/course-pic32.png", api_get_path(WEB_COURSE_PATH), $resultData['directory']);
+                $thumbSysPath = sprintf(
+                    "%s%s/course-pic32.png",
+                    api_get_path(SYS_COURSE_PATH),
+                    $resultData['directory']
+                );
+                $thumbWebPath = sprintf(
+                    "%s%s/course-pic32.png",
+                    api_get_path(WEB_COURSE_PATH),
+                    $resultData['directory']
+                );
 
                 if (!file_exists($thumbSysPath)) {
                     $courseImageThumb = new Image($imageSysPath);

+ 21 - 35
main/survey/fillsurvey.php

@@ -504,7 +504,8 @@ if ($survey_data['form_fields'] != '' &&
     $returnParams = $extraField->addElements($form, api_get_user_id());
     $jquery_ready_content = $returnParams['jquery_ready_content'];
 
-    // the $jquery_ready_content variable collects all functions that will be load in the $(document).ready javascript function
+    // the $jquery_ready_content variable collects all functions
+    // that will be load in the $(document).ready javascript function
     $htmlHeadXtra[] = '<script>
     $(document).ready(function(){
         '.$jquery_ready_content.'
@@ -691,10 +692,10 @@ if (isset($_GET['show']) || isset($_POST['personality'])) {
                             survey_question_option.sort as option_sort
                         FROM $table_survey_question survey_question
                         LEFT JOIN $table_survey_question_option survey_question_option
-                            ON survey_question.question_id = survey_question_option.question_id AND
-                            survey_question_option.c_id = $course_id
+                        ON survey_question.question_id = survey_question_option.question_id AND
+                        survey_question_option.c_id = $course_id
                         WHERE
-                            survey_question.survey_id = '".Database :: escape_string($survey_invitation['survey_id'])."' AND
+                            survey_question.survey_id = '".Database::escape_string($survey_invitation['survey_id'])."' AND
                             survey_question.question_id NOT IN (
                                 SELECT sa.question_id
                                 FROM ".$table_survey_answer." sa
@@ -764,9 +765,7 @@ if (isset($_GET['show']) || isset($_POST['personality'])) {
             } else {
                 $order = $shuffle;
             }
-
             $answer_list = [];
-
             // Get current user results
             $results = [];
             $sql = "SELECT survey_group_pri, user, SUM(value) as value
@@ -809,7 +808,6 @@ if (isset($_GET['show']) || isset($_POST['personality'])) {
                             survey_group_sec2='0'
                         GROUP BY survey_group_pri, survey_question.question_id
                     ) as temp
-
                     GROUP BY temp.survey_group_pri
                     ORDER BY temp.survey_group_pri";
 
@@ -869,7 +867,6 @@ if (isset($_GET['show']) || isset($_POST['personality'])) {
              */
 
             // i.e 70% - 70% -70% 70%  $equal_count =3
-
             $i = 0;
             $group_cant = 0;
             $equal_count = 0;
@@ -898,18 +895,19 @@ if (isset($_GET['show']) || isset($_POST['personality'])) {
                         ($result[2]['value'] == $result[3]['value'])
                     ) {
                         $group_cant = 1;
-                    }
-                    // i.e 70% - 70% -0% - 0%     -    $equal_count = 0 we only get the first 2 options
-                    /* elseif (($result[0]['value'] == $result[1]['value']) && ($result[1]['value'] != $result[2]['value'])) {
-                      $group_cant = 0;
-                      } */
-                    /*
-                      // i.e 70% - 70% -60% - 60%  $equal_count = 0 we only get the first 2 options
-                      elseif (($result[0]['value'] == $result[1]['value'])  &&  ($result[2]['value'] == $result[3]['value'])) {
-                      $group_cant = 0;
-                      } */
-                    // i.e. 80% - 70% - 70% - 70%
-                    elseif (($result[0]['value'] != $result[1]['value']) && ($result[1]['value'] == $result[2]['value']) && ($result[2]['value'] == $result[3]['value'])) {
+                    } elseif (($result[0]['value'] != $result[1]['value']) &&
+                        ($result[1]['value'] == $result[2]['value']) && ($result[2]['value'] == $result[3]['value'])
+                    ) {
+                        // i.e 70% - 70% -0% - 0%     -    $equal_count = 0 we only get the first 2 options
+                        /* elseif (($result[0]['value'] == $result[1]['value']) && ($result[1]['value'] != $result[2]['value'])) {
+                          $group_cant = 0;
+                          } */
+                        /*
+                          // i.e 70% - 70% -60% - 60%  $equal_count = 0 we only get the first 2 options
+                          elseif (($result[0]['value'] == $result[1]['value'])  &&  ($result[2]['value'] == $result[3]['value'])) {
+                          $group_cant = 0;
+                          } */
+                        // i.e. 80% - 70% - 70% - 70%
                         $group_cant = 0;
                     } else {
                         // i.e. 80% - 70% - 70% - 50
@@ -986,12 +984,7 @@ if (isset($_GET['show']) || isset($_POST['personality'])) {
                     if ($shuffle == '') {
                         $shuffle = ' BY survey_question.sort, survey_question_option.sort ASC ';
                     }
-
-                    //$val = 0;
-                    //if ($survey_data['one_question_per_page'] == 0) {
                     $val = (int) $_POST['personality'];
-                    //}
-                    //echo '<pre>'; print_r($paged_questions_sec); echo '</pre>';
                     if (is_array($paged_questions_sec)) {
                         $sql = "SELECT
                                     survey_question.survey_group_sec1,
@@ -1095,15 +1088,10 @@ if (isset($_GET['show']) || isset($_POST['personality'])) {
             if ($shuffle == '') {
                 $order_sql = ' BY survey_question.sort, survey_question_option.sort ASC ';
             }
-
-            //$val = 0;
-            //if ($survey_data['one_question_per_page'] == 0) {
             $val = $_GET['show'];
-            //}
-
             $result = null;
             if ($val != '') {
-                $imploded = implode(',', $paged_questions[$val]);
+                $imploded = Database::escape_string(implode(',', $paged_questions[$val]));
                 if ($imploded != '') {
                     // The answers are always in the same order NO shuffle
                     $order_sql = ' BY survey_question.sort, survey_question_option.sort ASC ';
@@ -1135,6 +1123,7 @@ if (isset($_GET['show']) || isset($_POST['personality'])) {
                     $question_counter_max = Database :: num_rows($result);
                 }
             }
+
             if (!is_null($result)) {
                 $counter = 0;
                 $limit = 0;
@@ -1172,11 +1161,10 @@ if (isset($_GET['show']) || isset($_POST['personality'])) {
 $sql = "SELECT * FROM $table_survey_question
         WHERE
             c_id = $course_id AND
-            type='".Database::escape_string('pagebreak')."' AND
+            type = '".Database::escape_string('pagebreak')."' AND
             survey_id='".intval($survey_invitation['survey_id'])."'";
 $result = Database::query($sql);
 $numberofpages = Database::num_rows($result) + 1;
-
 // Displaying the form with the questions
 if (isset($_GET['show'])) {
     $show = (int) $_GET['show'] + 1;
@@ -1196,9 +1184,7 @@ $g_c = isset($_GET['course']) ? Security::remove_XSS($_GET['course']) : '';
 $g_ic = isset($_GET['invitationcode']) ? Security::remove_XSS($_GET['invitationcode']) : '';
 $g_cr = isset($_GET['cidReq']) ? Security::remove_XSS($_GET['cidReq']) : '';
 $p_l = isset($_POST['language']) ? Security::remove_XSS($_POST['language']) : '';
-
 $add_parameters = isset($_GET['user_id']) ? '&user_id='.intval($_GET['user_id']) : '';
-
 $url = api_get_self().'?cidReq='.$courseInfo['code'].
     '&id_session='.$sessionId.
     $add_parameters.

+ 10 - 11
main/tracking/courseLog.php

@@ -97,10 +97,10 @@ $csv_content = [];
 // Scripts for reporting array hide/show columns
 $js = "<script>
     // hide column and display the button to unhide it
-    function foldup(in_id) {
-        $('#reporting_table .data_table tr td:nth-child(' + (in_id + 1) + ')').toggleClass('hide');
-        $('#reporting_table .data_table tr th:nth-child(' + (in_id + 1) + ')').toggleClass('hide');
-        $('div#unhideButtons a:nth-child(' + (in_id + 1) + ')').toggleClass('hide');
+    function foldup(id) {
+        $('#reporting_table .data_table tr td:nth-child(' + (id + 1) + ')').toggleClass('hide');
+        $('#reporting_table .data_table tr th:nth-child(' + (id + 1) + ')').toggleClass('hide');
+        $('div#unhideButtons a:nth-child(' + (id + 1) + ')').toggleClass('hide');
     }
 
     // add the red cross on top of each column
@@ -341,7 +341,7 @@ if ($showReporting) {
 $html .= Display::page_subheader2(get_lang('StudentList'));
 
 // PERSON_NAME_DATA_EXPORT is buggy
-$is_western_name_order = api_is_western_name_order();
+$sortByFirstName = api_sort_by_first_name();
 
 if (count($a_students) > 0) {
     $getLangXDays = get_lang('XDays');
@@ -400,7 +400,7 @@ if (count($a_students) > 0) {
         'users_tracking',
         ['TrackingCourseLog', 'get_number_of_users'],
         ['TrackingCourseLog', 'get_user_data'],
-        (api_is_western_name_order() xor api_sort_by_first_name()) ? 3 : 2
+        1
     );
 
     $parameters['cidReq'] = isset($_GET['cidReq']) ? Security::remove_XSS($_GET['cidReq']) : '';
@@ -412,15 +412,15 @@ if (count($a_students) > 0) {
     // tab of header texts
     $table->set_header(0, get_lang('OfficialCode'), true);
     $headers['official_code'] = get_lang('OfficialCode');
-    if ($is_western_name_order) {
+    if ($sortByFirstName) {
         $table->set_header(1, get_lang('FirstName'), true);
-        $headers['firstname'] = get_lang('FirstName');
         $table->set_header(2, get_lang('LastName'), true);
+        $headers['firstname'] = get_lang('FirstName');
         $headers['lastname'] = get_lang('LastName');
     } else {
         $table->set_header(1, get_lang('LastName'), true);
-        $headers['lastname'] = get_lang('LastName');
         $table->set_header(2, get_lang('FirstName'), true);
+        $headers['lastname'] = get_lang('LastName');
         $headers['firstname'] = get_lang('FirstName');
     }
     $table->set_header(3, get_lang('Login'), false);
@@ -504,7 +504,6 @@ if (count($a_students) > 0) {
                 'onclick' => "foldup($index); return false;",
             ]
         );
-
         $index++;
     }
     $html .= "</div>";
@@ -522,7 +521,7 @@ echo Display::panel($html, $titleSession);
 if ($export_csv) {
     $csv_headers = [];
     $csv_headers[] = get_lang('OfficialCode');
-    if ($is_western_name_order) {
+    if ($sortByFirstName) {
         $csv_headers[] = get_lang('FirstName');
         $csv_headers[] = get_lang('LastName');
     } else {

+ 1 - 1
main/user/add_users_to_session.php

@@ -275,7 +275,7 @@ if ($allowTutors == 'true') {
 
         if ($form_sent == 1) {
             //added a parameter to send emails when registering a user
-            SessionManager::subscribe_users_to_session($id_session, $UserList, null, true);
+            SessionManager::subscribeUsersToSession($id_session, $UserList, null, true);
             header('Location: resume_session.php?id_session='.$id_session);
             exit;
         }

+ 8 - 0
main/user/user.php

@@ -1026,6 +1026,14 @@ function modify_filter($user_id, $row, $data)
                 $disabled = '';
             }
 
+            $allow = api_get_configuration_value('extra');
+            if ($allow) {
+                $result .= '<a href="'.
+                    api_get_path(WEB_CODE_PATH).'extra/userInfo.php?'.api_get_cidreq().'&editMainUserInfo='.$user_id.'" title="'.get_lang('Edit').'" >'.
+                    Display::return_icon('edit.png', get_lang('Edit'), '', ICON_SIZE_SMALL).
+                    '</a>&nbsp;';
+            }
+
             if ($data['user_status_in_course'] == STUDENT) {
                 $result .= Display::url(
                     $text,

+ 1 - 1
main/webservices/http-auth.php

@@ -40,8 +40,8 @@ function getDigest()
 {
     // mod_php
     if (isset($_SERVER['PHP_AUTH_DIGEST'])) {
-        // most other servers
         $digest = $_SERVER['PHP_AUTH_DIGEST'];
+    // most other servers
     } elseif (isset($_SERVER['HTTP_AUTHENTICATION'])) {
         if (strpos(
                 strtolower($_SERVER['HTTP_AUTHENTICATION']),

+ 3 - 3
main/webservices/registration.soap.php

@@ -899,7 +899,7 @@ function WSCreateUsersPasswordCrypted($params)
                         $extra_field_name = $extra['field_name'];
                         $extra_field_value = $extra['field_value'];
                         // Save the external system's id into user_field_value table.
-                        $res = UserManager::update_extra_field_value(
+                        UserManager::update_extra_field_value(
                             $r_check_user[0],
                             $extra_field_name,
                             $extra_field_value
@@ -5364,7 +5364,7 @@ function WSSuscribeUsersToSession($params)
                     continue; // user_id is not active.
                 }
 
-                SessionManager::subscribe_users_to_session(
+                SessionManager::subscribeUsersToSession(
                     $sessionId,
                     [$user_id],
                     SESSION_VISIBLE_READ_ONLY,
@@ -5461,7 +5461,7 @@ function WSSubscribeUserToSessionSimple($params)
                 error_log($result);
             }
         } else {
-            SessionManager::subscribe_users_to_session(
+            SessionManager::subscribeUsersToSession(
                 $session_id,
                 [$user_id],
                 SESSION_VISIBLE_READ_ONLY,

+ 1 - 1
main/webservices/webservice_session.php

@@ -616,7 +616,7 @@ class WSSession extends WS
                 return $user_id;
             } else {
                 if ($state == 1) {
-                    SessionManager::subscribe_users_to_session(
+                    SessionManager::subscribeUsersToSession(
                         $session_id,
                         [$user_id]
                     );