Procházet zdrojové kódy

Minor - update from 1.11.x

Julio Montoya před 6 roky
rodič
revize
2ffb1a0c05
52 změnil soubory, kde provedl 1097 přidání a 1293 odebrání
  1. 10 9
      main/announcements/announcements.php
  2. 1 109
      main/course_home/activity.php
  3. 9 9
      main/course_progress/thematic.php
  4. 6 9
      main/coursecopy/import_moodle.php
  5. 3 7
      main/exercise/TestCategory.php
  6. 2 2
      main/exercise/exercise.class.php
  7. 35 38
      main/exercise/question_pool.php
  8. 1 0
      main/gradebook/lib/fe/gradebooktable.class.php
  9. 5 5
      main/group/group_space.php
  10. 3 3
      main/inc/ajax/agenda.ajax.php
  11. 6 4
      main/inc/ajax/lp.ajax.php
  12. 0 2
      main/inc/ajax/statistics.ajax.php
  13. 12 10
      main/inc/lib/AnnouncementManager.php
  14. 466 418
      main/inc/lib/MoodleImport.php
  15. 1 2
      main/inc/lib/agenda.lib.php
  16. 4 3
      main/inc/lib/attendance.lib.php
  17. 11 11
      main/inc/lib/course.lib.php
  18. 247 222
      main/inc/lib/course_home.lib.php
  19. 1 0
      main/inc/lib/document.lib.php
  20. 1 1
      main/inc/lib/exercise.lib.php
  21. 0 86
      main/inc/lib/formvalidator/FormValidator.class.php
  22. 16 8
      main/inc/lib/groupmanager.lib.php
  23. 3 13
      main/inc/lib/pear/HTML/Common.php
  24. 3 3
      main/inc/lib/pear/HTML/QuickForm.php
  25. 0 1
      main/inc/lib/pear/HTML/QuickForm/Renderer.php
  26. 4 3
      main/inc/lib/pear/HTML/QuickForm/checkbox.php
  27. 34 59
      main/inc/lib/pear/HTML/QuickForm/element.php
  28. 1 2
      main/inc/lib/pear/HTML/QuickForm/file.php
  29. 0 25
      main/inc/lib/pear/HTML/QuickForm/input.php
  30. 0 10
      main/inc/lib/pear/HTML/QuickForm/label.php
  31. 0 4
      main/inc/lib/pear/HTML/QuickForm/link.php
  32. 0 8
      main/inc/lib/pear/HTML/QuickForm/reset.php
  33. 0 30
      main/inc/lib/pear/HTML/QuickForm/static.php
  34. 2 9
      main/inc/lib/pear/HTML/QuickForm/submit.php
  35. 3 26
      main/inc/lib/pear/HTML/QuickForm/textarea.php
  36. 4 1
      main/inc/lib/social.lib.php
  37. 8 2
      main/inc/lib/userportal.lib.php
  38. 15 6
      main/inc/lib/zombie/zombie_manager.class.php
  39. 42 72
      main/inc/lib/zombie/zombie_report.class.php
  40. 78 38
      main/install/install.lib.php
  41. 12 7
      main/lp/learnpath.class.php
  42. 24 4
      main/lp/learnpathItem.class.php
  43. 0 1
      main/lp/lp_add_item.php
  44. 2 0
      main/lp/scorm_api.php
  45. 0 1
      main/messages/inbox.php
  46. 5 1
      main/mySpace/exercise_category_report.php
  47. 1 1
      main/mySpace/lp_tracking.php
  48. 0 1
      main/social/personal_data.php
  49. 1 1
      main/survey/create_meeting.php
  50. 0 1
      main/survey/reporting.php
  51. 7 2
      main/survey/surveyUtil.class.php
  52. 8 3
      main/work/add_document.php

+ 10 - 9
main/announcements/announcements.php

@@ -41,7 +41,6 @@ $allowToEdit = (
 
 $sessionId = api_get_session_id();
 $drhHasAccessToSessionContent = api_drh_can_access_all_session_content();
-
 if (!empty($sessionId) && $drhHasAccessToSessionContent) {
     $allowToEdit = $allowToEdit || api_is_drh();
 }
@@ -66,12 +65,12 @@ $isTutor = false;
 if (!empty($group_id)) {
     $groupProperties = GroupManager:: get_group_properties($group_id);
     $interbreadcrumb[] = [
-        "url" => api_get_path(WEB_CODE_PATH)."group/group.php?".api_get_cidreq(),
-        "name" => get_lang('Groups'),
+        'url' => api_get_path(WEB_CODE_PATH)."group/group.php?".api_get_cidreq(),
+        'name' => get_lang('Groups'),
     ];
     $interbreadcrumb[] = [
-        "url" => api_get_path(WEB_CODE_PATH)."group/group_space.php?".api_get_cidreq(),
-        "name" => get_lang('GroupSpace').' '.$groupProperties['name'],
+        'url' => api_get_path(WEB_CODE_PATH)."group/group_space.php?".api_get_cidreq(),
+        'name' => get_lang('GroupSpace').' '.$groupProperties['name'],
     ];
 
     if ($allowToEdit === false) {
@@ -86,7 +85,7 @@ if (!empty($group_id)) {
 /* Tracking */
 Event::event_access_tool(TOOL_ANNOUNCEMENT);
 
-$announcement_id = isset($_GET['id']) ? intval($_GET['id']) : null;
+$announcement_id = isset($_GET['id']) ? (int) $_GET['id'] : null;
 $action = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : 'list';
 $announcement_number = AnnouncementManager::getNumberAnnouncements();
 
@@ -118,8 +117,9 @@ switch ($action) {
 
             $announcementInfo = AnnouncementManager::get_by_id($courseId, $thisAnnouncementId);
             $sql = "SELECT DISTINCT announcement.id, announcement.display_order
-                    FROM $tbl_announcement announcement,
-                    $tbl_item_property itemproperty
+                    FROM $tbl_announcement announcement 
+                    INNER JOIN $tbl_item_property itemproperty
+                    ON (announcement.c_id = itemproperty.c_id)
                     WHERE
                         announcement.c_id = $courseId AND
                         itemproperty.c_id = $courseId AND
@@ -555,7 +555,8 @@ switch ($action) {
                 if (!isset($parts[1]) || empty($parts[1])) {
                     continue;
                 }
-                $form->addHtml("
+                $form->addHtml(
+                    "
                     <script>
                         $(document).on('ready', function () {
                             $('#choose_recipients').click();

+ 1 - 109
main/course_home/activity.php

@@ -43,8 +43,6 @@ if ($enabled === 'true') {
 }
 
 //	COURSE ADMIN ONLY VIEW
-$blocks = [];
-// Start of tools for CourseAdmins (teachers/tutors)
 if ($session_id === 0 && api_is_course_admin() && api_is_allowed_to_edit(null, true)) {
     $content .= '<div class="alert alert-success" style="border:0px; margin-top: 0px;padding:0px;">
 		<div class="normal-message" id="id_normal_message" style="display:none">';
@@ -53,46 +51,7 @@ if ($session_id === 0 && api_is_course_admin() && api_is_allowed_to_edit(null, t
     $content .= '</div>
 		<div class="alert alert-success" id="id_confirmation_message" style="display:none"></div>
 	</div>';
-
     $content .= $pluginExtra;
-
-    if (api_get_setting('show_session_data') == 'true' && $session_id > 0) {
-        $content .= '
-        <div class="row">
-            <div class="col-xs-12 col-md-12">
-                <span class="viewcaption">'.get_lang('SessionData').'</span>
-                <table class="course_activity_home">'.
-                    CourseHome::show_session_data($session_id).'
-                </table>
-            </div>
-        </div>';
-    }
-
-    $my_list = CourseHome::get_tools_category(TOOL_AUTHORING);
-
-    $blocks[] = [
-        'title' => get_lang('Authoring'),
-        'class' => 'course-tools-author',
-        'content' => CourseHome::show_tools_category($my_list),
-    ];
-
-    $list1 = CourseHome::get_tools_category(TOOL_INTERACTION);
-    $list2 = CourseHome::get_tools_category(TOOL_COURSE_PLUGIN);
-    $my_list = array_merge($list1, $list2);
-
-    $blocks[] = [
-        'title' => get_lang('Interaction'),
-        'class' => 'course-tools-interaction',
-        'content' => CourseHome::show_tools_category($my_list),
-    ];
-
-    $my_list = CourseHome::get_tools_category(TOOL_ADMIN_PLATFORM);
-
-    $blocks[] = [
-        'title' => get_lang('Administration'),
-        'class' => 'course-tools-administration',
-        'content' => CourseHome::show_tools_category($my_list),
-    ];
 } elseif (api_is_coach()) {
     $content .= $pluginExtra;
     if (api_get_setting('show_session_data') === 'true' && $session_id > 0) {
@@ -103,76 +62,9 @@ if ($session_id === 0 && api_is_course_admin() && api_is_allowed_to_edit(null, t
         $content .= CourseHome::show_session_data($session_id);
         $content .= '</table></div></div>';
     }
-
-    $my_list = CourseHome::get_tools_category(TOOL_STUDENT_VIEW);
-
-    $blocks[] = [
-        'content' => CourseHome::show_tools_category($my_list),
-    ];
-
-    $sessionsCopy = api_get_setting('allow_session_course_copy_for_teachers');
-    if ($sessionsCopy === 'true') {
-        // Adding only maintenance for coaches.
-        $myList = CourseHome::get_tools_category(TOOL_ADMIN_PLATFORM);
-        $onlyMaintenanceList = [];
-
-        foreach ($myList as $item) {
-            if ($item['name'] === 'course_maintenance') {
-                $item['link'] = 'course_info/maintenance_coach.php';
-
-                $onlyMaintenanceList[] = $item;
-            }
-        }
-
-        $blocks[] = [
-            'title' => get_lang('Administration'),
-            'content' => CourseHome::show_tools_category($onlyMaintenanceList),
-        ];
-    }
-} else {
-    $tools = CourseHome::get_tools_category(TOOL_STUDENT_VIEW);
-    $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
-        api_get_user_id(),
-        api_get_course_info()
-    );
-
-    // Force user icon for DRH
-    if ($isDrhOfCourse) {
-        $addUserTool = true;
-        foreach ($tools as $tool) {
-            if ($tool['name'] === 'user') {
-                $addUserTool = false;
-                break;
-            }
-        }
-
-        if ($addUserTool) {
-            $tools[] = [
-                'c_id' => api_get_course_int_id(),
-                'name' => 'user',
-                'link' => 'user/user.php',
-                'image' => 'members.gif',
-                'visibility' => '1',
-                'admin' => '0',
-                'address' => 'squaregrey.gif',
-                'added_tool' => '0',
-                'target' => '_self',
-                'category' => 'interaction',
-                'session_id' => api_get_session_id(),
-            ];
         }
-    }
-
-    if (count($tools) > 0) {
-        $blocks[] = ['content' => CourseHome::show_tools_category($tools)];
-    }
-
-    if ($isDrhOfCourse) {
-        $drhTool = CourseHome::get_tools_category(TOOL_DRH);
-        $blocks[] = ['content' => CourseHome::show_tools_category($drhTool)];
-    }
-}
 
+$blocks = CourseHome::getUserBlocks();
 $activityView = new Template('', false, false, false, false, false, false);
 $activityView->assign('blocks', $blocks);
 

+ 9 - 9
main/course_progress/thematic.php

@@ -152,21 +152,21 @@ if ($action == 'thematic_list') {
                         ICON_SIZE_TINY
                     ),
                     'index.php?'.api_get_cidreq().'&action=thematic_copy&thematic_id='.$my_thematic_id.$params.$url_token,
-                    ['class' => 'btn btn-outline-secondary']
+                    ['class' => 'btn btn-default']
                 );
                 if (api_get_session_id() == 0) {
                     if ($thematic['display_order'] > 1) {
-                        $toolbarThematic .= ' <a class="btn btn-outline-secondary" href="'.api_get_self().'?action=moveup&'.api_get_cidreq().'&thematic_id='.$my_thematic_id.$params.$url_token.'">'.
+                        $toolbarThematic .= ' <a class="btn btn-default" href="'.api_get_self().'?action=moveup&'.api_get_cidreq().'&thematic_id='.$my_thematic_id.$params.$url_token.'">'.
                             Display::return_icon('up.png', get_lang('Up'), '', ICON_SIZE_TINY).'</a>';
                     } else {
-                        $toolbarThematic .= '<div class="btn btn-outline-secondary">'.
+                        $toolbarThematic .= '<div class="btn btn-default">'.
                             Display::return_icon('up_na.png', '&nbsp;', '', ICON_SIZE_TINY).'</div>';
                     }
                     if (isset($thematic['max_thematic_item']) && $thematic['display_order'] < $thematic['max_thematic_item']) {
-                        $toolbarThematic .= ' <a class="btn btn-outline-secondary" href="'.api_get_self().'?action=movedown&a'.api_get_cidreq().'&thematic_id='.$my_thematic_id.$params.$url_token.'">'.
+                        $toolbarThematic .= ' <a class="btn btn-default" href="'.api_get_self().'?action=movedown&a'.api_get_cidreq().'&thematic_id='.$my_thematic_id.$params.$url_token.'">'.
                             Display::return_icon('down.png', get_lang('Down'), '', ICON_SIZE_TINY).'</a>';
                     } else {
-                        $toolbarThematic .= '<div class="btn btn-outline-secondary">'.
+                        $toolbarThematic .= '<div class="btn btn-default">'.
                             Display::return_icon('down_na.png', '&nbsp;', '', ICON_SIZE_TINY).'</div>';
                     }
                 }
@@ -177,7 +177,7 @@ if ($action == 'thematic_list') {
                             'action' => 'export_single_thematic',
                             'thematic_id' => $my_thematic_id,
                         ]),
-                        ['class' => 'btn btn-outline-secondary']
+                        ['class' => 'btn btn-default']
                     );
                     $toolbarThematic .= Display::url(
                         Display::return_icon(
@@ -189,12 +189,12 @@ if ($action == 'thematic_list') {
                         api_get_self().'?'.api_get_cidreq().$url_token.'&'.http_build_query(
                             ['action' => 'export_single_documents', 'thematic_id' => $my_thematic_id]
                         ),
-                        ['class' => 'btn btn-outline-secondary']
+                        ['class' => 'btn btn-default']
                     );
-                    $toolbarThematic .= '<a class="btn btn-outline-secondary" href="index.php?'.api_get_cidreq().'&action=thematic_edit&thematic_id='
+                    $toolbarThematic .= '<a class="btn btn-default" href="index.php?'.api_get_cidreq().'&action=thematic_edit&thematic_id='
                         .$my_thematic_id.$params.$url_token.'">'
                         .Display::return_icon('edit.png', get_lang('Edit'), '', ICON_SIZE_TINY).'</a>';
-                    $toolbarThematic .= '<a class="btn btn-outline-secondary" onclick="javascript:if(!confirm(\''
+                    $toolbarThematic .= '<a class="btn btn-default" onclick="javascript:if(!confirm(\''
                         .get_lang('AreYouSureToDelete')
                         .'\')) return false;" href="index.php?'.api_get_cidreq().'&action=thematic_delete&thematic_id='
                         .$my_thematic_id.$params.$url_token.'">'

+ 6 - 9
main/coursecopy/import_moodle.php

@@ -35,21 +35,18 @@ $form->addButtonImport(get_lang('Import'));
 
 if ($form->validate()) {
     $file = $_FILES['moodle_file'];
+
     $moodleImport = new MoodleImport();
-    $responseImport = $moodleImport->import($file);
 
-    Display::cleanFlashMessages();
+    try {
+        $responseImport = $moodleImport->import($file);
 
-    if ($responseImport) {
         Display::addFlash(
-            Display::return_message(
-                get_lang('MoodleFileImportedSuccessfully'),
-                'success'
-            )
+            Display::return_message(get_lang('MoodleFileImportedSuccessfully'), 'success')
         );
-    } else {
+    } catch (Exception $exception) {
         Display::addFlash(
-            Display::return_message(get_lang('ErrorImportingFile'), 'error')
+            Display::return_message($exception->getMessage(), 'error')
         );
     }
 }

+ 3 - 7
main/exercise/TestCategory.php

@@ -305,10 +305,8 @@ class TestCategory
      *
      * @return string
      */
-    public static function getCategoryNameForQuestion(
-        $questionId,
-        $courseId = 0
-    ) {
+    public static function getCategoryNameForQuestion($questionId, $courseId = 0)
+    {
         if (empty($courseId)) {
             $courseId = api_get_course_int_id();
         }
@@ -399,9 +397,7 @@ class TestCategory
     public static function getListOfCategoriesNameForTest($exerciseId, $grouped_by_category = true)
     {
         $result = [];
-        $categories = self::getListOfCategoriesIDForTest(
-            $exerciseId
-        );
+        $categories = self::getListOfCategoriesIDForTest($exerciseId);
 
         foreach ($categories as $catInfo) {
             $categoryId = $catInfo['id'];

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

@@ -7498,9 +7498,9 @@ class Exercise
                 INNER JOIN $TBL_QUESTIONS q
                 ON (e.question_id = q.id AND e.c_id = q.c_id)
                 INNER JOIN $categoryRelTable catRel
-                ON (catRel.question_id = e.question_id)
+                ON (catRel.question_id = e.question_id AND catRel.c_id = e.c_id)
                 INNER JOIN $categoryTable cat
-                ON (cat.id = catRel.category_id)
+                ON (cat.id = catRel.category_id AND cat.c_id = e.c_id)
                 WHERE
                   e.c_id = {$this->course_id} AND
                   e.exercice_id	= ".intval($this->id);

+ 35 - 38
main/exercise/question_pool.php

@@ -432,7 +432,10 @@ if ($exerciseId > 0) {
     $from = '';
     if (isset($courseCategoryId) && $courseCategoryId > 0) {
         $from = ", $TBL_COURSE_REL_CATEGORY crc ";
-        $where .= " AND crc.c_id=$selected_course AND crc.question_id=qu.id AND crc.category_id=$courseCategoryId";
+        $where .= " AND 
+                crc.c_id = $selected_course AND 
+                crc.question_id = qu.id AND 
+                crc.category_id = $courseCategoryId";
     }
     if (isset($exerciseLevel) && $exerciseLevel != -1) {
         $where .= ' AND level='.$exerciseLevel;
@@ -466,7 +469,8 @@ if ($exerciseId > 0) {
     $level_where = '';
     $from = '';
     if (isset($courseCategoryId) && $courseCategoryId > 0) {
-        $from = " INNER JOIN  $TBL_COURSE_REL_CATEGORY crc ON crc.question_id=q.id AND crc.c_id= q.c_id ";
+        $from = " INNER JOIN $TBL_COURSE_REL_CATEGORY crc 
+                  ON crc.question_id = q.id AND crc.c_id = q.c_id ";
         $level_where .= " AND
                 crc.c_id = $selected_course AND
                 crc.category_id = $courseCategoryId";
@@ -490,7 +494,8 @@ if ($exerciseId > 0) {
                 WHERE
                     ex.c_id = '$selected_course' AND
                     ex.active = '-1'
-                    $level_where $answer_where
+                    $level_where 
+                    $answer_where
              )
              UNION
              (
@@ -501,7 +506,8 @@ if ($exerciseId > 0) {
                 WHERE
                     q.c_id = '$selected_course' AND
                     r.question_id is null
-                    $level_where $answer_where
+                    $level_where 
+                    $answer_where
              )
              UNION
              (
@@ -512,7 +518,8 @@ if ($exerciseId > 0) {
                 WHERE
                     r.c_id = '$selected_course' AND
                     (r.exercice_id = '-1' OR r.exercice_id = '0')
-                    $level_where $answer_where
+                    $level_where 
+                    $answer_where
              )";
     $result = Database::query($sql);
     while ($row = Database::fetch_array($result, 'ASSOC')) {
@@ -667,14 +674,14 @@ if ($fromExercise <= 0) {
     // NOT IN A TEST - IN THE COURSE
     if ($selected_course == api_get_course_int_id()) {
         $actionLabel = get_lang('Modify');
-        $actionIcon1 = "edit";
-        $actionIcon2 = "delete";
+        $actionIcon1 = 'edit';
+        $actionIcon2 = 'delete';
         // We are in the course, question title can be a link to the question edit page
         $questionTagA = 1;
     } else { // NOT IN A TEST - NOT IN THE COURSE
         $actionLabel = get_lang('Reuse');
         $actionIcon1 = get_lang('MustBeInATest');
-        $actionIcon2 = "";
+        $actionIcon2 = '';
         // We are not in this course, to messy if we link to the question in another course
         $questionTagA = 0;
     }
@@ -682,51 +689,52 @@ if ($fromExercise <= 0) {
     // IN A TEST - IN THE COURSE
     if ($selected_course == api_get_course_int_id()) {
         $actionLabel = get_lang('Reuse');
-        $actionIcon1 = "add";
-        $actionIcon2 = "";
+        $actionIcon1 = 'add';
+        $actionIcon2 = '';
         $questionTagA = 1;
     } else {
         // IN A TEST - NOT IN THE COURSE
         $actionLabel = get_lang('Reuse');
-        $actionIcon1 = "clone";
-        $actionIcon2 = "";
+        $actionIcon1 = 'clone';
+        $actionIcon2 = '';
         $questionTagA = 0;
     }
 }
+
 // Display table
 $header = [
     [
         get_lang('QuestionUpperCaseFirstLetter'),
         false,
-        ["style" => "text-align:center"],
+        ['style' => 'text-align:center'],
         '',
     ],
     [
         get_lang('Type'),
         false,
-        ["style" => "text-align:center"],
-        ["style" => "text-align:center"],
+        ['style' => 'text-align:center'],
+        ['style' => 'text-align:center'],
         '',
     ],
     [
         get_lang('QuestionCategory'),
         false,
-        ["style" => "text-align:center"],
-        ["style" => "text-align:center"],
+        ['style' => 'text-align:center'],
+        ['style' => 'text-align:center'],
         '',
     ],
     [
         get_lang('Difficulty'),
         false,
-        ["style" => "text-align:center"],
-        ["style" => "text-align:center"],
+        ['style' => 'text-align:center'],
+        ['style' => 'text-align:center'],
         '',
     ],
     [
         $actionLabel,
         false,
-        ["style" => "text-align:center"],
-        ["style" => "text-align:center"],
+        ['style' => 'text-align:center'],
+        ['style' => 'text-align:center'],
         '',
     ],
 ];
@@ -735,20 +743,9 @@ $data = [];
 
 if (is_array($mainQuestionList)) {
     foreach ($mainQuestionList as $question) {
-        /*if ($hideDoubles) {
-            if (in_array($question['question'], $questionAdded)) {
-                continue;
-            }
-        }
-        $questionAdded[$question['question']] = $question;*/
-
         $row = [];
 
-        // This function checks if the question can be read
-        $question_type = get_question_type_for_question(
-            $selected_course,
-            $question['id']
-        );
+        $question_type = get_question_type_for_question($selected_course, $question['id']);
 
         if (empty($question_type)) {
             continue;
@@ -779,7 +776,7 @@ if (is_array($mainQuestionList)) {
             $answerType,
             $session_id,
             $exerciseId
-        )."&nbsp;".
+        ).'&nbsp;'.
         get_action_icon_for_question(
             $actionIcon2,
             $fromExercise,
@@ -900,7 +897,6 @@ function get_action_icon_for_question(
     $in_session_id,
     $in_exercise_id
 ) {
-    $res = "";
     $getParams = "&selected_course=$in_selected_course&courseCategoryId=$in_courseCategoryId&exerciseId=$in_exercise_id&exerciseLevel=$in_exerciseLevel&answerType=$in_answerType&session_id=$in_session_id";
     switch ($in_action) {
         case 'delete':
@@ -931,7 +927,8 @@ function get_action_icon_for_question(
             unset($myObjEx);
             break;
         case 'clone':
-            $url = api_get_self()."?".api_get_cidreq().$getParams."&question_copy=$in_questionid&course_id=$in_selected_course&fromExercise=$from_exercise";
+            $url = api_get_self()."?".api_get_cidreq().$getParams.
+                "&question_copy=$in_questionid&course_id=$in_selected_course&fromExercise=$from_exercise";
             $res = Display::url(
                 Display::return_icon('cd.png', get_lang('ReUseACopyInCurrentTest')),
                 $url
@@ -968,9 +965,9 @@ function get_question_type_for_question($in_selectedcourse, $in_questionid)
  *
  * @author hubert.borderiou 13-10-2011
  */
-function get_question_categorie_for_question($in_courseid, $in_questionid)
+function get_question_categorie_for_question($courseId, $questionId)
 {
-    $cat = TestCategory::getCategoryNameForQuestion($in_questionid, $in_courseid);
+    $cat = TestCategory::getCategoryNameForQuestion($questionId, $courseId);
 
     return $cat;
 }

+ 1 - 0
main/gradebook/lib/fe/gradebooktable.class.php

@@ -739,6 +739,7 @@ class GradebookTable extends SortableTable
                             $totalRanking,
                             SCORE_DIV,
                             SCORE_BOTH,
+                            true,
                             true
                         );
 

+ 5 - 5
main/group/group_space.php

@@ -455,11 +455,11 @@ function get_group_user_data($from, $number_of_items, $column, $direction)
 				user.firstname 	AS col2,"
             )."
 				user.email		AS col3
-				FROM $table_user user INNER JOIN 
-				$table_group_user group_rel_user
+				FROM $table_user user 
+				INNER JOIN $table_group_user group_rel_user
 				ON (group_rel_user.user_id = user.id)
 				INNER JOIN $tableGroup g
-				ON (group_rel_user.group_id = g.id)
+				ON (group_rel_user.group_id = g.iid)
 				WHERE 
 				    group_rel_user.c_id = $course_id AND 
 				    g.iid = '".$groupInfo['iid']."'
@@ -480,7 +480,7 @@ function get_group_user_data($from, $number_of_items, $column, $direction)
                     INNER JOIN $table_group_user gu 
                     ON (gu.user_id = u.id)
                     INNER JOIN $tableGroup g
-				    ON (gu.group_id = g.id)
+				    ON (gu.group_id = g.iid)
                     WHERE 
                         g.iid = '".$groupInfo['iid']."' AND 
                         gu.c_id = $course_id
@@ -501,7 +501,7 @@ function get_group_user_data($from, $number_of_items, $column, $direction)
                     INNER JOIN $table_group_user group_rel_user
                     ON (group_rel_user.user_id = user.id)
                     INNER JOIN $tableGroup g
-                    ON (group_rel_user.group_id = g.id)
+                    ON (group_rel_user.group_id = g.iid)
                     WHERE 
                         g.iid = '".$groupInfo['iid']."' AND 
                         group_rel_user.c_id = $course_id AND  

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

@@ -28,9 +28,9 @@ switch ($action) {
             break;
         }
         $add_as_announcement = isset($_REQUEST['add_as_annonuncement']) ? $_REQUEST['add_as_annonuncement'] : null;
-        $title = isset($_REQUEST['title']) ? Security::remove_XSS($_REQUEST['title']) : null;
-        $content = isset($_REQUEST['content']) ? Security::remove_XSS($_REQUEST['content']) : null;
-        $comment = isset($_REQUEST['comment']) ? Security::remove_XSS($_REQUEST['comment']) : null;
+        $title = isset($_REQUEST['title']) ? $_REQUEST['title'] : null;
+        $content = isset($_REQUEST['content']) ? $_REQUEST['content'] : null;
+        $comment = isset($_REQUEST['comment']) ? $_REQUEST['comment'] : null;
         $userToSend = isset($_REQUEST['users_to_send']) ? $_REQUEST['users_to_send'] : [];
 
         echo $agenda->addEvent(

+ 6 - 4
main/inc/ajax/lp.ajax.php

@@ -26,20 +26,22 @@ switch ($action) {
         if (empty($folderId)) {
             exit;
         }
-        $lpId = isset($_GET['lp_id']) ? $_GET['lp_id'] : null;
-        $url = isset($_GET['url']) ? $_GET['url'] : null;
+        $lpId = isset($_GET['lp_id']) ? $_GET['lp_id'] : false;
+        $url = isset($_GET['url']) ? $_GET['url'] : '';
+        $addMove = isset($_GET['add_move_button']) && $_GET['add_move_button'] == 1 ? true : false;
 
         echo DocumentManager::get_document_preview(
             $courseInfo,
             $lpId,
             null,
             api_get_session_id(),
-            true,
+            $addMove,
             null,
             $url,
             true,
             false,
-            $folderId
+            $folderId,
+            false
         );
         break;
     case 'add_lp_item':

+ 0 - 2
main/inc/ajax/statistics.ajax.php

@@ -8,8 +8,6 @@ use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
  */
 require_once __DIR__.'/../global.inc.php';
 
-use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
-
 api_protect_admin_script();
 
 $action = isset($_REQUEST['a']) ? $_REQUEST['a'] : null;

+ 12 - 10
main/inc/lib/AnnouncementManager.php

@@ -1,6 +1,7 @@
 <?php
 /* For licensing terms, see /license.txt */
 
+use Chamilo\CoreBundle\Entity\ExtraFieldValues;
 use Chamilo\CourseBundle\Entity\CAnnouncement;
 use Chamilo\CourseBundle\Entity\CItemProperty;
 
@@ -1620,8 +1621,11 @@ class AnnouncementManager
             $extraGroupCondition = " AND ip.to_group_id = $group_id ";
         }
 
-        if ((api_is_allowed_to_edit(false, true) || api_is_drh()) &&
-            ($allowUserEditSetting && !api_is_anonymous())
+        $allowDrhAccess = api_get_configuration_value('allow_drh_access_announcement');
+
+        if (api_is_allowed_to_edit(false, true) ||
+            ($allowUserEditSetting && !api_is_anonymous()) ||
+            ($allowDrhAccess && api_is_drh())
         ) {
             // A.1. you are a course admin with a USER filter
             // => see only the messages of this specific user + the messages of the group (s)he is member of.
@@ -1759,8 +1763,8 @@ class AnnouncementManager
                             ip.tool='announcement' 
                             $cond_user_id
                             $condition_session
-                            $searchCondition
-                            AND ip.visibility='1'
+                            $searchCondition AND 
+                            ip.visibility='1'
                         $groupBy
                         ORDER BY display_order DESC";
             } else {
@@ -1768,14 +1772,12 @@ class AnnouncementManager
                     if ($allowUserEditSetting && !api_is_anonymous()) {
                         $cond_user_id = " AND (
                             ip.lastedit_user_id = '".api_get_user_id()."' OR
-                            (
-                                (ip.to_user_id='$user_id' OR ip.to_user_id IS NULL) AND
+                                ((ip.to_user_id='$user_id' OR ip.to_user_id IS NULL) AND 
                                 (ip.to_group_id='0' OR ip.to_group_id IS NULL)
                             )
                         ) ";
                     } else {
-                        $cond_user_id = " AND (
-                        (ip.to_user_id='$user_id' OR ip.to_user_id IS NULL) AND 
+                        $cond_user_id = " AND ((ip.to_user_id='$user_id' OR ip.to_user_id IS NULL) AND 
                         (ip.to_group_id='0' OR ip.to_group_id IS NULL) ) ";
                     }
 
@@ -1823,8 +1825,8 @@ class AnnouncementManager
         }
 
         if (!is_null($start) && !is_null($limit)) {
-            $start = intval($start);
-            $limit = intval($limit);
+            $start = (int) $start;
+            $limit = (int) $limit;
             $sql .= " LIMIT $start, $limit";
         }
 

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 466 - 418
main/inc/lib/MoodleImport.php


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

@@ -2337,10 +2337,9 @@ class Agenda
         $action = isset($params['action']) ? Security::remove_XSS($params['action']) : null;
         $id = isset($params['id']) ? (int) $params['id'] : 0;
 
+        $url = api_get_self().'?action='.$action.'&id='.$id.'&type='.$this->type;
         if ($this->type == 'course') {
             $url = api_get_self().'?'.api_get_cidreq().'&action='.$action.'&id='.$id.'&type='.$this->type;
-        } else {
-            $url = api_get_self().'?action='.$action.'&id='.$id.'&type='.$this->type;
         }
 
         $form = new FormValidator(

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

@@ -117,9 +117,9 @@ class Attendance
         $course_id = api_get_course_int_id();
         $session_id = api_get_session_id();
         $condition_session = api_get_session_condition($session_id);
-        $column = intval($column);
-        $from = intval($from);
-        $number_of_items = intval($number_of_items);
+        $column = (int) $column;
+        $from = (int) $from;
+        $number_of_items = (int) $number_of_items;
 
         if (!in_array($direction, ['ASC', 'DESC'])) {
             $direction = 'ASC';
@@ -163,6 +163,7 @@ class Attendance
             if (api_get_session_id() == $attendance[6]) {
                 $session_star = api_get_session_image(api_get_session_id(), $user_info['status']);
             }
+
             if ($attendance[5] == 1) {
                 $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
                     api_get_user_id(),

+ 11 - 11
main/inc/lib/course.lib.php

@@ -88,29 +88,29 @@ class CourseManager
     /**
      * Creates a course.
      *
-     * @param array $params   columns in the main.course table
-     * @param int   $authorId
+     * @param array $params      Columns in the main.course table.
+     * @param int   $authorId    Optional.
+     * @param int   $accessUrlId Optional.
      *
      * @return mixed false if the course was not created, array with the course info
      */
-    public static function create_course($params, $authorId = 0)
+    public static function create_course($params, $authorId = 0, $accessUrlId = 0)
     {
         global $_configuration;
 
         $hook = HookCreateCourse::create();
 
         // Check portal limits
-        $access_url_id = 1;
-        if (api_get_multiple_access_url()) {
-            $access_url_id = api_get_current_access_url_id();
-        }
+        $accessUrlId = empty($accessUrlId)
+            ? (api_get_multiple_access_url() ? api_get_current_access_url_id() : 1)
+            : $accessUrlId;
 
         $authorId = empty($authorId) ? api_get_user_id() : (int) $authorId;
 
-        if (isset($_configuration[$access_url_id]) && is_array($_configuration[$access_url_id])) {
+        if (isset($_configuration[$accessUrlId]) && is_array($_configuration[$accessUrlId])) {
             $return = self::checkCreateCourseAccessUrlParam(
                 $_configuration,
-                $access_url_id,
+                $accessUrlId,
                 'hosting_limit_courses',
                 'PortalCoursesLimitReached'
             );
@@ -119,7 +119,7 @@ class CourseManager
             }
             $return = self::checkCreateCourseAccessUrlParam(
                 $_configuration,
-                $access_url_id,
+                $accessUrlId,
                 'hosting_limit_active_courses',
                 'PortalActiveCoursesLimitReached'
             );
@@ -153,7 +153,7 @@ class CourseManager
             $params['directory'] = $keys['currentCourseRepository'];
             $courseInfo = api_get_course_info($params['code']);
             if (empty($courseInfo)) {
-                $courseId = AddCourse::register_course($params);
+                $courseId = AddCourse::register_course($params, $accessUrlId);
                 $courseInfo = api_get_course_info_by_id($courseId);
 
                 if ($hook) {

+ 247 - 222
main/inc/lib/course_home.lib.php

@@ -133,9 +133,10 @@ class CourseHome
         }
 
         foreach ($all_tools as &$tool) {
-            if ($tool['image'] == 'scormbuilder.gif') {
+            if (isset($tool['image']) && $tool['image'] == 'scormbuilder.gif') {
                 // check if the published learnpath is visible for student
                 $lpId = self::getPublishedLpIdFromLink($tool['link']);
+
                 if (!api_is_allowed_to_edit(null, true) &&
                     !learnpath::is_lp_visible_for_student(
                         $lpId,
@@ -175,6 +176,7 @@ class CourseHome
 
             // Setting the actual image url
             $tool['img'] = Display::returnIconPath($tool['img']);
+            $target = isset($tool['target']) ? $tool['target'] : '';
 
             // VISIBLE
             if (($tool['visibility'] ||
@@ -190,7 +192,7 @@ class CourseHome
                     $cell_content .= '<a href="javascript: void(0);" onclick="javascript: window.open(\''.$tool['link'].$link_annex.'\',\'window_chat'.api_get_course_id().'\',config=\'height=\'+600+\', width=\'+825+\', left=2, top=2, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=no, directories=no, status=no\')" target="'.$tool['target'].'"><img src="'.$tool['img'].'" title="'.$tool_name.'" alt="'.$tool_name.'" align="absmiddle" border="0">'.$tool_name.'</a>';
                 } else {
                     // don't replace img with display::return_icon because $tool['img'] = api_get_path(WEB_IMG_PATH).$tool['img']
-                    $cell_content .= '<a href="'.$tool['link'].$link_annex.'" target="'.$tool['target'].'"><img src="'.$tool['img'].'" title="'.$tool_name.'" alt="'.$tool_name.'" align="absmiddle" border="0">'.$tool_name.'</a>';
+                    $cell_content .= '<a href="'.$tool['link'].$link_annex.'" target="'.$target.'"><img src="'.$tool['img'].'" title="'.$tool_name.'" alt="'.$tool_name.'" align="absmiddle" border="0">'.$tool_name.'</a>';
                 }
             } else {
                 // INVISIBLE
@@ -341,8 +343,8 @@ class CourseHome
                 $all_tools_list[] = $properties;
             }
         }
+        $lnk = [];
         if (isset($all_tools_list)) {
-            $lnk = [];
             foreach ($all_tools_list as &$tool) {
                 if ($tool['image'] == 'scormbuilder.gif') {
                     // check if the published learnpath is visible for student
@@ -391,7 +393,9 @@ class CourseHome
                 } elseif (strpos($tool['name'], 'chat') !== false && api_get_course_setting('allow_open_chat_window')) {
                     $html .= '<a href="javascript: void(0);" onclick="javascript: window.open(\''.htmlspecialchars($tool['link']).$qm_or_amp.api_get_cidreq().'\',\'window_chat'.api_get_course_id().'\',config=\'height=\'+600+\', width=\'+825+\', left=2, top=2, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=no, directories=no, status=no\')" target="'.$tool['target'].'" '.$class.'>';
                 } else {
-                    $html .= '<a href="'.htmlspecialchars($tool['link']).(($tool['image'] == 'external.gif' || $tool['image'] == 'external_na.gif') ? '' : $qm_or_amp.api_get_cidreq()).'" target="'.$tool['target'].'" '.$class.'>';
+                    $target = isset($tool['target']) ? $tool['target'] : '';
+                    $html .= '<a href="'.
+                        htmlspecialchars($tool['link']).(($tool['image'] == 'external.gif' || $tool['image'] == 'external_na.gif') ? '' : $qm_or_amp.api_get_cidreq()).'" target="'.$target.'" '.$class.'>';
                 }
 
                 $tool_name = self::translate_tool_name($tool);
@@ -406,7 +410,7 @@ class CourseHome
 
                 // This part displays the links to hide or remove a tool.
                 // These links are only visible by the course manager.
-                unset($lnk);
+                $lnk = [];
                 if (api_is_allowed_to_edit(null, true) && !api_is_coach()) {
                     if ($tool['visibility'] == '1' || $tool['name'] == TOOL_TRACKING) {
                         $link['name'] = Display::returnFontAwesomeIcon('minus');
@@ -759,12 +763,10 @@ class CourseHome
         }
 
         if (isset($tmp_all_tools_list)) {
+            $tbl_blogs_rel_user = Database::get_course_table(TABLE_BLOGS_REL_USER);
             foreach ($tmp_all_tools_list as $tool) {
                 if ($tool['image'] == 'blog.gif') {
                     // Init
-                    $tbl_blogs_rel_user = Database::get_course_table(TABLE_BLOGS_REL_USER);
-
-                    // Get blog id
                     $blog_id = substr($tool['link'], strrpos($tool['link'], '=') + 1, strlen($tool['link']));
 
                     // Get blog members
@@ -802,6 +804,7 @@ class CourseHome
     {
         $_user = api_get_user_info();
         $theme = api_get_setting('homepage_view');
+
         if ($theme === 'vertical_activity') {
             //ordering by get_lang name
             $order_tool_list = [];
@@ -824,7 +827,6 @@ class CourseHome
         $session_id = api_get_session_id();
         $is_platform_admin = api_is_platform_admin();
         $allowEditionInSession = api_get_configuration_value('allow_edit_tool_visibility_in_session');
-
         if ($session_id == 0) {
             $is_allowed_to_edit = api_is_allowed_to_edit(null, true) && api_is_course_admin();
         } else {
@@ -834,7 +836,6 @@ class CourseHome
             }
         }
 
-        $i = 0;
         $items = [];
         $app_plugin = new AppPlugin();
 
@@ -984,13 +985,12 @@ class CourseHome
                     $tool['link'] = $web_code_path.$tool['link'];
                 }
 
+                $class = '';
                 if ($tool['visibility'] == '0' && $toolAdmin != '1') {
                     $class = 'text-muted';
                     $info = pathinfo($tool['image']);
                     $basename = basename($tool['image'], '.'.$info['extension']); // $file is set to "index"
                     $tool['image'] = $basename.'_na.'.$info['extension'];
-                } else {
-                    $class = '';
                 }
 
                 $qm_or_amp = strpos($tool['link'], '?') === false ? '?' : '&';
@@ -1051,6 +1051,7 @@ class CourseHome
                         .$tool['original_link'].$qm_or_amp.api_get_cidreq();
                 }
 
+                // Use in the course home
                 $icon = Display::return_icon(
                     $tool['image'],
                     $tool_name,
@@ -1059,6 +1060,24 @@ class CourseHome
                     false
                 );
 
+                // Used in the top bar
+                $iconMedium = Display::return_icon(
+                    $tool['image'],
+                    $tool_name,
+                    ['class' => 'tool-icon', 'id' => 'toolimage_'.$toolIid],
+                    ICON_SIZE_MEDIUM,
+                    false
+                );
+
+                // Used for vertical navigation
+                $iconSmall = Display::return_icon(
+                    $tool['image'],
+                    $tool_name,
+                    ['class' => 'tool-img', 'id' => 'toolimage_'.$toolIid],
+                    ICON_SIZE_SMALL,
+                    false
+                );
+
                 /*if (!empty($tool['custom_icon'])) {
                     $image = self::getCustomWebIconPath().$tool['custom_icon'];
                     $icon = Display::img(
@@ -1081,6 +1100,10 @@ class CourseHome
                 }
                 $item['url_params'] = $tool_link_params;
                 $item['icon'] = Display::url($icon, $tool_link_params['href'], $tool_link_params);
+                $item['only_icon'] = $icon;
+                $item['only_icon_medium'] = $iconMedium;
+                $item['only_icon_small'] = $iconSmall;
+                $item['only_href'] = $tool_link_params['href'];
                 $item['tool'] = $tool;
                 $item['name'] = $tool_name;
                 $tool_link_params['id'] = 'is'.$tool_link_params['id'];
@@ -1090,21 +1113,21 @@ class CourseHome
                     $tool_link_params
                 );
                 $items[] = $item;
-                $i++;
             } // end of foreach
         }
 
-        if (api_get_setting('homepage_view') != 'activity_big') {
-            return $items;
-        }
-
         foreach ($items as &$item) {
-            $originalImage = self::getToolIcon($item);
-            $item['tool']['image'] = Display::url(
-                $originalImage,
-                $item['url_params']['href'],
-                $item['url_params']
-            );
+            $originalImage = self::getToolIcon($item, ICON_SIZE_BIG);
+            $item['tool']['only_icon_medium'] = self::getToolIcon($item, ICON_SIZE_MEDIUM, false);
+            $item['tool']['only_icon_small'] = self::getToolIcon($item, ICON_SIZE_SMALL, false);
+
+            if ($theme === 'activity_big') {
+                $item['tool']['image'] = Display::url(
+                    $originalImage,
+                    $item['url_params']['href'],
+                    $item['url_params']
+                );
+            }
         }
 
         return $items;
@@ -1183,13 +1206,15 @@ class CourseHome
 
         $toolName = Security::remove_XSS(stripslashes($tool['name']));
 
-        if (in_array($tool['image'], $already_translated_icons)) {
+        if (isset($tool['image']) && in_array($tool['image'], $already_translated_icons)) {
             return $toolName;
         }
 
         $toolName = api_underscore_to_camel_case($toolName);
 
-        if (isset($GLOBALS['Tool'.$toolName])) {
+        if (isset($tool['category']) && 'plugin' !== $tool['category'] &&
+            isset($GLOBALS['Tool'.$toolName])
+        ) {
             return get_lang('Tool'.$toolName);
         }
 
@@ -1236,121 +1261,12 @@ class CourseHome
         return $category;
     }
 
-    /**
-     * @param bool $include_admin_tools
-     *
-     * @return array
-     */
-    public static function get_navigation_items($include_admin_tools = false)
-    {
-        $navigation_items = [];
-        $course_id = api_get_course_int_id();
-        $courseInfo = api_get_course_info();
-        $sessionId = api_get_session_id();
-
-        $conditionSession = api_get_session_condition(
-            $sessionId,
-            true,
-            true,
-            'session_id'
-        );
-
-        if (!empty($course_id)) {
-            $course_tools_table = Database::get_course_table(TABLE_TOOL_LIST);
-            /* 	Link to the Course homepage */
-            $navigation_items['home']['image'] = 'home.png';
-            $navigation_items['home']['link'] = $courseInfo['course_public_url'];
-            $navigation_items['home']['name'] = get_lang('CourseHomepageLink');
-
-            $sql = "SELECT * FROM $course_tools_table
-                    WHERE 
-                      c_id = $course_id AND 
-                      visibility = '1' AND 
-                      admin = '0'
-                      $conditionSession
-                    ORDER BY id ASC";
-            $result = Database::query($sql);
-
-            $hideTools = [];
-            $hideToolsKeys = [];
-            if (!api_is_platform_admin()) {
-                $hideTools = api_get_setting('course_hide_tools');
-                $hideToolsKeys = array_keys($hideTools);
-            }
-
-            while ($row = Database::fetch_array($result)) {
-                if (!empty($hideTools)) {
-                    if (in_array($row['name'], $hideToolsKeys)) {
-                        // Tool is hidden
-                        if ($hideTools[$row['name']] == 'true') {
-                            continue;
-                        }
-                    }
-                }
-
-                $navigation_items[$row['id']] = $row;
-                if (stripos($row['link'], 'http://') === false &&
-                    stripos($row['link'], 'https://') === false
-                ) {
-                    $navigation_items[$row['id']]['link'] = api_get_path(WEB_CODE_PATH);
-
-                    if ($row['category'] == 'plugin') {
-                        $plugin = new AppPlugin();
-                        $pluginInfo = $plugin->getPluginInfo($row['name']);
-                        if (isset($pluginInfo['title'])) {
-                            $navigation_items[$row['id']]['link'] = api_get_path(WEB_PLUGIN_PATH);
-                            $navigation_items[$row['id']]['name'] = $pluginInfo['title'];
-                        }
-                    } else {
-                        $navigation_items[$row['id']]['name'] = self::translate_tool_name($row);
-                    }
-
-                    $navigation_items[$row['id']]['link'] .= $row['link'];
-                }
-            }
-
-            /* Admin (edit rights) only links
-            - Course settings (course admin only)
-            - Course rights (roles & rights overview) */
-            if ($include_admin_tools) {
-                $sql = "SELECT name, image FROM $course_tools_table
-                        WHERE c_id = $course_id  AND link='course_info/infocours.php'";
-                $sql_result = Database::query($sql);
-                $course_setting_info = Database::fetch_array($sql_result);
-                $course_setting_visual_name = self::translate_tool_name($course_setting_info);
-                if ($sessionId == 0) {
-                    // course settings item
-                    $navigation_items['course_settings']['image'] = $course_setting_info['image'];
-                    $navigation_items['course_settings']['link'] = api_get_path(WEB_CODE_PATH).'course_info/infocours.php';
-                    $navigation_items['course_settings']['name'] = $course_setting_visual_name;
-                }
-            }
-        }
-
-        foreach ($navigation_items as $key => $navigation_item) {
-            if (strstr($navigation_item['link'], '?')) {
-                //link already contains a parameter, add course id parameter with &
-                $parameter_separator = '&amp;';
-            } else {
-                //link doesn't contain a parameter yet, add course id parameter with ?
-                $parameter_separator = '?';
-            }
-            //$navigation_items[$key]['link'] .= $parameter_separator.api_get_cidreq();
-            $navigation_items[$key]['link'] .= $parameter_separator.'cidReq='.api_get_course_id().'&gidReq=0&id_session='.$sessionId;
-        }
-
-        return $navigation_items;
-    }
-
     /**
      * Show a navigation menu.
      */
     public static function show_navigation_menu()
     {
-        $navigation_items = self::get_navigation_items(true);
-
-        $course_id = api_get_course_id();
-
+        $blocks = self::getUserBlocks();
         $class = null;
         $idLearn = null;
         $item = null;
@@ -1358,62 +1274,37 @@ class CourseHome
 
         $html = '<div id="toolnav">';
         $html .= '<ul id="toolnavbox">';
-        $count = 0;
-        foreach ($navigation_items as $key => $navigation_item) {
             //students can't see the course settings option
-            $count++;
-            if (!api_is_allowed_to_edit() && $key == 'course_settings') {
-                continue;
-            }
-            $html .= '<li>';
-            $url_item = parse_url($navigation_item['link']);
-            $url_current = parse_url($_SERVER['REQUEST_URI']);
+        $showOnlyText = api_get_setting('show_navigation_menu') === 'text';
+        $showOnlyIcons = api_get_setting('show_navigation_menu') === 'icons';
 
-            if (api_get_setting('show_navigation_menu') == 'text') {
+        foreach ($blocks as $block) {
+            $blockItems = $block['content'];
+            foreach ($blockItems as $item) {
+            $html .= '<li>';
+                if ($showOnlyText) {
                 $class = 'text';
                 $marginLeft = 170;
-                $item = $navigation_item['name'];
-            } elseif (api_get_setting('show_navigation_menu') == 'icons') {
-                $class = 'icons';
-                $marginLeft = 25;
-                $item = Display::return_icon(
-                    substr($navigation_item['image'], 0, -3)."png",
-                    $navigation_item['name'],
-                    ['class' => 'tool-img'],
-                    ICON_SIZE_SMALL
-                );
-            } else {
-                $class = 'icons-text';
-                $item = $navigation_item['name'].
-                    Display::return_icon(
-                        substr($navigation_item['image'], 0, -3)."png",
-                        $navigation_item['name'],
-                        ['class' => 'tool-img'],
-                        ICON_SIZE_SMALL
-                    );
-            }
-
-            if (stristr($url_item['path'], $url_current['path'])) {
-                if (!isset($_GET['learnpath_id']) || strpos($url_item['query'], 'learnpath_id='.intval($_GET['learnpath_id'])) === 0) {
-                    $idLearn = ' id="here"';
+                    $show = $item['name'];
+                } elseif ($showOnlyIcons) {
+                    $class = 'icons';
+                    $marginLeft = 25;
+                    $show = $item['tool']['only_icon_small'];
+                } else {
+                    $class = 'icons-text';
+                        $show = $item['name'].$item['tool']['only_icon_small'];
                 }
-            }
-
-            if (strpos($navigation_item['link'], 'chat') !== false &&
-                api_get_course_setting('allow_open_chat_window', $course_id)
-            ) {
-                $html .= '<a '.$idLearn.' class="btn btn-default text-left '.$class.' " href="javascript: void(0);" onclick="javascript: window.open(\''.$navigation_item['link'].'\',\'window_chat'.api_get_course_id().'\',config=\'height=\'+600+\', width=\'+825+\', left=2, top=2, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=no, directories=no, status=no\')" target="'.$navigation_item['target'].'"';
-                $html .= ' title="'.$navigation_item['name'].'">';
-                $html .= $item;
-                $html .= '</a>';
-            } else {
-                $html .= '<a '.$idLearn.' class="btn btn-default text-left '.$class.'" href="'.$navigation_item['link'].'" target="_top" title="'.$navigation_item['name'].'">';
-                $html .= $item;
-                $html .= '</a>';
-            }
 
+                $item['url_params']['class'] = 'btn btn-default text-left '.$class;
+                $html .= Display::url(
+                    $show,
+                    $item['only_href'],
+                    $item['url_params']
+                );
             $html .= '</li>';
+            }
         }
+
         $html .= '</ul>';
         $html .= '<script>$(function() {
                 $("#toolnavbox a").stop().animate({"margin-left":"-'.$marginLeft.'px"},1000);
@@ -1443,52 +1334,40 @@ class CourseHome
     public static function getCourseToolBar($orientation = SHORTCUTS_HORIZONTAL): string
     {
         $origin = api_get_origin();
+        $courseInfo = api_get_course_info();
         if ($origin === 'learnpath') {
             return '';
         }
 
-        $navigation_items = self::get_navigation_items(false);
+        $blocks = self::getUserBlocks();
+
         $html = '';
-        if (!empty($navigation_items)) {
+        if (!empty($blocks)) {
             $style_id = 'toolshortcuts_vertical';
-            if ($orientation === SHORTCUTS_HORIZONTAL) {
+            if ($orientation == SHORTCUTS_HORIZONTAL) {
                 $style_id = 'toolshortcuts_horizontal';
             }
             $html .= '<div id="'.$style_id.'">';
-            foreach ($navigation_items as $key => $navigation_item) {
-                if (strpos($navigation_item['link'], 'chat') !== false &&
-                    api_get_course_setting('allow_open_chat_window')
-                ) {
-                    $html .= '<a class="items-icon" href="javascript: void(0);" onclick="javascript: window.open(\''.$navigation_item['link'].'\',\'window_chat'.api_get_course_id().'\',config=\'height=\'+600+\', width=\'+825+\', left=2, top=2, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=no, directories=no, status=no\')" target="'.$navigation_item['target'].'"';
-                } else {
-                    $html .= '<a class="items-icon" href="'.$navigation_item['link'].'"';
-                }
-                if (strpos(api_get_self(), $navigation_item['link']) !== false) {
-                    $html .= ' id="here"';
-                }
-                $html .= ' target="_top" title="'.$navigation_item['name'].'">';
 
-                if (isset($navigation_item['category']) && $navigation_item['category'] == 'plugin') {
-                    /*$plugin_info = $app_plugin->getPluginInfo($navigation_item['name']);
-                    if (isset($plugin_info) && isset($plugin_info['title'])) {
-                        $tool_name = $plugin_info['title'];
-                    }*/
-                    if (!file_exists(api_get_path(SYS_CODE_PATH).'img/'.$navigation_item['image']) &&
-                        !file_exists(api_get_path(SYS_CODE_PATH).'img/icons/'.ICON_SIZE_MEDIUM.'/'.$navigation_item['image'])
-                    ) {
-                        $navigation_item['image'] = 'plugins.png';
-                    }
-                }
+            $html .= Display::url(
+                Display::return_icon('home.png', get_lang('CourseHomepageLink'), '', ICON_SIZE_MEDIUM),
+                $courseInfo['course_public_url'],
+                ['class' => 'items-icon']
+            );
 
-                $html .= Display::return_icon(
-                    substr($navigation_item['image'], 0, -3).'png',
-                    $navigation_item['name'],
-                    [],
-                    ICON_SIZE_MEDIUM
-                );
-                $html .= '</a> ';
-                if ($orientation == SHORTCUTS_VERTICAL) {
-                    $html .= '<br />';
+            foreach ($blocks as $block) {
+                $blockItems = $block['content'];
+                foreach ($blockItems as $item) {
+                    $item['url_params']['id'] = '';
+                    $item['url_params']['class'] = 'items-icon';
+                    $html .= Display::url(
+                        $item['tool']['only_icon_medium'],
+                        $item['only_href'],
+                        $item['url_params']
+                    );
+                    if ($orientation == SHORTCUTS_VERTICAL) {
+                        $html .= '<br />';
+                    }
                 }
             }
             $html .= '</div>';
@@ -1688,6 +1567,145 @@ class CourseHome
         }
     }
 
+    /**
+     * @return array
+     */
+    public static function getCourseAdminBlocks()
+    {
+        $blocks = [];
+        $my_list = self::get_tools_category(TOOL_AUTHORING);
+
+        $blocks[] = [
+            'title' => get_lang('Authoring'),
+            'class' => 'course-tools-author',
+            'content' => self::show_tools_category($my_list),
+        ];
+
+        $list1 = self::get_tools_category(TOOL_INTERACTION);
+        $list2 = self::get_tools_category(TOOL_COURSE_PLUGIN);
+        $my_list = array_merge($list1, $list2);
+
+        $blocks[] = [
+            'title' => get_lang('Interaction'),
+            'class' => 'course-tools-interaction',
+            'content' => self::show_tools_category($my_list),
+        ];
+
+        $my_list = self::get_tools_category(TOOL_ADMIN_PLATFORM);
+
+        $blocks[] = [
+            'title' => get_lang('Administration'),
+            'class' => 'course-tools-administration',
+            'content' => self::show_tools_category($my_list),
+        ];
+
+        return $blocks;
+    }
+
+    /**
+     * @return array
+     */
+    public static function getCoachBlocks()
+    {
+        $blocks = [];
+        $my_list = self::get_tools_category(TOOL_STUDENT_VIEW);
+
+        $blocks[] = [
+            'content' => self::show_tools_category($my_list),
+        ];
+
+        $sessionsCopy = api_get_setting('allow_session_course_copy_for_teachers');
+        if ($sessionsCopy === 'true') {
+            // Adding only maintenance for coaches.
+            $myList = self::get_tools_category(TOOL_ADMIN_PLATFORM);
+            $onlyMaintenanceList = [];
+
+            foreach ($myList as $item) {
+                if ($item['name'] === 'course_maintenance') {
+                    $item['link'] = 'course_info/maintenance_coach.php';
+
+                    $onlyMaintenanceList[] = $item;
+                }
+            }
+
+            $blocks[] = [
+                'title' => get_lang('Administration'),
+                'content' => self::show_tools_category($onlyMaintenanceList),
+            ];
+        }
+
+        return $blocks;
+    }
+
+    /**
+     * @return array
+     */
+    public static function getStudentBlocks()
+    {
+        $blocks = [];
+        $tools = self::get_tools_category(TOOL_STUDENT_VIEW);
+        $isDrhOfCourse = CourseManager::isUserSubscribedInCourseAsDrh(
+            api_get_user_id(),
+            api_get_course_info()
+        );
+
+        // Force user icon for DRH
+        if ($isDrhOfCourse) {
+            $addUserTool = true;
+            foreach ($tools as $tool) {
+                if ($tool['name'] === 'user') {
+                    $addUserTool = false;
+                    break;
+                }
+            }
+
+            if ($addUserTool) {
+                $tools[] = [
+                    'c_id' => api_get_course_int_id(),
+                    'name' => 'user',
+                    'link' => 'user/user.php',
+                    'image' => 'members.gif',
+                    'visibility' => '1',
+                    'admin' => '0',
+                    'address' => 'squaregrey.gif',
+                    'added_tool' => '0',
+                    'target' => '_self',
+                    'category' => 'interaction',
+                    'session_id' => api_get_session_id(),
+                ];
+            }
+        }
+
+        if (count($tools) > 0) {
+            $blocks[] = ['content' => self::show_tools_category($tools)];
+        }
+
+        if ($isDrhOfCourse) {
+            $drhTool = self::get_tools_category(TOOL_DRH);
+            $blocks[] = ['content' => self::show_tools_category($drhTool)];
+        }
+
+        return $blocks;
+    }
+
+    /**
+     * @return array
+     */
+    public static function getUserBlocks()
+    {
+        $sessionId = api_get_session_id();
+        // Start of tools for CourseAdmins (teachers/tutors)
+        if ($sessionId === 0 && api_is_course_admin() && api_is_allowed_to_edit(null, true)) {
+            $blocks = self::getCourseAdminBlocks();
+        } elseif (api_is_coach()) {
+            $blocks = self::getCoachBlocks();
+        } else {
+            $blocks = self::getStudentBlocks();
+        }
+
+        return $blocks;
+    }
+
     /**
      * Filter tool icons. Only show if $patronKey is = :teacher
      * Example dataIcons[i]['name']: parameter titleIcons1:teacher || titleIcons2 || titleIcons3:teacher.
@@ -1749,10 +1767,12 @@ class CourseHome
      * Find the tool icon when homepage_view is activity_big.
      *
      * @param array $item
+     * @param int   $iconSize
+     * @param bool  $generateId
      *
      * @return string
      */
-    private static function getToolIcon(array $item)
+    private static function getToolIcon(array $item, $iconSize, $generateId = true)
     {
         $image = str_replace('.gif', '.png', $item['tool']['image']);
         $toolIid = isset($item['tool']['iid']) ? $item['tool']['iid'] : null;
@@ -1779,11 +1799,16 @@ class CourseHome
             );
         }
 
+        $id = '';
+        if ($generateId) {
+            $id = 'toolimage_'.$toolIid;
+        }
+
         return Display::return_icon(
-            'tool_'.$image,
+            $image,
             $item['name'],
-            ['id' => 'toolimage_'.$toolIid],
-            ICON_SIZE_BIG,
+            ['id' => $id],
+            $iconSize,
             false
         );
     }

+ 1 - 0
main/inc/lib/document.lib.php

@@ -6509,6 +6509,7 @@ class DocumentManager
                         $media->setWidth($size[0]);
                         $media->setHeight($size[1]);
                     }
+                    $document->setPath();
                 } else {
                     // We get the content and create a file
                     $handle = tmpfile();

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

@@ -3205,7 +3205,7 @@ EOT;
             // only end is set
             $time_conditions .= " (start_time IS NULL AND end_time <> '' AND end_time > '$now') OR ";
             // nothing is set
-            $time_conditions .= " (start_time IS NULL AND end_time IS NULL))  ";
+            $time_conditions .= ' (start_time IS NULL AND end_time IS NULL)) ';
         }
 
         $needle_where = !empty($search) ? " AND title LIKE '?' " : '';

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

@@ -1290,92 +1290,6 @@ EOT;
         return $this->returnForm();
     }
 
-    /**
-     * Create a form validator based on an array of form data:.
-     *
-     *         array(
-     *             'name' => 'zombie_report_parameters',    //optional
-     *             'method' => 'GET',                       //optional
-     *             'items' => array(
-     *                 array(
-     *                     'name' => 'ceiling',
-     *                     'label' => 'Ceiling',            //optional
-     *                     'type' => 'date',
-     *                     'default' => date()              //optional
-     *                 ),
-     *                 array(
-     *                     'name' => 'active_only',
-     *                     'label' => 'ActiveOnly',
-     *                     'type' => 'checkbox',
-     *                     'default' => true
-     *                 ),
-     *                 array(
-     *                     'name' => 'submit_button',
-     *                     'type' => 'style_submit_button',
-     *                     'value' => get_lang('Search'),
-     *                     'attributes' => array('class' => 'search')
-     *                 )
-     *             )
-     *         );
-     *
-     * @param array $form_data
-     *
-     * @deprecated use normal FormValidator construct
-     *
-     * @return FormValidator
-     */
-    public static function create($form_data)
-    {
-        if (empty($form_data)) {
-            return null;
-        }
-        $form_name = isset($form_data['name']) ? $form_data['name'] : 'form';
-        $form_method = isset($form_data['method']) ? $form_data['method'] : 'POST';
-        $form_action = isset($form_data['action']) ? $form_data['action'] : '';
-        $form_target = isset($form_data['target']) ? $form_data['target'] : '';
-        $form_attributes = isset($form_data['attributes']) ? $form_data['attributes'] : null;
-        $form_track_submit = isset($form_data['track_submit']) ? $form_data['track_submit'] : true;
-        $reset = null;
-        $result = new FormValidator($form_name, $form_method, $form_action, $form_target, $form_attributes, $form_track_submit);
-
-        $defaults = [];
-        foreach ($form_data['items'] as $item) {
-            $name = $item['name'];
-            $type = isset($item['type']) ? $item['type'] : 'text';
-            $label = isset($item['label']) ? $item['label'] : '';
-            if ($type == 'wysiwyg') {
-                $element = $result->addHtmlEditor($name, $label);
-            } else {
-                $element = $result->addElement($type, $name, $label);
-            }
-            if (isset($item['attributes'])) {
-                $attributes = $item['attributes'];
-                $element->setAttributes($attributes);
-            }
-            if (isset($item['value'])) {
-                $value = $item['value'];
-                $element->setValue($value);
-            }
-            if (isset($item['default'])) {
-                $defaults[$name] = $item['default'];
-            }
-            if (isset($item['rules'])) {
-                $rules = $item['rules'];
-                foreach ($rules as $rule) {
-                    $message = $rule['message'];
-                    $type = $rule['type'];
-                    $format = isset($rule['format']) ? $rule['format'] : null;
-                    $validation = isset($rule['validation']) ? $rule['validation'] : 'server';
-                    $force = isset($rule['force']) ? $rule['force'] : false;
-                    $result->addRule($name, $message, $type, $format, $validation, $reset, $force);
-                }
-            }
-        }
-        $result->setDefaults($defaults);
-
-        return $result;
-    }
-
     /**
      * @return HTML_QuickForm_Renderer_Default
      */

+ 16 - 8
main/inc/lib/groupmanager.lib.php

@@ -109,7 +109,7 @@ class GroupManager
         $course_id = $course_info['real_id'];
         $table_group = Database::get_course_table(TABLE_GROUP);
 
-        $select = " g.id,
+        $select = ' g.id,
                     g.iid,
                     g.name,
                     g.description,
@@ -119,9 +119,9 @@ class GroupManager
                     g.self_registration_allowed,
                     g.self_unregistration_allowed,
                     g.session_id,
-                    g.status";
+                    g.status';
         if ($getCount) {
-            $select = " DISTINCT count(g.iid) as count ";
+            $select = ' DISTINCT count(g.iid) as count ';
         }
 
         $sql = "SELECT 
@@ -148,7 +148,7 @@ class GroupManager
         if (!empty($session_condition)) {
             $sql .= $session_condition;
         }
-        $sql .= "ORDER BY UPPER(g.name)";
+        $sql .= ' ORDER BY UPPER(g.name)';
 
         $result = Database::query($sql);
 
@@ -1685,15 +1685,19 @@ class GroupManager
      */
     public static function get_subscribed_users($groupInfo)
     {
+        if (empty($groupInfo)) {
+            return [];
+        }
+
         $table_user = Database::get_main_table(TABLE_MAIN_USER);
         $table_group_user = Database::get_course_table(TABLE_GROUP_USER);
         $order_clause = api_sort_by_first_name() ? ' ORDER BY u.firstname, u.lastname' : ' ORDER BY u.lastname, u.firstname';
         $orderListByOfficialCode = api_get_setting('order_user_list_by_official_code');
         if ($orderListByOfficialCode === 'true') {
-            $order_clause = " ORDER BY u.official_code, u.firstname, u.lastname";
+            $order_clause = ' ORDER BY u.official_code, u.firstname, u.lastname';
         }
 
-        $group_id = intval($groupInfo['id']);
+        $group_id = (int) $groupInfo['iid'];
 
         if (empty($group_id)) {
             return [];
@@ -1741,16 +1745,20 @@ class GroupManager
      */
     public static function get_subscribed_tutors($groupInfo, $id_only = false)
     {
+        if (empty($groupInfo)) {
+            return [];
+        }
+
         $table_user = Database::get_main_table(TABLE_MAIN_USER);
         $table_group_tutor = Database::get_course_table(TABLE_GROUP_TUTOR);
         $order_clause = api_sort_by_first_name() ? ' ORDER BY u.firstname, u.lastname' : ' ORDER BY u.lastname, u.firstname';
 
         $orderListByOfficialCode = api_get_setting('order_user_list_by_official_code');
         if ($orderListByOfficialCode === 'true') {
-            $order_clause = " ORDER BY u.official_code, u.firstname, u.lastname";
+            $order_clause = ' ORDER BY u.official_code, u.firstname, u.lastname';
         }
 
-        $group_id = intval($groupInfo['id']);
+        $group_id = (int) $groupInfo['iid'];
         $course_id = api_get_course_int_id();
 
         $sql = "SELECT tg.id, u.user_id, u.lastname, u.firstname, u.email

+ 3 - 13
main/inc/lib/pear/HTML/Common.php

@@ -146,6 +146,7 @@ class HTML_Common
                 $strAttr .= ' ' . $key . '= "' . $value. '"';
             }
         }
+
         return $strAttr;
     }
 
@@ -155,7 +156,7 @@ class HTML_Common
      * @access   private
      * @return   array
      */
-    function _parseAttributes($attributes)
+    public function _parseAttributes($attributes)
     {
         if (is_array($attributes)) {
             $ret = array();
@@ -457,17 +458,6 @@ class HTML_Common
      */
     function charset($newCharset = null)
     {
-        // Modified by Ivan Tcholakov, 16-MAR-2010
-        //static $charset = 'ISO-8859-1';
-        static $charset;
-        if (!isset($charset)) {
-            $charset = api_get_system_encoding();
-        }
-        //
-
-        if (!is_null($newCharset)) {
-            $charset = $newCharset;
-        }
-        return $charset;
+        return 'UTF-8';
     } // end func charset
 }

+ 3 - 3
main/inc/lib/pear/HTML/QuickForm.php

@@ -350,19 +350,19 @@ class HTML_QuickForm extends HTML_Common
                 if (is_array($filter) && (2 != count($filter) || !is_callable($filter))) {
                     foreach ($filter as $val) {
                         if (!is_callable($val)) {
-                            throw new \Exception("Callback function does not exist in QuickForm::setDefaults()");
+                            throw new \Exception('Callback function does not exist in QuickForm::setDefaults()');
                         } else {
                             $defaultValues = $this->_recursiveFilter($val, $defaultValues);
                         }
                     }
                 } elseif (!is_callable($filter)) {
-                    throw new \Exception("Callback function does not exist in QuickForm::setDefaults()");
+                    throw new \Exception('Callback function does not exist in QuickForm::setDefaults()');
                 } else {
                     $defaultValues = $this->_recursiveFilter($filter, $defaultValues);
                 }
             }
 
-            $this->_defaultValues = HTML_QuickForm::arrayMerge($this->_defaultValues, $defaultValues);
+            $this->_defaultValues = self::arrayMerge($this->_defaultValues, $defaultValues);
             $this->_constantValues = $this->_defaultValues;
             foreach (array_keys($this->_elements) as $key) {
                 $this->_elements[$key]->onQuickFormEvent('updateValue', null, $this);

+ 0 - 1
main/inc/lib/pear/HTML/QuickForm/Renderer.php

@@ -155,4 +155,3 @@ class HTML_QuickForm_Renderer
         return;
     } // end func finishGroup
 } // end class HTML_QuickForm_Renderer
-?>

+ 4 - 3
main/inc/lib/pear/HTML/QuickForm/checkbox.php

@@ -140,10 +140,11 @@ class HTML_QuickForm_checkbox extends HTML_QuickForm_input
         } elseif ($this->_flagFrozen) {
             $label = $this->_text;
         } else {
-            $className = $this->checkboxClass;
+            $labelClass = $this->labelClass;
+            $checkClass = $this->checkboxClass;
             $name = $this->_attributes['name'];
-            $label ='<div id="'.$name.'" class="'.$className.'_'.$name.'">
-                <label>' .
+            $label ='<div id="'.$name.'" class="'.$checkClass.'">
+                <label class="'.$labelClass.'">' .
                     HTML_QuickForm_input::toHtml().' '.$this->_text.
                 '</label>
                 </div>

+ 34 - 59
main/inc/lib/pear/HTML/QuickForm/element.php

@@ -43,17 +43,15 @@ class HTML_QuickForm_element extends HTML_Common
     /**
      * Label of the field
      * @var       string
-     * @since     1.3
-     * @access    private
      */
-    var $_label = '';
+    public $_label = '';
 
     /**
      * Label "for" a field... (Chamilo LMS customization)
      * @var     string
      * @access  private
      */
-    var $_label_for = '';
+    public $_label_for = '';
 
     /**
      * Form element type
@@ -61,7 +59,7 @@ class HTML_QuickForm_element extends HTML_Common
      * @since     1.0
      * @access    private
      */
-    var $_type = '';
+    public $_type = '';
 
     /**
      * Flag to tell if element is frozen
@@ -69,7 +67,7 @@ class HTML_QuickForm_element extends HTML_Common
      * @since     1.0
      * @access    private
      */
-    var $_flagFrozen = false;
+    public $_flagFrozen = false;
 
     /**
      * Does the element support persistant data when frozen
@@ -77,7 +75,7 @@ class HTML_QuickForm_element extends HTML_Common
      * @since     1.3
      * @access    private
      */
-    var $_persistantFreeze = false;
+    public $_persistantFreeze = false;
 
     protected $columnsSize;
 
@@ -179,9 +177,6 @@ class HTML_QuickForm_element extends HTML_Common
         return 3.2;
     } // end func apiVersion
 
-    // }}}
-    // {{{ getType()
-
     /**
      * Returns element type
      *
@@ -194,9 +189,6 @@ class HTML_QuickForm_element extends HTML_Common
         return $this->_type;
     } // end func getType
 
-    // }}}
-    // {{{ setName()
-
     /**
      * Sets the input field name
      *
@@ -207,12 +199,8 @@ class HTML_QuickForm_element extends HTML_Common
      */
     public function setName($name)
     {
-        // interface method
     } //end func setName
 
-    // }}}
-    // {{{ getName()
-
     /**
      * Returns the element name
      *
@@ -222,12 +210,8 @@ class HTML_QuickForm_element extends HTML_Common
      */
     public function getName()
     {
-        // interface method
     } //end func getName
 
-    // }}}
-    // {{{ setValue()
-
     /**
      * Sets the value of the form element
      *
@@ -238,12 +222,8 @@ class HTML_QuickForm_element extends HTML_Common
      */
     public function setValue($value)
     {
-        // interface
     } // end func setValue
 
-    // }}}
-    // {{{ getValue()
-
     /**
      * Returns the value of the form element
      *
@@ -253,12 +233,30 @@ class HTML_QuickForm_element extends HTML_Common
      */
     public function getValue()
     {
-        // interface
         return null;
     } // end func getValue
 
-    // }}}
-    // {{{ freeze()
+    /**
+     * @return string
+     */
+    public function getCleanValue()
+    {
+        $value = $this->cleanValueFromParameter($this->getValue());
+
+        return $value;
+    }
+
+    /**
+     * @param string $value
+     *
+     * @return string
+     */
+    public function cleanValueFromParameter($value)
+    {
+        $value = @htmlspecialchars($value, ENT_COMPAT, HTML_Common::charset());
+
+        return $value;
+    }
 
     /**
      * Freeze the element so that only its value is returned
@@ -271,9 +269,6 @@ class HTML_QuickForm_element extends HTML_Common
         $this->_flagFrozen = true;
     } //end func freeze
 
-    // }}}
-    // {{{ unfreeze()
-
    /**
     * Unfreezes the element so that it becomes editable
     *
@@ -286,9 +281,6 @@ class HTML_QuickForm_element extends HTML_Common
         $this->_flagFrozen = false;
     }
 
-    // }}}
-    // {{{ getFrozenHtml()
-
     /**
      * Returns the value of field without HTML tags
      *
@@ -302,12 +294,16 @@ class HTML_QuickForm_element extends HTML_Common
         // Modified by Ivan Tcholakov, 16-MAR-2010.
         //return ('' != $value? htmlspecialchars($value): '&nbsp;') .
         //       $this->_getPersistantData();
+        if (!empty($value)) {
+            $value = $this->getCleanValue();
+        } else {
+            $value = '&nbsp;';
+        }
+
+        $value .= $this->_getPersistantData();
 
-        $value =  ('' != $value ? @htmlspecialchars($value, ENT_COMPAT, HTML_Common::charset()): '&nbsp;') .
-               $this->_getPersistantData();
         return '<span class="freeze">'.$value.'</span>';
-        //
-    } //end func getFrozenHtml
+    }
 
    /**
     * Used by getFrozenHtml() to pass the element's value if _persistantFreeze is on
@@ -329,9 +325,6 @@ class HTML_QuickForm_element extends HTML_Common
         }
     }
 
-    // }}}
-    // {{{ isFrozen()
-
     /**
      * Returns whether or not the element is frozen
      *
@@ -344,9 +337,6 @@ class HTML_QuickForm_element extends HTML_Common
         return $this->_flagFrozen;
     } // end func isFrozen
 
-    // }}}
-    // {{{ setPersistantFreeze()
-
     /**
      * Sets wether an element value should be kept in an hidden field
      * when the element is frozen or not
@@ -361,9 +351,6 @@ class HTML_QuickForm_element extends HTML_Common
         $this->_persistantFreeze = $persistant;
     } //end func setPersistantFreeze
 
-    // }}}
-    // {{{ setLabel()
-
     /**
      * Sets display text for the element
      *
@@ -381,9 +368,6 @@ class HTML_QuickForm_element extends HTML_Common
         }
     } //end func setLabel
 
-    // }}}
-    // {{{ getLabel()
-
     /**
      * Returns display text for the element
      *
@@ -407,9 +391,6 @@ class HTML_QuickForm_element extends HTML_Common
         return $this->_label_for;
     } //end func getLabelFor
 
-    // }}}
-    // {{{ _findValue()
-
     /**
      * Tries to find the element value from the values array
      *
@@ -451,9 +432,6 @@ class HTML_QuickForm_element extends HTML_Common
         }
     } //end func _findValue
 
-    // }}}
-    // {{{ onQuickFormEvent()
-
     /**
      * Called by HTML_QuickForm whenever form event is made on this element
      *
@@ -547,9 +525,6 @@ class HTML_QuickForm_element extends HTML_Common
         return $this->_prepareValue($value, $assoc);
     }
 
-    // }}}
-    // {{{ _prepareValue()
-
    /**
     * Used by exportValue() to prepare the value for returning
     *

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

@@ -268,8 +268,7 @@ class HTML_QuickForm_file extends HTML_QuickForm_input
                 $image = $(\'#'.$id.'_preview_image\'),
                 $input = $(\'[name="'.$id.'_crop_result"]\'),
                 $cropButton = $(\'#'.$id.'_crop_button\'),
-                $formGroup = $(\'#'.$id.'-form-group\');
-                
+                $formGroup = $(\'#'.$id.'-form-group\');                
 
             function isValidType(file) {
                 var fileTypes = [\'image/jpg\', \'image/jpeg\', \'image/gif\', \'image/png\'];

+ 0 - 25
main/inc/lib/pear/HTML/QuickForm/input.php

@@ -1,6 +1,4 @@
 <?php
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
-
 /**
  * Base class for <input /> form elements
  *
@@ -35,8 +33,6 @@
  */
 class HTML_QuickForm_input extends HTML_QuickForm_element
 {
-    // {{{ constructor
-
     /**
      * Class constructor
      *
@@ -52,9 +48,6 @@ class HTML_QuickForm_input extends HTML_QuickForm_element
         parent::__construct($elementName, $elementLabel, $attributes);
     } //end constructor
 
-    // }}}
-    // {{{ setType()
-
     /**
      * Sets the element type
      *
@@ -69,9 +62,6 @@ class HTML_QuickForm_input extends HTML_QuickForm_element
         $this->updateAttributes(array('type'=>$type));
     } // end func setType
 
-    // }}}
-    // {{{ setName()
-
     /**
      * Sets the input field name
      *
@@ -85,9 +75,6 @@ class HTML_QuickForm_input extends HTML_QuickForm_element
         $this->updateAttributes(array('name'=>$name));
     } //end func setName
 
-    // }}}
-    // {{{ getName()
-
     /**
      * Returns the element name
      *
@@ -100,9 +87,6 @@ class HTML_QuickForm_input extends HTML_QuickForm_element
         return $this->getAttribute('name');
     } //end func getName
 
-    // }}}
-    // {{{ setValue()
-
     /**
      * Sets the value of the form element
      *
@@ -116,9 +100,6 @@ class HTML_QuickForm_input extends HTML_QuickForm_element
         $this->updateAttributes(array('value'=>$value));
     } // end func setValue
 
-    // }}}
-    // {{{ getValue()
-
     /**
      * Returns the value of the form element
      *
@@ -131,9 +112,6 @@ class HTML_QuickForm_input extends HTML_QuickForm_element
         return $this->getAttribute('value');
     } // end func getValue
 
-    // }}}
-    // {{{ toHtml()
-
     /**
      * Returns the input field in HTML
      *
@@ -150,9 +128,6 @@ class HTML_QuickForm_input extends HTML_QuickForm_element
         }
     } //end func toHtml
 
-    // }}}
-    // {{{ onQuickFormEvent()
-
     /**
      * Called by HTML_QuickForm whenever form event is made on this element
      *

+ 0 - 10
main/inc/lib/pear/HTML/QuickForm/label.php

@@ -19,8 +19,6 @@
  */
 class HTML_QuickForm_label extends HTML_QuickForm_static
 {
-    // {{{ constructor
-
     /**
      * Class constructor
      *
@@ -36,12 +34,4 @@ class HTML_QuickForm_label extends HTML_QuickForm_static
         parent::__construct(null, $label, $text, $attributes);
         $this->_type = 'html';
     }
-
-    /**
-     * @return string
-     */
-    public function toHtml()
-    {
-        return parent::toHtml();
-    }
 }

+ 0 - 4
main/inc/lib/pear/HTML/QuickForm/link.php

@@ -188,8 +188,4 @@ class HTML_QuickForm_link extends HTML_QuickForm_static
     {
         return;
     } //end func getFrozenHtml
-
-    // }}}
-
 } //end class HTML_QuickForm_textarea
-?>

+ 0 - 8
main/inc/lib/pear/HTML/QuickForm/reset.php

@@ -2,8 +2,6 @@
 
 class HTML_QuickForm_reset extends HTML_QuickForm_button
 {
-    // {{{ constructor
-
     /**
      * Class constructor
      *
@@ -22,9 +20,6 @@ class HTML_QuickForm_reset extends HTML_QuickForm_button
         $this->setType('reset');
     } //end constructor
 
-    // }}}
-    // {{{ freeze()
-
     /**
      * Freeze the element so that only its value is returned
      *
@@ -35,7 +30,4 @@ class HTML_QuickForm_reset extends HTML_QuickForm_button
     {
         return false;
     } //end func freeze
-
-    // }}}
-
 }

+ 0 - 30
main/inc/lib/pear/HTML/QuickForm/static.php

@@ -32,9 +32,6 @@
  */
 class HTML_QuickForm_static extends HTML_QuickForm_element
 {
-
-    // {{{ properties
-
     /**
      * Display text
      * @var       string
@@ -42,9 +39,6 @@ class HTML_QuickForm_static extends HTML_QuickForm_element
      */
     var $_text = null;
 
-    // }}}
-    // {{{ constructor
-
     /**
      * Class constructor
      *
@@ -61,9 +55,6 @@ class HTML_QuickForm_static extends HTML_QuickForm_element
         $this->_text = $text;
     } //end constructor
 
-    // }}}
-    // {{{ setName()
-
     /**
      * Sets the element name
      *
@@ -76,9 +67,6 @@ class HTML_QuickForm_static extends HTML_QuickForm_element
         $this->updateAttributes(array('name'=>$name));
     } //end func setName
 
-    // }}}
-    // {{{ getName()
-
     /**
      * Returns the element name
      *
@@ -90,9 +78,6 @@ class HTML_QuickForm_static extends HTML_QuickForm_element
         return $this->getAttribute('name');
     } //end func getName
 
-    // }}}
-    // {{{ setText()
-
     /**
      * Sets the text
      *
@@ -105,9 +90,6 @@ class HTML_QuickForm_static extends HTML_QuickForm_element
         $this->_text = $text;
     } // end func setText
 
-    // }}}
-    // {{{ setValue()
-
     /**
      * Sets the text (uses the standard setValue call to emulate a form element.
      *
@@ -120,9 +102,6 @@ class HTML_QuickForm_static extends HTML_QuickForm_element
         $this->setText($text);
     } // end func setValue
 
-    // }}}
-    // {{{ toHtml()
-
     /**
      * Returns the static text element in HTML
      *
@@ -134,9 +113,6 @@ class HTML_QuickForm_static extends HTML_QuickForm_element
         return $this->_getTabs() . $this->_text;
     } //end func toHtml
 
-    // }}}
-    // {{{ getFrozenHtml()
-
     /**
      * Returns the value of field without HTML tags
      *
@@ -148,9 +124,6 @@ class HTML_QuickForm_static extends HTML_QuickForm_element
         return $this->toHtml();
     } //end func getFrozenHtml
 
-    // }}}
-    // {{{ onQuickFormEvent()
-
     /**
      * Called by HTML_QuickForm whenever form event is made on this element
      *
@@ -181,9 +154,6 @@ class HTML_QuickForm_static extends HTML_QuickForm_element
         return true;
     } // end func onQuickFormEvent
 
-    // }}}
-    // {{{ exportValue()
-
    /**
     * We override this here because we don't want any values from static elements
     */

+ 2 - 9
main/inc/lib/pear/HTML/QuickForm/submit.php

@@ -34,8 +34,6 @@
  */
 class HTML_QuickForm_submit extends HTML_QuickForm_input
 {
-    // {{{ constructor
-
     /**
      * Class constructor
      *
@@ -53,9 +51,6 @@ class HTML_QuickForm_submit extends HTML_QuickForm_input
         $this->setType('submit');
     } //end constructor
 
-    // }}}
-    // {{{ freeze()
-
     /**
      * Freeze the element so that only its value is returned
      *
@@ -67,9 +62,6 @@ class HTML_QuickForm_submit extends HTML_QuickForm_input
         return false;
     } //end func freeze
 
-    // }}}
-    // {{{ exportValue()
-
    /**
     * Only return the value if it is found within $submitValues (i.e. if
     * this particular submit button was clicked)
@@ -78,4 +70,5 @@ class HTML_QuickForm_submit extends HTML_QuickForm_input
     {
         return $this->_prepareValue($this->_findValue($submitValues), $assoc);
     }
-}
+
+}

+ 3 - 26
main/inc/lib/pear/HTML/QuickForm/textarea.php

@@ -40,7 +40,7 @@ class HTML_QuickForm_textarea extends HTML_QuickForm_element
      * @since     1.0
      * @access    private
      */
-    public $_value = null;
+    public $_value;
 
     /**
      * Class constructor
@@ -62,6 +62,7 @@ class HTML_QuickForm_textarea extends HTML_QuickForm_element
         parent::__construct($elementName, $elementLabel, $attributes);
         $this->_persistantFreeze = true;
         $this->_type = 'textarea';
+        $this->_value = null;
     }
 
     /**
@@ -77,9 +78,6 @@ class HTML_QuickForm_textarea extends HTML_QuickForm_element
         $this->updateAttributes(array('name'=>$name));
     } //end func setName
 
-    // }}}
-    // {{{ getName()
-
     /**
      * Returns the element name
      *
@@ -92,9 +90,6 @@ class HTML_QuickForm_textarea extends HTML_QuickForm_element
         return $this->getAttribute('name');
     } //end func getName
 
-    // }}}
-    // {{{ setValue()
-
     /**
      * Sets value for textarea element
      *
@@ -108,9 +103,6 @@ class HTML_QuickForm_textarea extends HTML_QuickForm_element
         $this->_value = $value;
     } //end func setValue
 
-    // }}}
-    // {{{ getValue()
-
     /**
      * Returns the value of the form element
      *
@@ -123,9 +115,6 @@ class HTML_QuickForm_textarea extends HTML_QuickForm_element
         return $this->_value;
     } // end func getValue
 
-    // }}}
-    // {{{ setWrap()
-
     /**
      * Sets wrap type for textarea element
      *
@@ -139,9 +128,6 @@ class HTML_QuickForm_textarea extends HTML_QuickForm_element
         $this->updateAttributes(array('wrap' => $wrap));
     } //end func setWrap
 
-    // }}}
-    // {{{ setRows()
-
     /**
      * Sets height in rows for textarea element
      *
@@ -155,9 +141,6 @@ class HTML_QuickForm_textarea extends HTML_QuickForm_element
         $this->updateAttributes(array('rows' => $rows));
     } //end func setRows
 
-    // }}}
-    // {{{ setCols()
-
     /**
      * Sets width in cols for textarea element
      *
@@ -171,9 +154,6 @@ class HTML_QuickForm_textarea extends HTML_QuickForm_element
         $this->updateAttributes(array('cols' => $cols));
     } //end func setCols
 
-    // }}}
-    // {{{ toHtml()
-
     /**
      * Returns the textarea element in HTML
      *
@@ -206,10 +186,7 @@ class HTML_QuickForm_textarea extends HTML_QuickForm_element
      */
     public function getFrozenHtml()
     {
-        // Modified by Ivan Tcholakov, 16-MAR-2010.
-        //$value = htmlspecialchars($this->getValue());
-        $value = @htmlspecialchars($this->getValue(), ENT_COMPAT, HTML_Common::charset());
-        //
+        $value = $this->getCleanValue();
         if ($this->getAttribute('wrap') == 'off') {
             $html = $this->_getTabs() . '<pre>' . $value."</pre>\n";
         } else {

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

@@ -320,8 +320,11 @@ class SocialManager extends UserManager
                     msg_status='.MESSAGE_STATUS_INVITATION_PENDING;
         $res = Database::query($sql);
         $row = Database::fetch_array($res, 'ASSOC');
+        if ($row) {
+            return (int) $row['count_message_in_box'];
+        }
 
-        return $row['count_message_in_box'];
+        return 0;
     }
 
     /**

+ 8 - 2
main/inc/lib/userportal.lib.php

@@ -827,6 +827,7 @@ class IndexManager
                 'link' => api_get_path(WEB_PATH).'main/messages/inbox.php',
                 'title' => get_lang('Inbox').$cant_msg,
             ];
+
             $items[] = [
                 'class' => 'new-message-social',
                 'icon' => Display::return_icon('new-message.png', get_lang('Compose')),
@@ -842,6 +843,13 @@ class IndexManager
                     'link' => api_get_path(WEB_PATH).'main/social/invitations.php',
                     'title' => get_lang('PendingInvitations').$total_invitations,
                 ];
+            } else {
+                $items[] = [
+                    'class' => 'personal-data',
+                    'icon' => Display::return_icon('database.png', get_lang('PersonalDataReport')),
+                    'link' => api_get_path(WEB_CODE_PATH).'social/personal_data.php',
+                    'title' => get_lang('PersonalDataReport'),
+                ];
             }
 
             if (api_get_configuration_value('allow_my_files_link_in_homepage')) {
@@ -889,7 +897,6 @@ class IndexManager
         }
 
         if (true === api_get_configuration_value('whispeak_auth_enabled')) {
-            //if (!WhispeakAuthPlugin::checkUserIsEnrolled($userId)) {
             $itemTitle = WhispeakAuthPlugin::create()->get_title();
 
             $items[] = [
@@ -898,7 +905,6 @@ class IndexManager
                 'link' => WhispeakAuthPlugin::getEnrollmentUrl(),
                 'title' => $itemTitle,
             ];
-            //}
         }
 
         return $items;

+ 15 - 6
main/inc/lib/zombie/zombie_manager.class.php

@@ -28,8 +28,14 @@ class ZombieManager
      *
      * @return ResultSet
      */
-    public static function listZombies($ceiling, $active_only = true, $count = 0, $from = 10, $column = 'user.firstname', $direction = 'desc')
-    {
+    public static function listZombies(
+        $ceiling,
+        $active_only = true,
+        $from = 0,
+        $count = 10,
+        $column = 'user.firstname',
+        $direction = 'desc'
+    ) {
         if (empty($column)) {
             $column = 'user.firstname';
         }
@@ -41,6 +47,7 @@ class ZombieManager
 
         $sql = 'SELECT
                     user.user_id,
+                    user.official_code,
                     user.firstname,
                     user.lastname,
                     user.username,
@@ -74,15 +81,17 @@ class ZombieManager
                         access.login_date <= '$ceiling' AND
                         user.user_id = access.login_user_id";
         }
+
         if ($active_only) {
             $sql .= ' AND user.active = 1';
         }
 
+        $sql .= " ORDER BY $column $direction";
+        if (!is_null($from) && !is_null($count)) {
         $count = intval($count);
         $from = intval($from);
-
-        $sql .= " ORDER BY $column $direction";
-        $sql .= " LIMIT $count, $from ";
+            $sql .= " LIMIT $from, $count ";
+        }
 
         $result = Database::query($sql);
 
@@ -94,7 +103,7 @@ class ZombieManager
      */
     public static function deactivate_zombies($ceiling)
     {
-        $zombies = self::list_zombies($ceiling);
+        $zombies = self::listZombies($ceiling);
         $ids = [];
         foreach ($zombies as $zombie) {
             $ids[] = $zombie['user_id'];

+ 42 - 72
main/inc/lib/zombie/zombie_report.class.php

@@ -34,9 +34,6 @@ class ZombieReport implements Countable
     public function get_parameters()
     {
         $result = [
-            'name' => 'zombie_report_parameters',
-            'method' => 'GET',
-            'attributes' => ['class' => 'well form-horizontal form-search'],
             'items' => [
                 [
                     'name' => 'ceiling',
@@ -44,10 +41,6 @@ class ZombieReport implements Countable
                     'type' => 'date_picker',
                     'default' => $this->get_ceiling('Y-m-d'),
                     'rules' => [
-//                        array(
-//                            'type' => 'required',
-//                            'message' => get_lang('Required')
-//                        ),
                         [
                             'type' => 'date',
                             'message' => get_lang('Date'),
@@ -68,14 +61,6 @@ class ZombieReport implements Countable
                 ],
             ],
         ];
-        $additional_parameters = $this->get_additional_parameters();
-        foreach ($additional_parameters as $key => $value) {
-            $result['items'][] = [
-                'type' => 'hidden',
-                'name' => $key,
-                'value' => $value,
-            ];
-        }
 
         return $result;
     }
@@ -85,31 +70,37 @@ class ZombieReport implements Countable
      */
     public function get_parameters_form()
     {
-        $parameters = $this->get_parameters();
-        if (empty($parameters)) {
-            return null;
-        }
-        if (empty($this->parameters_form)) {
-            $this->parameters_form = new FormValidator(
-                $parameters['name'],
-                $parameters['method'],
+        $form = new FormValidator(
+            'zombie_report_parameters',
+            'get',
                 null,
                 null,
-                $parameters['attributes']
+            ['class' => 'well form-horizontal form-search']
             );
+
+        $form->addDatePicker('ceiling', get_lang('LastAccess'));
+        $form->addCheckBox('active_only', get_lang('ActiveOnly'));
+        $form->addButtonSearch(get_lang('Search'));
+
+        $params = [
+            'active_only' => $this->get_active_only(),
+            'ceiling' => $this->get_ceiling('Y-m-d'),
+        ];
+        $form->setDefaults($params);
+        $additional = $this->get_additional_parameters();
+        foreach ($additional as $key => $value) {
+            $value = Security::remove_XSS($value);
+            $form->addHidden($key, $value);
         }
 
-        return $this->parameters_form;
+        return $form;
     }
 
     public function display_parameters($return = false)
     {
         $form = $this->get_parameters_form();
-        if (empty($form)) {
-            return '';
-        }
-
         $result = $form->returnForm();
+
         if ($return) {
             return $result;
         } else {
@@ -120,9 +111,6 @@ class ZombieReport implements Countable
     public function is_valid()
     {
         $form = $this->get_parameters_form();
-        if (empty($form)) {
-            return true;
-        }
 
         return $form->isSubmitted() == false || $form->validate();
     }
@@ -175,57 +163,39 @@ class ZombieReport implements Countable
         }
 
         $action = $this->get_action();
-        $f = [$this, 'action_'.$action];
-        if (is_callable($f)) {
-            return call_user_func($f, $ids);
+        switch ($action) {
+            case 'activate':
+                return UserManager::activate_users($ids);
+                break;
+            case 'deactivate':
+                return UserManager::deactivate_users($ids);
+                break;
+            case 'delete':
+                return UserManager::delete_users($ids);
         }
 
         return false;
     }
 
-    public function action_deactivate($ids)
-    {
-        return UserManager::deactivate_users($ids);
-    }
-
-    public function action_activate($ids)
-    {
-        return UserManager::activate_users($ids);
-    }
-
-    public function action_delete($ids)
-    {
-        return UserManager::delete_users($ids);
-    }
-
     public function count()
     {
-        if (!$this->is_valid()) {
-            return 0;
-        }
-
         $ceiling = $this->get_ceiling();
         $active_only = $this->get_active_only();
-        $items = ZombieManager::listZombies($ceiling, $active_only);
+        $items = ZombieManager::listZombies($ceiling, $active_only, null, null);
 
         return count($items);
     }
 
     public function get_data($from, $count, $column, $direction)
     {
-        if (!$this->is_valid()) {
-            return [];
-        }
-
         $ceiling = $this->get_ceiling();
         $active_only = $this->get_active_only();
-
-        $items = ZombieManager::listZombies($ceiling, $active_only, $count, $from, $column, $direction);
+        $items = ZombieManager::listZombies($ceiling, $active_only, $from, $count, $column, $direction);
         $result = [];
         foreach ($items as $item) {
             $row = [];
             $row[] = $item['user_id'];
-            $row[] = $item['code'];
+            $row[] = $item['official_code'];
             $row[] = $item['firstname'];
             $row[] = $item['lastname'];
             $row[] = $item['username'];
@@ -253,12 +223,12 @@ class ZombieReport implements Countable
         $additional_parameters = $this->get_additional_parameters();
         $parameters = array_merge($additional_parameters, $parameters);
 
-        $table = new SortableTable('users', $count, $data, 1, 50);
+        $table = new SortableTable('zombie_users', $count, $data, 1, 50);
         $table->set_additional_parameters($parameters);
 
         $col = 0;
         $table->set_header($col++, '', false);
-        $table->set_header($col++, get_lang('Code'));
+        $table->set_header($col++, get_lang('OfficialCode'));
         $table->set_header($col++, get_lang('FirstName'));
         $table->set_header($col++, get_lang('LastName'));
         $table->set_header($col++, get_lang('LoginName'));
@@ -267,7 +237,7 @@ class ZombieReport implements Countable
         $table->set_header($col++, get_lang('AuthenticationSource'));
         $table->set_header($col++, get_lang('RegisteredDate'));
         $table->set_header($col++, get_lang('LastAccess'), false);
-        $table->set_header($col++, get_lang('Active'), false);
+        $table->set_header($col, get_lang('Active'), false);
 
         $table->set_column_filter(5, [$this, 'format_email']);
         $table->set_column_filter(6, [$this, 'format_status']);
@@ -295,7 +265,7 @@ class ZombieReport implements Countable
      */
     public function format_active($active)
     {
-        $active = ($active == '1');
+        $active = $active == '1';
         if ($active) {
             $image = 'accept';
             $text = get_lang('Yes');
@@ -324,14 +294,14 @@ class ZombieReport implements Countable
     public function display($return = false)
     {
         $result = $this->display_parameters($return);
-        if ($this->perform_action()) {
-            if ($return) {
-                $result .= Display::return_message(get_lang('Done'), 'confirmation');
-            } else {
-                echo Display::return_message(get_lang('Done'), 'confirmation');
-            }
+        $valid = $this->perform_action();
+
+        if ($valid) {
+            echo Display::return_message(get_lang('Updated'), 'confirmation');
         }
+
         $result .= $this->display_data($return);
+
         if ($return) {
             return $result;
         }

+ 78 - 38
main/install/install.lib.php

@@ -429,6 +429,8 @@ function write_system_config_file($path)
                 Your problems can be related on two possible causes:<br />
                 <ul>
                   <li>Permission problems.<br />Try initially with <em>chmod -R 777</em> and increase restrictions gradually.</li>
+                  <li>PHP is running in <a href="http://www.php.net/manual/en/features.safe-mode.php" target="_blank">Safe-Mode</a>. 
+                  If possible, try to switch it off.</li>
                 </ul>
                 <a href="http://forum.chamilo.org/" target="_blank">Read about this problem in Support Forum</a><br /><br />
                 Please go back to step 5.
@@ -577,6 +579,8 @@ function get_config_param($param, $updatePath = '')
  */
 function get_config_param_from_db($param = '')
 {
+    $param = Database::escape_string($param);
+
     if (($res = Database::query("SELECT * FROM settings_current WHERE variable = '$param'")) !== false) {
         if (Database::num_rows($res) > 0) {
             $row = Database::fetch_array($res);
@@ -1960,12 +1964,17 @@ function updateDirAndFilesPermissions()
     $permissions_for_new_directories = isset($_SESSION['permissions_for_new_directories']) ? $_SESSION['permissions_for_new_directories'] : 0770;
     $permissions_for_new_files = isset($_SESSION['permissions_for_new_files']) ? $_SESSION['permissions_for_new_files'] : 0660;
     // use decoct() to store as string
-    $sql = "UPDATE $table SET selected_value = '0".decoct($permissions_for_new_directories)."'
-              WHERE variable  = 'permissions_for_new_directories'";
-    Database::query($sql);
+    Database::update(
+        $table,
+        ['selected_value' => '0'.decoct($permissions_for_new_directories)],
+        ['variable = ?' => 'permissions_for_new_directories']
+    );
 
-    $sql = "UPDATE $table SET selected_value = '0".decoct($permissions_for_new_files)."' WHERE variable  = 'permissions_for_new_files'";
-    Database::query($sql);
+    Database::update(
+        $table,
+        ['selected_value' => '0'.decoct($permissions_for_new_files)],
+        ['variable = ?' => 'permissions_for_new_files']
+    );
 
     if (isset($_SESSION['permissions_for_new_directories'])) {
         unset($_SESSION['permissions_for_new_directories']);
@@ -2324,9 +2333,8 @@ function fixIds(EntityManager $em)
 
     // Delete group data of groups that don't exist.
     $sql = "DELETE FROM c_item_property
-            WHERE to_group_id IS NOT NULL AND to_group_id NOT IN (SELECT DISTINCT id FROM c_group_info)";
+            WHERE to_group_id <> 0 AND to_group_id IS NOT NULL AND to_group_id NOT IN (SELECT DISTINCT iid FROM c_group_info)";
     $connection->executeQuery($sql);
-
     // This updates the group_id with c_group_info.iid instead of c_group_info.id
 
     if ($debug) {
@@ -2399,7 +2407,8 @@ function fixIds(EntityManager $em)
             $ref = $item['ref'];
 
             // Fix group id
-            if (!empty($groupId)) {
+            // Commented group id is already fixed in Version20150603181728.php
+            /*if (!empty($groupId)) {
                 $sql = "SELECT * FROM c_group_info
                         WHERE c_id = $courseId AND id = $groupId";
                 $data = $connection->fetchAssoc($sql);
@@ -2413,7 +2422,7 @@ function fixIds(EntityManager $em)
                     $sql = "DELETE FROM c_item_property WHERE iid = $iid";
                     $connection->executeQuery($sql);
                 }
-            }
+            }*/
 
             $sql = '';
             $newId = '';
@@ -3259,9 +3268,7 @@ function finishInstallationWithContainer(
 
     $manager = Database::getManager();
     $connection = $manager->getConnection();
-
     $sql = getVersionTable();
-
     // Add version table
     $connection->executeQuery($sql);
 
@@ -3412,8 +3419,11 @@ function finishInstallationWithContainer(
     );
 
     // Set default language
-    $sql = "UPDATE language SET available = 1 WHERE dokeos_folder = '$languageForm'";
-    Database::query($sql);
+    Database::update(
+        Database::get_main_table(TABLE_MAIN_LANGUAGE),
+        ['available' => 1],
+        ['dokeos_folder = ?' => $languageForm]
+    );
 
     // Install settings
     installSettings(
@@ -3502,14 +3512,21 @@ function installProfileSettings($installationProfile = '')
     if (!empty($params->parent)) {
         installProfileSettings($params->parent);
     }
+
+    $tblSettings = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
+
     foreach ($settings as $id => $param) {
-        $sql = "UPDATE settings_current
-                SET selected_value = '".$param->selected_value."'
-                WHERE variable = '".$param->variable."'";
+        $conditions = ['variable = ? ' => $param->variable];
+
         if (!empty($param->subkey)) {
-            $sql .= " AND subkey='".$param->subkey."'";
+            $conditions['AND subkey = ? '] = $param->subkey;
         }
-        Database::query($sql);
+
+        Database::update(
+            $tblSettings,
+            ['selected_value' => $param->selected_value],
+            $conditions
+        );
     }
 
     return true;
@@ -3538,6 +3555,16 @@ function rrmdir($dir)
     }
 }
 
+/**
+ * @param        $id
+ * @param string $type
+ * @param bool   $preview
+ * @param bool   $anonymous
+ *
+ * @throws \Doctrine\DBAL\DBALException
+ *
+ * @return array
+ */
 function get_group_picture_path_by_id($id, $type = 'web', $preview = false, $anonymous = false)
 {
     switch ($type) {
@@ -3596,6 +3623,8 @@ function get_group_picture_path_by_id($id, $type = 'web', $preview = false, $ano
  * @param EntityManager $manager
  * @param bool          $processFiles
  *
+ * @throws \Doctrine\DBAL\DBALException
+ *
  * @return bool Always returns true except if the process is broken
  */
 function migrateSwitch($fromVersion, $manager, $processFiles = true)
@@ -3668,7 +3697,6 @@ function migrateSwitch($fromVersion, $manager, $processFiles = true)
         case '1.10.2':
         case '1.10.4':
         case '1.10.6':
-        case '1.10.8':
         case '1.10.8':
             $database = new Database();
             $database->setManager($manager);
@@ -3735,6 +3763,8 @@ function migrateSwitch($fromVersion, $manager, $processFiles = true)
 
 /**
  * @param \Doctrine\DBAL\Connection $connection
+ *
+ * @throws \Doctrine\DBAL\DBALException
  */
 function fixPostGroupIds($connection)
 {
@@ -3790,26 +3820,36 @@ function fixPostGroupIds($connection)
         $courseId = $row['c_id'];
         $sessionId = $row['session_id'];
         $workId = $row['id'];
-        $itemInfo = api_get_item_property_info(
-            $courseId,
-            'work',
-            $workId,
-            $sessionId
-        );
-        $courseInfo = api_get_course_info_by_id($courseId);
+        $sessionCondition = " session_id = $sessionId";
+        if (empty($sessionId)) {
+            $sessionCondition = ' (session_id = 0 OR session_id IS NULL) ';
+        }
+        $sql = "SELECT * FROM c_item_property
+                WHERE
+                    c_id = $courseId AND
+                    tool = 'work' AND
+                    ref = $workId AND
+                    $sessionCondition ";
+        $itemInfo = $connection->fetchAssoc($sql);
         if (empty($itemInfo)) {
-            api_item_property_update(
-                $courseInfo,
-                'work',
-                $workId,
-                'visible',
-                1,
-                $groupId,
-                null,
-                null,
-                null,
-                $sessionId
-            );
+            $params = [
+                'c_id' => $courseId,
+                'to_group_id' => $groupId,
+                //'to_user_id' => null,
+                'insert_user_id' => 1,
+                'session_id' => $sessionId,
+                'tool' => 'work',
+                'insert_date' => api_get_utc_datetime(),
+                'lastedit_date' => api_get_utc_datetime(),
+                'ref' => $workId,
+                'lastedit_type' => 'visible',
+                'lastedit_user_id' => 1,
+                'visibility' => 1,
+            ];
+            $connection->insert('c_item_property', $params);
+            $id = $connection->lastInsertId();
+            $sql = "UPDATE c_item_property SET id = iid WHERE iid = $id";
+            $connection->executeQuery($sql);
         }
     }
     error_log('End - Fix work documents');

+ 12 - 7
main/lp/learnpath.class.php

@@ -5,6 +5,7 @@ use Chamilo\CoreBundle\Repository\CourseRepository;
 use Chamilo\CourseBundle\Component\CourseCopy\CourseArchiver;
 use Chamilo\CourseBundle\Component\CourseCopy\CourseBuilder;
 use Chamilo\CourseBundle\Component\CourseCopy\CourseRestorer;
+use Chamilo\CourseBundle\Entity\CDocument;
 use Chamilo\CourseBundle\Entity\CItemProperty;
 use Chamilo\CourseBundle\Entity\CLp;
 use Chamilo\CourseBundle\Entity\CLpCategory;
@@ -3671,7 +3672,6 @@ class learnpath
                             }
 
                             $type_quiz = false;
-
                             foreach ($list as $toc) {
                                 if ($toc['id'] == $lp_item_id && ($toc['type'] == 'quiz')) {
                                     $type_quiz = true;
@@ -3705,7 +3705,6 @@ class learnpath
                     if (strpos($document_name, '_DELETED_')) {
                         $file = 'blank.php?error=document_deleted';
                     }
-
                     break;
                 case 2:
                     if ($this->debug > 2) {
@@ -6259,10 +6258,14 @@ class learnpath
             if (file_exists($iconPath.'lp_'.$icon_name.'.png')) {
                 $icon = Display::return_icon('lp_'.$icon_name.'.png');
             } else {
-                if ($arrLP[$i]['item_type'] === TOOL_LP_FINAL_ITEM) {
-                    $icon = Display::return_icon('certificate.png');
+                if (file_exists($iconPath.'lp_'.$icon_name.'.gif')) {
+                    $icon = Display::return_icon('lp_'.$icon_name.'.gif');
                 } else {
-                    $icon = Display::return_icon('folder_document.png');
+                    if ($arrLP[$i]['item_type'] === TOOL_LP_FINAL_ITEM) {
+                        $icon = Display::return_icon('certificate.png');
+                    } else {
+                        $icon = Display::return_icon('folder_document.png');
+                    }
                 }
             }
 
@@ -10216,8 +10219,10 @@ class learnpath
     public function display_item_prerequisites_form($item_id = 0)
     {
         $course_id = api_get_course_int_id();
+        $item_id = (int) $item_id;
+
         $tbl_lp_item = Database::get_course_table(TABLE_LP_ITEM);
-        $item_id = intval($item_id);
+
         /* Current prerequisite */
         $sql = "SELECT * FROM $tbl_lp_item
                 WHERE iid = $item_id";
@@ -12513,7 +12518,7 @@ EOD;
             $link = 'lp/lp_controller.php?cidReq='.$courseInfo['code'].'&id_session='.$sessionId.'&gidReq=0&gradebook=0&origin=&action=view_category&id='.$id;
             // Delete tools
             $sql = "DELETE FROM $tbl_tool
-                    WHERE c_id = ".$courseId." AND (link LIKE '$link%' AND image LIKE 'lp_category.%')";
+                    WHERE c_id = ".$courseId." AND (link LIKE '$link%' AND image='lp_category.gif')";
             Database::query($sql);
         }
     }

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

@@ -2495,8 +2495,18 @@ class learnpathItem
                                                         LIMIT 0, 1';
                                                 $rs_quiz = Database::query($sql);
                                                 if ($quiz = Database::fetch_array($rs_quiz)) {
-                                                    $minScore = $items[$refs_list[$this->get_id()]]->getPrerequisiteMinScore();
-                                                    $maxScore = $items[$refs_list[$this->get_id()]]->getPrerequisiteMaxScore();
+                                                    /** @var learnpathItem $myItemToCheck */
+                                                    $myItemToCheck = $items[$refs_list[$this->get_id()]];
+                                                    $minScore = $myItemToCheck->getPrerequisiteMinScore();
+                                                    $maxScore = $myItemToCheck->getPrerequisiteMaxScore();
+
+                                                    if (empty($minScore)) {
+                                                        // Try with mastery_score
+                                                        $masteryScoreAsMin = $myItemToCheck->get_mastery_score();
+                                                        if (!empty($masteryScoreAsMin)) {
+                                                            $minScore = $masteryScoreAsMin;
+                                                        }
+                                                    }
 
                                                     if (isset($minScore) && isset($minScore)) {
                                                         // Taking min/max prerequisites values see BT#5776
@@ -2547,8 +2557,18 @@ class learnpathItem
                                             $rs_quiz = Database::query($sql);
                                             if (Database::num_rows($rs_quiz) > 0) {
                                                 while ($quiz = Database::fetch_array($rs_quiz)) {
-                                                    $minScore = $items[$refs_list[$this->get_id()]]->getPrerequisiteMinScore();
-                                                    $maxScore = $items[$refs_list[$this->get_id()]]->getPrerequisiteMaxScore();
+                                                    /** @var learnpathItem $myItemToCheck */
+                                                    $myItemToCheck = $items[$refs_list[$this->get_id()]];
+                                                    $minScore = $myItemToCheck->getPrerequisiteMinScore();
+                                                    $maxScore = $myItemToCheck->getPrerequisiteMaxScore();
+
+                                                    if (empty($minScore)) {
+                                                        // Try with mastery_score
+                                                        $masteryScoreAsMin = $myItemToCheck->get_mastery_score();
+                                                        if (!empty($masteryScoreAsMin)) {
+                                                            $minScore = $masteryScoreAsMin;
+                                                        }
+                                                    }
 
                                                     if (isset($minScore) && isset($minScore)) {
                                                         // Taking min/max prerequisites values see BT#5776

+ 0 - 1
main/lp/lp_add_item.php

@@ -24,7 +24,6 @@ $lpId = isset($_REQUEST['lp_id']) ? (int) $_REQUEST['lp_id'] : 0;
 $submit = isset($_POST['submit_button']) ? $_POST['submit_button'] : null;
 $type = isset($_GET['type']) ? $_GET['type'] : null;
 $action = isset($_GET['action']) ? $_GET['action'] : null;
-
 $is_allowed_to_edit = api_is_allowed_to_edit(null, false);
 
 $listUrl = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?action=view&lp_id='.$lpId.'&'.api_get_cidreq().'&isStudentView=true';

+ 2 - 0
main/lp/scorm_api.php

@@ -1692,6 +1692,8 @@ function switch_item(current_item, next_item) {
             if ($("#lp_media_file").length != 0) {
                 $("#lp_media_file").html(tmp_data);
             }
+
+            LPViewUtils.setHeightLPToc();
         }
     });
 

+ 0 - 1
main/messages/inbox.php

@@ -26,7 +26,6 @@ if (isset($_GET['messages_page_nr'])) {
 
 $nameTools = get_lang('Messages');
 $show_message = null;
-
 if (isset($_GET['form_reply']) || isset($_GET['form_delete'])) {
     $info_reply = [];
     $info_delete = [];

+ 5 - 1
main/mySpace/exercise_category_report.php

@@ -94,7 +94,11 @@ if ($form->validate() && !empty($courseInfo)) {
     $exerciseId = isset($values['exercise_id']) ? $values['exercise_id'] : 0;
     $startDate = Security::remove_XSS($values['start_date']);
     $exportFilename = 'exercise_results_report_'.$exerciseId.'_'.$courseInfo['code'];
-    $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_exercise_results_report&exercise_id='.$exerciseId.'&start_date='.$startDate.'&cidReq='.$courseInfo['code'].'&export_filename='.$exportFilename;
+    $url = api_get_path(WEB_AJAX_PATH).
+        'model.ajax.php?a=get_exercise_results_report&exercise_id='.$exerciseId.
+        '&start_date='.$startDate.'&cidReq='.$courseInfo['code'].
+        '&course_id='.$courseId.
+        '&export_filename='.$exportFilename;
 
     $categoryList = TestCategory::getListOfCategoriesIDForTest($exerciseId, $courseId);
     $columns = [

+ 1 - 1
main/mySpace/lp_tracking.php

@@ -90,7 +90,7 @@ $actions[] = Display::url(
 );
 $actions[] = Display::url(
     Display::return_icon('printer.png', get_lang('Print'), '', ICON_SIZE_MEDIUM),
-    'window.print();'
+    'javascript:window.print();'
 );
 $actions[] = Display::url(
     Display::return_icon('export_csv.png', get_lang('ExportAsCSV'), '', ICON_SIZE_MEDIUM),

+ 0 - 1
main/social/personal_data.php

@@ -51,7 +51,6 @@ if (api_get_setting('allow_terms_conditions') === 'true') {
     $formDelete->addButtonDelete(get_lang('DeleteAccount'));
     $formToString .= $formDelete->returnForm();
 }
-
 switch ($action) {
     case 'send_legal':
         $language = api_get_interface_language();

+ 1 - 1
main/survey/create_meeting.php

@@ -68,7 +68,7 @@ $hideList = '';
 $maxEvents = 20;
 for ($i = 1; $i <= $maxEvents; $i++) {
     $name = 'time_'.$i;
-    $form->addDateTimeRangePicker($name, get_lang('Time'));
+    $form->addDateTimeRangePicker($name, get_lang('Date'));
     if ($i > 3) {
         $hideList .= "$('#".$name."_alt').parent().parent().parent().hide();";
     }

+ 0 - 1
main/survey/reporting.php

@@ -76,7 +76,6 @@ if (!empty($exportReport) && !empty($format)) {
                 $userId
             );
             $filename = 'survey_results_'.$survey_id.'.csv';
-
             header('Content-type: application/octet-stream');
             header('Content-Type: application/force-download');
 

+ 7 - 2
main/survey/surveyUtil.class.php

@@ -107,7 +107,6 @@ class SurveyUtil
         if (empty($question_id)) {
             return false;
         }
-
         // Table definition
         $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
 
@@ -1554,8 +1553,12 @@ class SurveyUtil
                     count(options.question_option_id) as number_of_options
 				FROM $table_survey_question questions
 				LEFT JOIN $table_survey_question_option options
-                ON questions.question_id = options.question_id AND options.c_id = questions.c_id
+                ON 
+                  questions.question_id = options.question_id AND 
+                  options.c_id = questions.c_id
 				WHERE
+				    survey_question NOT LIKE '%{{%' AND
+				    questions.type <> 'pagebreak' AND
 				    questions.survey_id = $surveyId AND
 				    questions.c_id = $course_id
 				GROUP BY questions.question_id
@@ -1620,6 +1623,8 @@ class SurveyUtil
 				    survey_question.question_id = survey_question_option.question_id AND 
 				    survey_question_option.c_id = survey_question.c_id
 				WHERE 
+				    survey_question NOT LIKE '%{{%' AND
+				    survey_question.type <> 'pagebreak' AND
 				    survey_question.survey_id = $surveyId AND
 				    survey_question.c_id = $course_id
 				ORDER BY survey_question.sort ASC, survey_question_option.sort ASC";

+ 8 - 3
main/work/add_document.php

@@ -60,11 +60,12 @@ if (empty($docId)) {
     if (!empty($documents)) {
         echo Display::page_subheader(get_lang('DocumentsAdded'));
         echo '<div class="well">';
+        $urlDocument = api_get_path(WEB_CODE_PATH).'work/add_document.php';
         foreach ($documents as $doc) {
             $documentId = $doc['document_id'];
             $docData = DocumentManager::get_document_data_by_id($documentId, $courseInfo['code']);
             if ($docData) {
-                $url = api_get_path(WEB_CODE_PATH).'work/add_document.php?action=delete&id='.$workId.'&document_id='.$documentId.'&'.api_get_cidreq();
+                $url = $urlDocument.'?action=delete&id='.$workId.'&document_id='.$documentId.'&'.api_get_cidreq();
                 $link = Display::url(get_lang('Remove'), $url, ['class' => 'btn btn-danger']);
                 echo $docData['title'].' '.$link.'<br />';
             }
@@ -74,12 +75,16 @@ if (empty($docId)) {
 
     $documentTree = DocumentManager::get_document_preview(
         $courseInfo,
-        null,
+        false,
         null,
         api_get_session_id(),
         false,
         '/',
-        api_get_path(WEB_CODE_PATH).'work/add_document.php?id='.$workId.'&'.api_get_cidreq()
+        api_get_path(WEB_CODE_PATH).'work/add_document.php?id='.$workId.'&'.api_get_cidreq(),
+        false,
+        false,
+        false,
+        false
     );
     echo Display::page_subheader(get_lang('Documents'));
     echo $documentTree;

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů