Ver Fonte

merge from 1.11.x

jmontoya há 9 anos atrás
pai
commit
805ec2e50b
75 ficheiros alterados com 4221 adições e 253 exclusões
  1. 11 10
      .travis.yml
  2. 51 6
      app/Resources/public/css/base.css
  3. 1 1
      custompages/first_login-dist.php
  4. 33 0
      documentation/changelog.html
  5. 3 2
      main/admin/user_move_stats.php
  6. 2 1
      main/auth/cas/lib/CAS/PGTStorage/pgt-db.php
  7. 1 0
      main/auth/shibboleth/test/shibboleth_test.class.php
  8. 2 2
      main/course_home/course_home.php
  9. BIN
      main/default_course_document/images/mr_chamilo/assistance.png
  10. BIN
      main/default_course_document/images/mr_chamilo/collaborative.png
  11. BIN
      main/default_course_document/images/mr_chamilo/doubts.png
  12. BIN
      main/default_course_document/images/mr_chamilo/gotowork.png
  13. BIN
      main/default_course_document/images/mr_chamilo/idea.png
  14. BIN
      main/default_course_document/images/mr_chamilo/navigate_computer.png
  15. BIN
      main/default_course_document/images/mr_chamilo/optimistic.png
  16. BIN
      main/default_course_document/images/mr_chamilo/optimistic_woman.png
  17. BIN
      main/default_course_document/images/mr_chamilo/practicing.png
  18. BIN
      main/default_course_document/images/mr_chamilo/reading.png
  19. BIN
      main/default_course_document/images/mr_chamilo/results.png
  20. 224 0
      main/default_course_document/images/mr_chamilo/svg/assistance.svg
  21. 323 0
      main/default_course_document/images/mr_chamilo/svg/collaborative.svg
  22. 258 0
      main/default_course_document/images/mr_chamilo/svg/doubts.svg
  23. 206 0
      main/default_course_document/images/mr_chamilo/svg/gotowork.svg
  24. 227 0
      main/default_course_document/images/mr_chamilo/svg/idea.svg
  25. 214 0
      main/default_course_document/images/mr_chamilo/svg/navigate_computer.svg
  26. 233 0
      main/default_course_document/images/mr_chamilo/svg/optimistic.svg
  27. 349 0
      main/default_course_document/images/mr_chamilo/svg/optimistic_woman.svg
  28. 396 0
      main/default_course_document/images/mr_chamilo/svg/practicing.svg
  29. 377 0
      main/default_course_document/images/mr_chamilo/svg/reading.svg
  30. 322 0
      main/default_course_document/images/mr_chamilo/svg/results.svg
  31. 439 0
      main/default_course_document/images/mr_chamilo/svg/teaching.svg
  32. 188 0
      main/default_course_document/images/mr_chamilo/svg/writing.svg
  33. BIN
      main/default_course_document/images/mr_chamilo/teaching.png
  34. BIN
      main/default_course_document/images/mr_chamilo/writing.png
  35. 21 9
      main/document/document.php
  36. 11 8
      main/document/slideshow.php
  37. 6 1
      main/document/upload.php
  38. 1 1
      main/dropbox/dropbox_functions.inc.php
  39. 14 12
      main/exercice/exercise_submit.php
  40. 9 0
      main/exercice/exercise_submit_modal.php
  41. 1 1
      main/exercice/hotspot.class.php
  42. 2 2
      main/forum/editpost.php
  43. 7 14
      main/forum/editthread.php
  44. 3 1
      main/forum/forumfunction.inc.php
  45. 3 3
      main/forum/forumqualify.php
  46. 4 9
      main/forum/newthread.php
  47. 34 76
      main/forum/viewforum.php
  48. 1 1
      main/forum/viewpost.php
  49. 4 4
      main/forum/viewthread.php
  50. 4 1
      main/forum/viewthread_flat.inc.php
  51. 4 0
      main/forum/viewthread_nested.inc.php
  52. 2 3
      main/group/member_settings.php
  53. 8 8
      main/group/settings.php
  54. 21 17
      main/group/tutor_settings.php
  55. 2 2
      main/inc/lib/add_course.lib.inc.php
  56. 1 0
      main/inc/lib/api.lib.php
  57. 5 5
      main/inc/lib/formvalidator/FormValidator.class.php
  58. 1 1
      main/inc/lib/groupmanager.lib.php
  59. 6 2
      main/inc/lib/sub_language.class.php
  60. 1 1
      main/inc/lib/usermanager.lib.php
  61. 11 3
      main/lang/brazilian/trad4all.inc.php
  62. 1 1
      main/lang/bulgarian/trad4all.inc.php
  63. 2 1
      main/lang/english/trad4all.inc.php
  64. 2 0
      main/lang/french/trad4all.inc.php
  65. 1 0
      main/lang/japanese/trad4all.inc.php
  66. 1 1
      main/lang/russian/trad4all.inc.php
  67. 2 1
      main/lang/simpl_chinese/trad4all.inc.php
  68. 1 0
      main/lang/spanish/trad4all.inc.php
  69. 4 4
      main/newscorm/lp_view_item.php
  70. 4 0
      main/template/default/agenda/month.tpl
  71. 5 1
      main/template/default/layout/head.tpl
  72. 18 24
      main/user/user.php
  73. 30 6
      main/webservices/registration.soap.php
  74. 92 3
      tests/datafiller/data_courses.php
  75. 11 4
      tests/datafiller/fill_courses.php

+ 11 - 10
.travis.yml

@@ -3,7 +3,7 @@ sudo: required
 language: php
 
 php:
-  - 5.4
+  #- 5.4 // Removed because of Chash dependencies on PHP 5.5
   - 5.5
   - 5.6
 
@@ -29,20 +29,21 @@ before_script:
   - php5 -v
   - php5 -m
   - composer self-update
-  - composer global require "fxp/composer-asset-plugin:1.0.3"
+  # Previously, fxp/composer-asset-plugin was required but was causing a lot of trouble updating. Now it's disabled.
+  #- composer global require "fxp/composer-asset-plugin:1.0.3"
   # You can either use the composer install method and face the Github limit
   #- composer install -n
-  #- composer -v update
+  - composer -v update
   # ...OR use the proxy repository to download the necessary dependencies
-  - git clone -b 1.10.x --depth=1 https://github.com/ywarnier/chamilo-vendors.git
-  - sudo mv chamilo-vendors/vendor .
-  - sudo mv chamilo-vendors/web .
-  - sudo mv chamilo-vendors/composer.lock .
-  - sudo rm -rf chamilo-vendors
+  #- git clone -b 1.10.x --depth=1 https://github.com/ywarnier/chamilo-vendors.git
+  #- sudo mv chamilo-vendors/vendor .
+  #- sudo mv chamilo-vendors/web .
+  #- sudo mv chamilo-vendors/composer.lock .
+  #- sudo rm -rf chamilo-vendors
   # Continue...
   - phpenv config-add tests/travis-php-config.ini
   # enable php-fpm
-  - sudo /etc/init.d/php-fpm stop
+  - sudo /etc/init.d/php5-fpm stop
   - sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf
   - sudo a2enmod rewrite actions fastcgi alias
   - echo "cgi.fix_pathinfo = 1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
@@ -51,7 +52,7 @@ before_script:
   - sudo cp -f tests/travis-apache /etc/apache2/sites-available/default
   - sudo sed -e "s?%TRAVIS_BUILD_DIR%?$(pwd)?g" --in-place /etc/apache2/sites-available/default
   - sudo service apache2 restart
-  - sudo service php-fpm restart
+  - sudo service php5-fpm restart
   - php5 -v
   # install Chash, a database, and then install Chamilo
   - git clone https://github.com/chamilo/chash

+ 51 - 6
app/Resources/public/css/base.css

@@ -91,7 +91,7 @@ a.thumbnail:hover{
     -ms-flex-negative:1 ;
     display: block;
     position: relative;
-    width: 100%;
+    
 }
 /*------------------------*/
 .cursor-pointer {
@@ -1651,7 +1651,13 @@ div.admin_section h4 {
 
 
 /* Groups boxes */
-
+.toolbar-groups{
+    margin-bottom: 30px;
+}
+.form-group  label span{
+    display: block;
+    font-size: 12px;
+}
 .group_invitation_grid_container { width:100%;}
 .group_invitation_grid_item {
     border:1px dotted #CCCCCC;
@@ -4460,21 +4466,52 @@ ul.holder li.bit-box{
 }
 
 /***    Draggable answer    ***/
-ul.exercise-draggable-answer {
-  min-height: 3.5em;
+.question_options ul.exercise-draggable-answer{
+  float: left;
+  margin-bottom: 20px;
+  min-height: 2em;
+  min-width: 100%;
 }
-ul.exercise-draggable-answer li.touch-items {
+ul.exercise-draggable-answer li {
   cursor: move;
+  float: left;
   margin: 0 20px 20px 0;
+  padding: 5px 20px;
   text-align: center;
+}
+ul.exercise-draggable-answer .touch-items{
+  background: #ffffff;
+  background-image: -webkit-linear-gradient(top, #ffffff, #cfcfcf);
+  background-image: -moz-linear-gradient(top, #ffffff, #cfcfcf);
+  background-image: -ms-linear-gradient(top, #ffffff, #cfcfcf);
+  background-image: -o-linear-gradient(top, #ffffff, #cfcfcf);
+  background-image: linear-gradient(to bottom, #ffffff, #cfcfcf);
+  -webkit-border-radius: 4;
+  -moz-border-radius: 4;
+  border-radius: 4px;
+  font-family: Arial;
+  color: #2e2e2e;
+  font-size: 13px;
+  padding: 10px 20px 10px 20px;
+  border: solid #b0b0b0 1px;
+  text-decoration: none;
   z-index: 100;
 }
+ul.exercise-draggable-answer .touch-items:hover{
+  background: #ffffff;
+  background-image: -webkit-linear-gradient(top, #ffffff, #b8d3e3);
+  background-image: -moz-linear-gradient(top, #ffffff, #b8d3e3);
+  background-image: -ms-linear-gradient(top, #ffffff, #b8d3e3);
+  background-image: -o-linear-gradient(top, #ffffff, #b8d3e3);
+  background-image: linear-gradient(to bottom, #ffffff, #b8d3e3);
+  text-decoration: none;
+}
 .question_options .ui-widget{
   padding: 10px 20px;
 }
 .question_options .droppable {
   margin: 0 20px 20px 0;
-  padding: 0 10px 10px;
+  padding: 10px;
   text-align: center;
   background-color: #ECF0F1;
   border: dotted #dddddd 4px;
@@ -4495,6 +4532,11 @@ ul.exercise-draggable-answer li.touch-items {
 }
 .question_options .droppable .gallery .exercise-draggable-answer-option {
   margin-bottom: 15px;
+  background-color: #286090;
+  color: #ffffff;
+  padding-top: 5px;
+  padding-bottom: 5px;
+  border-radius: 4px;
 }
 
 /***    Matching Draggable answer ***/
@@ -5962,6 +6004,9 @@ a.sessionView {
     .col-xs-6{
         width: 100%;
     }
+    .gallery .canvas-two{
+        width: 100%;
+    }
 }
 
 .elfinder-cwd-filename {

+ 1 - 1
custompages/first_login-dist.php

@@ -48,7 +48,7 @@ if (isset($_POST['password'])) {
 		''
 	);
 
-    if ($updated) {
+    if ($updated !== false) {
         UserManager::update_extra_field_value($u['user_id'], 'already_logged_in', 'true');
         ConditionalLogin::login();
     }

+ 33 - 0
documentation/changelog.html

@@ -83,12 +83,14 @@
     <h3>Notable new Features</h3>
     <h4>For end-users, teachers and Chamilo admins</h4>
     <ul>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/f08406490c3152c4299fa1916e944bdfc72bf37d">f0840649</a> - <a href="https://support.chamilo.org/issues/8037">#8037</a>) Show user classes on learner details page</li>
         <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/08b7cd5708f7ae783703b70bee29d3bb14ddf72e">08b7cd57</a> - <a href="https://support.chamilo.org/issues/8085">#8085</a>) Add announcements tags list again</li>
         <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/da8bce63019338ab1261a6b1be75adbf2f99d340">da8bce63</a> - <a href="https://support.chamilo.org/issues/8086">#8086</a>) Add modulo operation for calculated answers</li>
         <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/d2a2878cfbd3db3f0bf569ad5490aafd02d57a61">d2a2878c</a>) Updated Excel template to integrate no negative score management when importing questions. Fill blank or form type of question, matching type of question and category management</li>
     </ul>
     <h4>For developers and sysadmins</h4>
     <ul>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/150bd15db5c2d6e719532e6ecc2a9e9f5173c92a">150bd15d</a> - <a href="https://support.chamilo.org/issues/7926">#7926</a>) Fix Nginx config example</li>
         <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/aebd287c3cf6f86e896a758bd48e604deac476e5">aebd287c</a> - <a href="https://support.chamilo.org/issues/8105">#8105</a>) Boost agenda query efficiency</li>
         <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/b22023e8fda76176ca0cdceb82794bcd6f8cf9e0">b22023e8</a> - <a href="https://support.chamilo.org/issues/288">#288</a>) Add PENS plugin (beta)</li>
         <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/7532197623c9e1cd8170c52bab772a43451925f5">75321976</a> - <a href="https://support.chamilo.org/issues/8081">#8081</a>) Added Last 15 days recents login chart</li>
@@ -107,6 +109,37 @@
 
     <h3>Improvements (minor features) and debug</h3>
     <ul>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/e07caf3901f90639d0e6c40104ce86f9fbea27b7">e07caf39</a> - <a href="https://support.chamilo.org/issues/8065">#8065</a>) Fix dialog when deleting an event on the course agenda</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/69ff271e0c071a5a73f605c91a10e626594a2061">69ff271e</a> - <a href="https://support.chamilo.org/issues/8065">#8065</a>) Fix delete c_event form when the date is 'today'</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/9471e4b27ac646303532b3406ba93e995e13e679">9471e4b2</a> - <a href="https://support.chamilo.org/issues/8065">#8065</a>) Fix dialog when deleting a recurring course event</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/b507335e318eb95eb1c2eeba93c4de7837744ee2">b507335e</a> - <a href="https://support.chamilo.org/issues/8124">#8124</a>) Fix hotspot delineation question type</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/48c47f54c558a12937c4451f26ec3012e5080d14">48c47f54</a> - <a href="https://support.chamilo.org/issues/8125">#8125</a>) Fix exercise description appearing multiple time in multiple-question-per-page mode</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/08307e8b5bcd25d7dccee8ae52bcaa8e5de14755">08307e8b</a>) Fix missing icon in hotspot upload form</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/4efec51add4e6cd158cc0422e2f1015d8c4775ea">4efec51a</a> - <a href="https://task.beeznest.com/issues/7683">BT#7683</a>) Fix appearance of the sessions catalogue</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/b45f9528bc32cf0a510cf0370a36eb65ee05b7ed">b45f9528</a>) Fix groups style</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c896e041e7d9dc2660498ccd2291b3ba7a0caab6">c896e041</a> - <a href="https://support.chamilo.org/issues/8123">#8123</a>) CSS setting panel description for arrow state CT#8123</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/117f9dba34ffd3384e119ad722b5d2ee59adb4ec">117f9dba</a> - <a href="https://support.chamilo.org/issues/8104">#8104</a>) Fix Flat and Nested views preventing the clicking on the user image in a posts list (redirected to the full page of chamilo when the forum was in a LP)</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/52b94f03f2a0423f7d7f4de49664baa75b788667">52b94f03</a>) Fix course catalogue responsive style for mobiles</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/0c0439c42b4e24e1c7634d08326b24b40757ba76">0c0439c4</a>) Add possibility to filter available languages in getAllLanguages()</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/72acb64e67d28358bb06b206ba86189677521279">72acb64e</a> - <a href="https://support.chamilo.org/issues/8122">#8122</a>) Improve "return to course homepage" button style in exercises</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/f74e4d97b4d09c85f9f5add150bac6945520e244">f74e4d97</a> - <a href="https://support.chamilo.org/issues/8092">#8092</a>) Fix catalogue pagination when one tries to subscribe to a password-protected course</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/6594ee615e823982162984db95b8f743473e86b0">6594ee61</a> - <a href="https://support.chamilo.org/issues/8123">#8123</a>) Fix exercise description panel initially-collapsed behaviour</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/87ce2210355432e1567e6d51ff7b565f7da3313c">87ce2210</a>) MINOR - Change 20 number to INVITEE constant</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/682e6d4f1c1a0cb96e649bb00d62981cae7f0566">682e6d4f</a>) Prevent making adding a group tutor from a invitee-type user</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/961375baf9cd45e56f36eb767b44d0417d5d115e">961375ba</a> - <a href="https://support.chamilo.org/issues/8044">#8044</a>) Purge c_document and c_item_propery records when deleting a session</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/0458c389a78ba1944a18c9724314728fbb92ab0c">0458c389</a> - <a href="https://support.chamilo.org/issues/8109">#8109</a>) Fix course custom theme setting</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/f38c8d7841c8a2e3bdb46bd12cd4abaa660b089a">f38c8d78</a> - <a href="https://support.chamilo.org/issues/8113">#8113</a>) Checking if user exist before insertion</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/7be074e1f80d95e82ee8e382945e0c0c8f85d6d3">7be074e1</a>) Fix style of documents gallery</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/4138381339ca5c6af2044b19d31d5ed2074785e5">41383813</a> - <a href="https://support.chamilo.org/issues/8037">#8037</a>) Fix save class as a social group</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/a3f90367b8b5a5c6b6452a6b7e75d37dd51937b9">a3f90367</a> - <a href="https://support.chamilo.org/issues/10922">#10922</a>) Fix hide_global_announcements_when_not_connected</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/b0c54e660a727e47000e0494629e22676ac9f6b5">b0c54e66</a> - <a href="https://task.beeznest.com/issues/10922">BT#10922</a>) Remove unnecessary instance of SysAnnouncement</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/6685772943ddeb2607d5c8c1f6cec0b2c2fbad78">66857729</a> - <a href="https://task.beeznest.com/issues/10922">BT#10922</a>) Fix update of global announcements in all languages</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c8215d7e12f40461062e6eae8243d420e6ccc7bc">c8215d7e</a> - <a href="https://task.beeznest.com/issues/10657">BT#10657</a>) Arrangement appearance configuration of the main page</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/b58f773c50b64d361350aaad6476ac3c99b7fdf4">b58f773c</a>) Add new accepted formats to CSS upload handler</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/36f40bacdbc16ce46936a6f90d29e7a6bd07110d">36f40bac</a>) Added message class to behat tests (1.10.x)</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/8c1de01f636e7781d0a12ae809f5bf95e2b394a1">8c1de01f</a> - <a href="https://support.chamilo.org/issues/8022">#8022</a>) Fix checkbox extra field edit in course edition by admin</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/4bdce3630a09f3fb1726729b5401d0cd97fbcca9">4bdce363</a> - <a href="https://task.beeznest.com/issues/10893">BT#10893</a>) Add new element addMultipleUpload to use drag and drop features in assignments and documents</li>
+
         <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/cea07e84d24984de48350e4de8f0b9351d06a8a0">cea07e84</a> - <a href="https://task.beeznest.com/issues/8986">BT#8986</a>) Fix error course info</li>
         <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/1265dfc3c19b835b8c1befbfa145f9fac2a2052c">1265dfc3</a> - <a href="https://task.beeznest.com/issues/10730">BT#10730</a>) Fix upgrade issue with usergroup_rel_user table</li>
         <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/e7fa1a208a0319d6ee7fa96c06a12ea907092f60">e7fa1a20</a>) Add condition if value is empty in course restorer</li>

+ 3 - 2
main/admin/user_move_stats.php

@@ -199,9 +199,10 @@ if (isset($_REQUEST['load_ajax'])) {
                     foreach ($list as $id => $data) {
                         if ($update_database) {
                             $sql = "UPDATE $TBL_TRACK_E_COURSE_ACCESS SET session_id = $new_session_id WHERE course_access_id = $id";
-                            if ($debug) echo $sql;
+                            if ($debug) {
+                                echo $sql;
+                            }
                             $res = Database::query($sql);
-                            if ($debug) var_dump($res);
                             $result_message[$TBL_TRACK_E_COURSE_ACCESS]++;
                         }
                     }

+ 2 - 1
main/auth/cas/lib/CAS/PGTStorage/pgt-db.php

@@ -206,8 +206,9 @@ class PGTStorageDB extends PGTStorage
       // try to connect to the database
       $this->_link = DB::connect($this->getURL());
       if ( DB::isError($this->_link) ) {
-	phpCAS::error('could not connect to database ('.DB::errorMessage($this->_link).')');
+	    phpCAS::error('could not connect to database ('.DB::errorMessage($this->_link).')');
       }
+      // Dump into trace
       var_dump($this->_link);
       phpCAS::traceBEnd();
     }

+ 1 - 0
main/auth/shibboleth/test/shibboleth_test.class.php

@@ -204,6 +204,7 @@ class ShibbolethTest
         {
             $message = "Assert failed $message <br/>";
             echo $message;
+            // Dump variable for debug
             var_dump(debug_backtrace());
             die;
         }

+ 2 - 2
main/course_home/course_home.php

@@ -69,7 +69,7 @@ $(document).ready(function() {
 		tool_info = tool_id.split("_");
 		my_tool_id = tool_info[1];
         $("#id_normal_message").attr("class", "normal-message alert alert-success");
-        
+
 		$.ajax({
 			contentType: "application/x-www-form-urlencoded",
 			beforeSend: function(objeto) {
@@ -269,8 +269,8 @@ if (api_get_setting('course.homepage_view') == 'activity' ||
 	require 'vertical_activity.php';
 }
 
-
 $content = '<div id="course_tools">'.$content.'</div>';
+
 $tpl = new Template(null);
 $tpl->assign('message', $show_message);
 $tpl->assign('content', $content);

BIN
main/default_course_document/images/mr_chamilo/assistance.png


BIN
main/default_course_document/images/mr_chamilo/collaborative.png


BIN
main/default_course_document/images/mr_chamilo/doubts.png


BIN
main/default_course_document/images/mr_chamilo/gotowork.png


BIN
main/default_course_document/images/mr_chamilo/idea.png


BIN
main/default_course_document/images/mr_chamilo/navigate_computer.png


BIN
main/default_course_document/images/mr_chamilo/optimistic.png


BIN
main/default_course_document/images/mr_chamilo/optimistic_woman.png


BIN
main/default_course_document/images/mr_chamilo/practicing.png


BIN
main/default_course_document/images/mr_chamilo/reading.png


BIN
main/default_course_document/images/mr_chamilo/results.png


Diff do ficheiro suprimidas por serem muito extensas
+ 224 - 0
main/default_course_document/images/mr_chamilo/svg/assistance.svg


Diff do ficheiro suprimidas por serem muito extensas
+ 323 - 0
main/default_course_document/images/mr_chamilo/svg/collaborative.svg


Diff do ficheiro suprimidas por serem muito extensas
+ 258 - 0
main/default_course_document/images/mr_chamilo/svg/doubts.svg


Diff do ficheiro suprimidas por serem muito extensas
+ 206 - 0
main/default_course_document/images/mr_chamilo/svg/gotowork.svg


Diff do ficheiro suprimidas por serem muito extensas
+ 227 - 0
main/default_course_document/images/mr_chamilo/svg/idea.svg


Diff do ficheiro suprimidas por serem muito extensas
+ 214 - 0
main/default_course_document/images/mr_chamilo/svg/navigate_computer.svg


Diff do ficheiro suprimidas por serem muito extensas
+ 233 - 0
main/default_course_document/images/mr_chamilo/svg/optimistic.svg


Diff do ficheiro suprimidas por serem muito extensas
+ 349 - 0
main/default_course_document/images/mr_chamilo/svg/optimistic_woman.svg


Diff do ficheiro suprimidas por serem muito extensas
+ 396 - 0
main/default_course_document/images/mr_chamilo/svg/practicing.svg


Diff do ficheiro suprimidas por serem muito extensas
+ 377 - 0
main/default_course_document/images/mr_chamilo/svg/reading.svg


Diff do ficheiro suprimidas por serem muito extensas
+ 322 - 0
main/default_course_document/images/mr_chamilo/svg/results.svg


Diff do ficheiro suprimidas por serem muito extensas
+ 439 - 0
main/default_course_document/images/mr_chamilo/svg/teaching.svg


Diff do ficheiro suprimidas por serem muito extensas
+ 188 - 0
main/default_course_document/images/mr_chamilo/svg/writing.svg


BIN
main/default_course_document/images/mr_chamilo/teaching.png


BIN
main/default_course_document/images/mr_chamilo/writing.png


+ 21 - 9
main/document/document.php

@@ -52,6 +52,7 @@ if (
 }
 $_user = api_get_user_info();
 $courseInfo = api_get_course_info();
+$courseId = $courseInfo['real_id'];
 $course_dir = $courseInfo['directory'] . '/document';
 $sys_course_path = api_get_path(SYS_COURSE_PATH);
 $base_work_dir = $sys_course_path . $course_dir;
@@ -118,6 +119,8 @@ if (api_get_session_id() != 0) {
     $group_member_with_upload_rights = $group_member_with_upload_rights && api_is_allowed_to_session_edit(false, true);
 }
 
+$groupMemberWithEditRights = $is_allowed_to_edit || GroupManager::is_tutor_of_group($userId, $groupId, $courseId);
+
 // Setting group variables.
 if (!empty($groupId)) {
     // Get group info
@@ -152,9 +155,13 @@ if (!empty($groupId)) {
             'url' => api_get_path(WEB_CODE_PATH).'group/group_space.php?'.api_get_cidreq(),
             'name' => get_lang('GroupSpace').' '.$group_properties['name']
         );
-        //allowed to upload?
-        if ($is_allowed_to_edit || GroupManager::is_subscribed($userId, $groupId)) {
-            // Only courseadmin or group members can upload
+
+        // Allowed to upload?
+        if ($is_allowed_to_edit ||
+            GroupManager::is_subscribed($userId, $groupId) ||
+            GroupManager::is_tutor_of_group($userId, $groupId, $courseId)
+        ) {
+            // Only course admin or group members can upload
             $group_member_with_upload_rights = true;
         }
     }
@@ -193,7 +200,8 @@ switch ($action) {
                             $_GET['deleteid'],
                             $courseInfo,
                             $sessionId,
-                            api_get_user_id())
+                            api_get_user_id()
+                        )
                         ) {
                             api_not_allowed();
                         }
@@ -204,7 +212,8 @@ switch ($action) {
                         api_get_user_id(),
                         '',
                         $_GET['deleteid'],
-                        true)
+                        true
+                    )
                     ) {
                         api_not_allowed();
                     }
@@ -218,7 +227,6 @@ switch ($action) {
                 );
 
                 // Check whether the document is in the database.
-
                 if (!empty($documentInfo)) {
                     $deleteDocument = DocumentManager::delete_document(
                         $courseInfo,
@@ -989,7 +997,9 @@ if ($is_allowed_to_edit ||
             );
 
             // filter if is my shared folder. TODO: move this code to build_move_to_selector function
-            if (DocumentManager::is_my_shared_folder(api_get_user_id(), $curdirpath, $sessionId) && !$is_allowed_to_edit) {
+            if (DocumentManager::is_my_shared_folder(api_get_user_id(), $curdirpath, $sessionId) &&
+                !$is_allowed_to_edit
+            ) {
                 //only main user shared folder
                 $main_user_shared_folder_main = '/shared_folder/sf_user_'.api_get_user_id();
                 $main_user_shared_folder_sub = '/shared_folder\/sf_user_'.api_get_user_id().'\//'; //all subfolders
@@ -1021,7 +1031,6 @@ if ($is_allowed_to_edit ||
     }
 
     if (!empty($moveTo) && isset($_POST['move_file'])) {
-
         if (!$is_allowed_to_edit) {
             if (DocumentManager::check_readonly($courseInfo, api_get_user_id(), $_POST['move_file'])) {
                 api_not_allowed(true);
@@ -1790,7 +1799,8 @@ if (isset($documentAndFolders) && is_array($documentAndFolders)) {
             $row[] = $invisibility_span_open.$display_date.$invisibility_span_close;
 
             // Admins get an edit column
-            if ($is_allowed_to_edit || $group_member_with_upload_rights ||
+            if ($is_allowed_to_edit ||
+                $groupMemberWithEditRights ||
                 DocumentManager::is_my_shared_folder(api_get_user_id(), $curdirpath, $sessionId)
             ) {
                 $is_template = isset($document_data['is_template']) ? $document_data['is_template'] : false;
@@ -1813,6 +1823,8 @@ if (isset($documentAndFolders) && is_array($documentAndFolders)) {
                     );
                 }
                 $row[] = $edit_icons;
+            } else {
+                $row[] = '';
             }
             $row[] = $last_edit_date;
             $row[] = $size;

+ 11 - 8
main/document/slideshow.php

@@ -165,12 +165,13 @@ if (isset($_SESSION["image_resizing"]) &&  $_SESSION["image_resizing"] == "resiz
 
 // This is for viewing all the images in the slideshow as thumbnails.
 $image_tag = array ();
+$html = '';
 if ($slide_id == 'all') {
 
 	// Config for make thumbnails
     $allowed_thumbnail_types = array('jpg', 'jpeg', 'gif', 'png');
-	$max_thumbnail_width     = 200;
-	$max_thumbnail_height    = 200;
+	$max_thumbnail_width     = 250;
+	$max_thumbnail_height    = 250;
 	$png_compression	     = 0;//0(none)-9
 	$jpg_quality  	         = 75;//from 0 to 100 (default is 75). More quality less compression
 
@@ -331,7 +332,7 @@ if ($slide_id == 'all') {
 	for ($k = 0; $k < $number_iteration; $k++) {
 		for ($i = 0; $i < $number_image; $i++) {
 			if (isset($image_tag[$p])) {
-                            $html .= '<div class="col-md-3">';
+                            $html .= '<div class="col-xs-6 col-sm-3 col-md-2">';
                             $html .= '<div class="canvas-one">';
                             $html .= '<a class="canvas-two" href="slideshow.php?slide_id='.$p.'&curdirpath='.$pathurl.'">';
                             $html .= '<div class="frame">';
@@ -472,16 +473,18 @@ if ($slide_id != 'all' && !empty($image_files_only)) {
 			$aux = explode('.', htmlspecialchars($image_files_only[$slide]));
 			$ext = $aux[count($aux) - 1];
 
-            if ($_SESSION['image_resizing'] == 'resizing') {
+            if (isset($_SESSION['image_resizing']) && $_SESSION['image_resizing'] == 'resizing') {
                 $resize_info = get_lang('Resizing').'<br />';
-                $resize_widht = $_SESSION["image_resizing_width"].' x ';
+                $resize_width = $_SESSION["image_resizing_width"].' x ';
                 $resize_height = $_SESSION['image_resizing_height'];
-            } elseif($_SESSION['image_resizing'] != 'noresizing'){
+            } elseif (isset($_SESSION['image_resizing']) && $_SESSION['image_resizing'] != 'noresizing'){
                 $resize_info = get_lang('Resizing').'<br />';
-                $resize_widht = get_lang('Auto').' x ';
+                $resize_width = get_lang('Auto').' x ';
                 $resize_height = get_lang('Auto');
             } else {
                 $resize_info = get_lang('NoResizing').'<br />';
+				$resize_width = '';
+				$resize_height = '';
             }
 
             echo '<tr>';
@@ -498,7 +501,7 @@ if ($slide_id != 'all' && !empty($image_files_only)) {
 			echo '<tr>';
 			echo '<td align="center">';
 			echo $resize_info;
-			echo $resize_widht;
+			echo $resize_width;
 			echo $resize_height;
 			echo '</td>';
 			echo '</tr>';

+ 6 - 1
main/document/upload.php

@@ -298,7 +298,12 @@ $simple_form = $form->returnForm();
 
 $url = api_get_path(WEB_AJAX_PATH).'document.ajax.php?'.api_get_cidreq().'&a=upload_file&curdirpath='.$path;
 
-$multipleForm = new FormValidator('post');
+$multipleForm = new FormValidator(
+    'drag_drop',
+    'post',
+    '#',
+    array('enctype' => 'multipart/form-data')
+);
 $multipleForm->addMultipleUpload($url);
 
     $headers = array(

+ 1 - 1
main/dropbox/dropbox_functions.inc.php

@@ -653,7 +653,7 @@ function display_add_form($dropbox_unid, $viewReceivedCategory, $viewSentCategor
             }
             $userId = $current_user['user_id'];
             $userInfo = api_get_user_info($userId);
-            if ($userInfo['status'] != 20) {
+            if ($userInfo['status'] != INVITEE) {
                 $groupNameListToString = '';
                 if (!empty($groups)) {
                     $groupNameList = array_column($groups, 'name');

+ 14 - 12
main/exercice/exercise_submit.php

@@ -1108,19 +1108,21 @@ if (!empty($error)) {
         	$remind_highlight = ' remind_highlight ';
         }
 
-        // Showing the question
+        // Showing the exercise description
         if (!empty($objExercise->description)){
-            //echo Display::panel($objExercise->description, get_lang('ExerciseDescriptionLabel'));
-            echo Display::panelCollapse('<span>'.
-                get_lang('ExerciseDescriptionLabel').'</span>',
-                $objExercise->description,
-                'exercise-description',
-                [],
-                'description',
-                'exercise-collapse',
-                false,
-                true
-            );
+            if ($objExercise->type == ONE_PER_PAGE || ($objExercise->type != ONE_PER_PAGE && $i==1)) {
+                //echo Display::panel($objExercise->description, get_lang('ExerciseDescriptionLabel'));
+                echo Display::panelCollapse('<span>'.
+                    get_lang('ExerciseDescriptionLabel').'</span>',
+                    $objExercise->description,
+                    'exercise-description',
+                    [],
+                    'description',
+                    'exercise-collapse',
+                    false,
+                    true
+                );
+            }
         }
 
         echo '<div id="question_div_'.$questionId.'" class="main-question '.$remind_highlight.'" >';

+ 9 - 0
main/exercice/exercise_submit_modal.php

@@ -12,8 +12,12 @@ api_protect_course_script(false);
 require_once api_get_path(LIBRARY_PATH).'geometry.lib.php';
 
 Display::display_reduced_header();
+
+echo '<div id="delineation-container">';
+
 $message = null;
 $dbg_local = 0;
+$gradebook = null;
 
 $final_overlap = null;
 $final_missing = null;
@@ -76,6 +80,8 @@ if (isset($_GET['hotspot'])) {
     }
 }
 
+$choice_value = '';
+
 $user_array = substr($user_array,0,-1);
 
 if (isset($_GET['choice'])){
@@ -590,3 +596,6 @@ if ($links!='') {
    			//self.parent.tb_remove();
  	 	</script>';
 }
+
+echo '</div>';
+

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

@@ -34,7 +34,7 @@ class HotSpot extends Question
 		parent::createForm($form, $fck_config);
 
 		if (!isset($_GET['editQuestion'])) {
-			$form->addElement('file','imageUpload',array('<img src="../img/icons/22/hotspots.png" />', get_lang('UploadJpgPicture')) );
+			$form->addElement('file','imageUpload',array('<img src="'.Display::return_icon('hotspot.png', null, null, ICON_SIZE_BIG, false, true).'" />', get_lang('UploadJpgPicture')) );
 
 			// setting the save button here and not in the question class.php
 			// Saving a question

+ 2 - 2
main/forum/editpost.php

@@ -187,7 +187,7 @@ if ($origin != 'learnpath') {
         echo '<a href="index.php?'.api_get_cidreq().'">'.
             Display::return_icon('back.png', get_lang('BackToForumOverview'), '', ICON_SIZE_MEDIUM).'</a>';
     }
-    echo '<a href="viewforum.php?forum='.Security::remove_XSS($_GET['forum']).'&gidReq='.Security::remove_XSS($_GET['gidReq']).'&origin='.$origin.'">'.
+    echo '<a href="viewforum.php?forum='.intval($_GET['forum']).'&'.api_get_cidreq().'&origin='.$origin.'">'.
         Display::return_icon('forum.png', get_lang('BackToForum'), '', ICON_SIZE_MEDIUM).'</a>';
     echo '</div>';
 }
@@ -260,7 +260,7 @@ if (!empty($values) and isset($_POST['SubmitPost'])) {
 }
 
 // Footer
-if ($origin == 'learnpath') {
+if (isset($origin) && $origin == 'learnpath') {
     Display::display_reduced_footer();
 } else {
     Display::display_footer();

+ 7 - 14
main/forum/editthread.php

@@ -10,7 +10,6 @@
 
 use ChamiloSession as Session;
 
-// Including the global initialization file.
 require_once '../inc/global.inc.php';
 
 // The section (tabs).
@@ -19,7 +18,6 @@ $this_section = SECTION_COURSES;
 api_protect_course_script(true);
 
 $cidreq = api_get_cidreq();
-
 $nameTools = get_lang('ToolForum');
 
 /* Including necessary files */
@@ -53,14 +51,9 @@ if (!empty($gradebook) && $gradebook == 'view') {
     );
 }
 
-if (!empty($_GET['gidReq'])) {
-    $toolgroup = intval($_GET['gidReq']);
-    Session::write('toolgroup',$toolgroup);
-}
-
 $threadId = isset($_GET['thread']) ? intval($_GET['thread']) : 0;
 $courseInfo = isset($_GET['cidReq']) ? api_get_course_info($_GET['cidReq']) : 0;
-$cId = isset($courseInfo['real_id']) ? intval($courseInfo['real_id']) : 0; 
+$cId = isset($courseInfo['real_id']) ? intval($courseInfo['real_id']) : 0;
 
 /* Is the user allowed here? */
 
@@ -113,12 +106,12 @@ if (!empty($groupId)) {
     $groupProperties = GroupManager :: get_group_properties($groupId);
     $interbreadcrumb[] = array('url' => '../group/group.php?'.$cidreq, 'name' => get_lang('Groups'));
     $interbreadcrumb[] = array('url' => '../group/group_space.php?'.$cidreq, 'name' => get_lang('GroupSpace').' '.$groupProperties['name']);
-    $interbreadcrumb[] = array('url' => 'viewforum.php?'.$cidreq.'&forum='.Security::remove_XSS($_GET['forum']), 'name' => $currentForum['forum_title']);
-    $interbreadcrumb[] = array('url' => 'newthread.php?'.$cidreq.'&forum='.Security::remove_XSS($_GET['forum']),'name' => get_lang('EditThread'));
+    $interbreadcrumb[] = array('url' => 'viewforum.php?'.$cidreq.'&forum='.intval($_GET['forum']), 'name' => $currentForum['forum_title']);
+    $interbreadcrumb[] = array('url' => 'newthread.php?'.$cidreq.'&forum='.intval($_GET['forum']),'name' => get_lang('EditThread'));
 } else {
     $interbreadcrumb[] = array('url' => 'index.php?'.$cidreq, 'name' => $nameTools);
     $interbreadcrumb[] = array('url' => 'viewforumcategory.php?'.$cidreq.'&forumcategory='.$currentForumCategory['cat_id'], 'name' => $currentForumCategory['cat_title']);
-    $interbreadcrumb[] = array('url' => 'viewforum.php?'.$cidreq.'&forum='.Security::remove_XSS($_GET['forum']), 'name' => $currentForum['forum_title']);
+    $interbreadcrumb[] = array('url' => 'viewforum.php?'.$cidreq.'&forum='.intval($_GET['forum']), 'name' => $currentForum['forum_title']);
     $interbreadcrumb[] = array('url' => '#', 'name' => get_lang('EditThread'));
 }
 
@@ -129,13 +122,13 @@ $tableLink = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
 $htmlHeadXtra[] = <<<JS
     <script>
     $(document).on('ready', function() {
-        
+
         if ($('#thread_qualify_gradebook').is(':checked') == true) {
             document.getElementById('options_field').style.display = 'block';
         } else {
             document.getElementById('options_field').style.display = 'none';
         }
-        
+
         $('#thread_qualify_gradebook').click(function() {
             if ($('#thread_qualify_gradebook').is(':checked') == true) {
                 document.getElementById('options_field').style.display = 'block';
@@ -175,7 +168,7 @@ $values = showUpdateThreadForm(
 );
 
 if (!empty($values) && isset($values['SubmitPost'])) {
-    
+
     // update thread in table forum_thread.
     updateThread($values);
 }

+ 3 - 1
main/forum/forumfunction.inc.php

@@ -3375,7 +3375,7 @@ function show_edit_post_form(
     $form = new FormValidator(
         'edit_post',
         'post',
-        api_get_self().'?'.api_get_cidreq().'&forum='.Security::remove_XSS($_GET['forum']).'&thread='.Security::remove_XSS($_GET['thread']).'&post='.Security::remove_XSS($_GET['post'])
+        api_get_self().'?'.api_get_cidreq().'&forum='.intval($_GET['forum']).'&thread='.intval($_GET['thread']).'&post='.intval($_GET['post'])
     );
     $form->addElement('header', get_lang('EditPost'));
     // Setting the form elements.
@@ -5628,7 +5628,9 @@ function editAttachedFile($array, $id, $courseId = null) {
  * @param int $forumId Forum ID from where the post are
  * @param int $threadId Thread ID where forum post are
  * @param int $postId Post ID to identify Post
+ * @deprecated this function seems to never been used
  * @return string The Forum Attachment Ajax Form
+ *
  */
 function getAttachmentAjaxForm($forumId, $threadId, $postId)
 {

+ 3 - 3
main/forum/forumqualify.php

@@ -117,14 +117,14 @@ if ($origin == 'learnpath') {
 
         if ($message <> 'PostDeletedSpecial') {
             if (isset($_GET['gradebook']) and $_GET['gradebook']=='view') {
-                $info_thread=get_thread_information(Security::remove_XSS($_GET['thread']));
+                $info_thread = get_thread_information($_GET['thread']);
                 $interbreadcrumb[] = array(
-                    "url" => "viewthread.php?".api_get_cidreq()."&forum=".$info_thread['forum_id']."&thread=".Security::remove_XSS($_GET['thread']),
+                    "url" => "viewthread.php?".api_get_cidreq()."&forum=".$info_thread['forum_id']."&thread=".intval($_GET['thread']),
                     "name" => prepare4display($currentThread['thread_title'])
                 );
             } else {
                 $interbreadcrumb[] = array(
-                    "url" => "viewthread.php?".api_get_cidreq()."&forum=".Security::remove_XSS($_GET['forum'])."&thread=".Security::remove_XSS($_GET['thread']),
+                    "url" => "viewthread.php?".api_get_cidreq()."&forum=".intval($_GET['forum'])."&thread=".intval($_GET['thread']),
                     "name" => prepare4display($currentThread['thread_title'])
                 );
             }

+ 4 - 9
main/forum/newthread.php

@@ -61,11 +61,6 @@ if (api_is_in_gradebook()) {
     );
 }
 
-if (!empty($_GET['gidReq'])) {
-    $toolgroup = intval($_GET['gidReq']);
-    Session::write('toolgroup',$toolgroup);
-}
-
 /* Is the user allowed here? */
 
 // The user is not allowed here if:
@@ -117,12 +112,12 @@ if (!empty($groupId)) {
     $groupProperties = GroupManager :: get_group_properties($groupId);
     $interbreadcrumb[] = array('url' => '../group/group.php?'.$cidreq, 'name' => get_lang('Groups'));
     $interbreadcrumb[] = array('url' => '../group/group_space.php?'.$cidreq, 'name' => get_lang('GroupSpace').' '.$groupProperties['name']);
-    $interbreadcrumb[] = array('url' => 'viewforum.php?'.$cidreq.'&forum='.Security::remove_XSS($_GET['forum']), 'name' => $current_forum['forum_title']);
-    $interbreadcrumb[] = array('url' => 'newthread.php?'.$cidreq.'&forum='.Security::remove_XSS($_GET['forum']),'name' => get_lang('NewTopic'));
+    $interbreadcrumb[] = array('url' => 'viewforum.php?'.$cidreq.'&forum='.intval($_GET['forum']), 'name' => $current_forum['forum_title']);
+    $interbreadcrumb[] = array('url' => 'newthread.php?'.$cidreq.'&forum='.intval($_GET['forum']),'name' => get_lang('NewTopic'));
 } else {
     $interbreadcrumb[] = array('url' => 'index.php?'.$cidreq, 'name' => $nameTools);
     $interbreadcrumb[] = array('url' => 'viewforumcategory.php?'.$cidreq.'&forumcategory='.$current_forum_category['cat_id'], 'name' => $current_forum_category['cat_title']);
-    $interbreadcrumb[] = array('url' => 'viewforum.php?'.$cidreq.'&forum='.Security::remove_XSS($_GET['forum']), 'name' => $current_forum['forum_title']);
+    $interbreadcrumb[] = array('url' => 'viewforum.php?'.$cidreq.'&forum='.intval($_GET['forum']), 'name' => $current_forum['forum_title']);
     $interbreadcrumb[] = array('url' => '#', 'name' => get_lang('NewTopic'));
 }
 
@@ -165,7 +160,7 @@ handle_forum_and_forumcategories();
 // Action links
 echo '<div class="actions">';
 echo '<span style="float:right;">'.search_link().'</span>';
-echo '<a href="viewforum.php?forum='.Security::remove_XSS($_GET['forum']).'&'.$cidreq.'">'.
+echo '<a href="viewforum.php?forum='.intval($_GET['forum']).'&'.$cidreq.'">'.
     Display::return_icon('back.png',get_lang('BackToForum'),'',ICON_SIZE_MEDIUM).'</a>';
 echo '</div>';
 

+ 34 - 76
main/forum/viewforum.php

@@ -50,10 +50,13 @@ require_once 'forumfunction.inc.php';
 
 $userid  = api_get_user_id();
 $sessionId = api_get_session_id();
+$groupId = api_get_group_id();
+$courseId = api_get_course_int_id();
+
+$isTutor = GroupManager::is_tutor_of_group($userId, $groupId, $courseId);
 
 /* MAIN DISPLAY SECTION */
 
-$groupId = api_get_group_id();
 $my_forum = isset($_GET['forum']) ? $_GET['forum'] : '';
 // Note: This has to be validated that it is an existing forum.
 $current_forum = get_forum_information($my_forum);
@@ -69,23 +72,23 @@ if (!empty($groupId)) {
     //Group info & group category info
     $group_properties = GroupManager::get_group_properties($groupId);
     //User has access in the group?
-    $user_has_access_in_group = GroupManager::user_has_access($userid, $groupId, GroupManager::GROUP_TOOL_FORUM);
+    $user_has_access_in_group = GroupManager::user_has_access($userId, $groupId, GroupManager::GROUP_TOOL_FORUM);
     $is_group_tutor = GroupManager::is_tutor_of_group(api_get_user_id(), $groupId);
 
     //Course
     if (
-        !api_is_allowed_to_edit(false, true) AND  //is a student
-        (($current_forum_category && $current_forum_category['visibility'] == 0) OR
-        $current_forum['visibility'] == 0 OR !$user_has_access_in_group)
+        !api_is_allowed_to_edit(false, true) &&  //is a student
+        (($current_forum_category && $current_forum_category['visibility'] == 0) ||
+        $current_forum['visibility'] == 0 || !$user_has_access_in_group)
     ) {
         api_not_allowed(true);
     }
 } else {
     //Course
     if (
-        !api_is_allowed_to_edit(false, true) AND  //is a student
+        !api_is_allowed_to_edit(false, true) &&  //is a student
         (
-            ($current_forum_category && $current_forum_category['visibility'] == 0) OR
+            ($current_forum_category && $current_forum_category['visibility'] == 0) ||
             $current_forum['visibility'] == 0
         ) //forum category or forum visibility is false
     ) {
@@ -105,11 +108,6 @@ if (api_is_in_gradebook()) {
     );
 }
 
-if (!empty($_GET['gidReq'])) {
-    $toolgroup = Database::escape_string($_GET['gidReq']);
-    Session::write('toolgroup',$toolgroup);
-}
-
 $forumUrl = api_get_path(WEB_CODE_PATH).'forum/';
 
 if ($origin == 'group') {
@@ -151,9 +149,9 @@ if ($origin == 'learnpath') {
 /* Actions */
 // Change visibility of a forum or a forum category.
 if (
-    ($my_action == 'invisible' OR $my_action == 'visible') AND
-    isset($_GET['content']) AND
-    isset($_GET['id']) AND
+    ($my_action == 'invisible' || $my_action == 'visible') &&
+    isset($_GET['content']) &&
+    isset($_GET['id']) &&
     api_is_allowed_to_edit(false, true) &&
     api_is_allowed_to_session_edit(false, true)
 ) {
@@ -161,8 +159,8 @@ if (
 }
 // Locking and unlocking.
 if (
-    ($my_action == 'lock' OR $my_action == 'unlock') AND
-    isset($_GET['content']) AND isset($_GET['id']) AND
+    ($my_action == 'lock' || $my_action == 'unlock') &&
+    isset($_GET['content']) && isset($_GET['id']) &&
     api_is_allowed_to_edit(false, true) &&
     api_is_allowed_to_session_edit(false, true)
 ) {
@@ -170,9 +168,9 @@ if (
 }
 // Deleting.
 if (
-    $my_action == 'delete' AND
-    isset($_GET['content']) AND
-    isset($_GET['id']) AND
+    $my_action == 'delete' &&
+    isset($_GET['content']) &&
+    isset($_GET['id']) &&
     api_is_allowed_to_edit(false, true) &&
     api_is_allowed_to_session_edit(false, true)
 ) {
@@ -276,7 +274,7 @@ if (
             $table_list .= '<th>' . get_lang('Qualify') . '</th>';
         }
         $table_list .= '</tr>';
-        $max_qualify = showQualify('2', $userid, $_GET['id']);
+        $max_qualify = showQualify('2', $userId, $_GET['id']);
         $counter_stdlist = 0;
 
         if (Database::num_rows($student_list) > 0) {
@@ -357,9 +355,9 @@ if ($origin != 'learnpath') {
 // 2. the course member is here and new threads are allowed
 // 3. a visitor is here and new threads AND allowed AND  anonymous posts are allowed
 if (
-    api_is_allowed_to_edit(false, true) OR
-    ($current_forum['allow_new_threads'] == 1 AND isset($_user['user_id'])) OR
-    ($current_forum['allow_new_threads'] == 1 AND !isset($_user['user_id']) AND $current_forum['allow_anonymous'] == 1)
+    api_is_allowed_to_edit(false, true) ||
+    ($current_forum['allow_new_threads'] == 1 && isset($_user['user_id'])) ||
+    ($current_forum['allow_new_threads'] == 1 && !isset($_user['user_id']) && $current_forum['allow_anonymous'] == 1)
 ) {
     if ($current_forum['locked'] <> 1 AND $current_forum['locked'] <> 1) {
         if (!api_is_anonymous() && !api_is_invitee()) {
@@ -431,7 +429,7 @@ if (is_array($threads)) {
     foreach ($threads as $row) {
         // Thread who have no replies yet and the only post is invisible should not be displayed to students.
         if (api_is_allowed_to_edit(false, true) ||
-            !($row['thread_replies'] == '0' AND $row['visibility'] == '0')
+            !($row['thread_replies'] == '0' && $row['visibility'] == '0')
         ) {
 
             $my_whatsnew_post_info = null;
@@ -541,60 +539,22 @@ if (is_array($threads)) {
                 . Display::return_icon('post-item.png', null, null, ICON_SIZE_TINY)
                 . ' ' . $last_post;
             $html .= '</div>';
-
-            /*
-            if ($row['last_poster_user_id'] == '0') {
-                $name = $row['poster_name'];
-                $last_poster_username = "";
-            } else {
-                $name = api_get_person_name($row['last_poster_firstname'], $row['last_poster_lastname']);
-                $tab_last_poster_info = api_get_user_info($row['last_poster_user_id']);
-                $last_poster_username = sprintf(get_lang('LoginX'), $tab_last_poster_info['username']);
-            }
-            // If the last post is invisible and it is not the teacher who is looking then we have to find the last visible post of the thread.
-            if (($row['visible'] == '1' OR api_is_allowed_to_edit(false, true)) && $origin != 'learnpath') {
-                $last_post = $post_date.' '.get_lang('By').' '.display_user_link($row['last_poster_user_id'], $name, '', $last_poster_username);
-            } elseif ($origin != 'learnpath') {
-                $last_post_sql = "SELECT post.*, user.firstname, user.lastname, user.username FROM $table_posts post, $table_users user WHERE post.poster_id=user.user_id AND visible='1' AND thread_id='".$row['thread_id']."' AND post.c_id=".api_get_course_int_id()." ORDER BY post_id DESC";
-                $last_post_result = Database::query($last_post_sql);
-                $last_post_row = Database::fetch_array($last_post_result);
-                $name = api_get_person_name($last_post_row['firstname'], $last_post_row['lastname']);
-                $last_post_info_username = sprintf(get_lang('LoginX'), $last_post_row['username']);
-                $last_post = api_convert_and_format_date($last_post_row['post_date']).' '.get_lang('By').' '.display_user_link($last_post_row['poster_id'], $name, '', $last_post_info_username);
-            } else {
-                $last_post_sql = "SELECT post.*, user.firstname, user.lastname, user.username FROM $table_posts post, $table_users user WHERE post.poster_id=user.user_id AND visible='1' AND thread_id='".$row['thread_id']."' AND post.c_id=".api_get_course_int_id()." ORDER BY post_id DESC";
-                $last_post_result = Database::query($last_post_sql);
-                $last_post_row = Database::fetch_array($last_post_result);
-                $last_post_info_username = sprintf(get_lang('LoginX'), $last_post_row['username']);
-                $name = api_get_person_name($last_post_row['firstname'], $last_post_row['lastname']);
-                $last_post = api_convert_and_format_date($last_post_row['post_date']).' '.get_lang('By').' '.Display::tag('span', $name, array("title"=>api_htmlentities($last_post_info_username, ENT_QUOTES)));
-            }*/
-
-
             $html .= '<div class="col-md-3">';
+            $cidreq = api_get_cidreq();
+
             // Get attachment id.
             if (isset($row['post_id'])) {
                 $attachment_list = get_attachment($row['post_id']);
             }
             $id_attach = !empty($attachment_list) ? $attachment_list['id'] : '';
-
-            $sql = "SELECT post_id
-                    FROM $table_posts
-                    WHERE
-                        c_id = $course_id AND
-                        post_title='" . Database::escape_string($row['thread_title']) . "' AND
-                        thread_id = ".$row['thread_id']."
-            ";
-
-            $result_post_id = Database::query($sql);
-            $row_post_id = Database::fetch_array($result_post_id);
             $iconsEdit = '';
             if ($origin != 'learnpath') {
                 if (api_is_allowed_to_edit(false, true) &&
-                    !(api_is_course_coach() && $current_forum['session_id'] != $sessionId)) {
-                    $iconsEdit .= '<a href="' . $forumUrl . 'editpost.php?' . api_get_cidreq()
-                        . '&forum=' . Security::remove_XSS($my_forum) . '&thread='
-                        . Security::remove_XSS($row['thread_id']) . '&post=' . $row_post_id['post_id']
+                    !(api_is_course_coach() && $current_forum['session_id'] != $sessionId)
+                ) {
+                    $iconsEdit .= '<a href="' . $forumUrl . 'editthread.php?' . $cidreq
+                        . '&forum=' . intval($my_forum) . '&thread='
+                        . intval($row['thread_id'])
                         . '&id_attach=' . $id_attach . '">'
                         . Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL) . '</a>';
 
@@ -606,8 +566,8 @@ if (is_array($threads)) {
                             ICON_SIZE_SMALL
                         );
                     } else {
-                        $iconsEdit.= '<a href="' . api_get_self() . '?' . api_get_cidreq() . '&forum='
-                            . Security::remove_XSS($my_forum) . '&action=delete&content=thread&id='
+                        $iconsEdit.= '<a href="' . api_get_self() . '?' . $cidreq . '&forum='
+                            . intval($my_forum) . '&action=delete&content=thread&id='
                             . $row['thread_id'] . $origin_string
                             . "\" onclick=\"javascript:if(!confirm('"
                             . addslashes(api_htmlentities(get_lang('DeleteCompleteThread'), ENT_QUOTES))
@@ -635,8 +595,8 @@ if (is_array($threads)) {
                             'gidReq' => api_get_group_id()
                         )
                     );
-                    $iconsEdit .= '<a href="viewforum.php?' . api_get_cidreq() . '&forum='
-                        . Security::remove_XSS($my_forum)
+                    $iconsEdit .= '<a href="viewforum.php?' . $cidreq . '&forum='
+                        . intval($my_forum)
                         . '&action=move&thread=' . $row['thread_id'] . $origin_string . '">'
                         . Display::return_icon('move.png', get_lang('MoveThread'), array(), ICON_SIZE_SMALL)
                         . '</a>';
@@ -685,8 +645,6 @@ if (is_array($threads)) {
 echo '</div>';
 echo isset($table_list) ? $table_list : '';
 
-/* FOOTER */
-
 if ($origin != 'learnpath') {
     Display::display_footer();
 }

+ 1 - 1
main/forum/viewpost.php

@@ -64,7 +64,7 @@ if ($origin == 'learnpath') {
         'name' => prepare4display($current_forum_category['cat_title']),
     );
     $interbreadcrumb[] = array(
-        'url' => 'viewforum.php?'.api_get_cidreq().'&forum='.Security::remove_XSS($_GET['forum']).'&origin='.$origin.'&search='.Security::remove_XSS(urlencode($_GET['search'])),
+        'url' => 'viewforum.php?'.api_get_cidreq().'&forum='.intval($_GET['forum']).'&origin='.$origin.'&search='.Security::remove_XSS(urlencode($_GET['search'])),
         'name' => prepare4display($current_forum['forum_title']),
     );
 

+ 4 - 4
main/forum/viewthread.php

@@ -159,7 +159,7 @@ if ($my_message != 'PostDeletedSpecial') {
     echo '<span style="float:right;">'.search_link().'</span>';
     if ($origin != 'learnpath') {
         echo '<a href="' . $forumUrl . 'viewforum.php?forum='
-            . Security::remove_XSS($_GET['forum']) . '&' . api_get_cidreq() . '">'
+            . intval($_GET['forum']) . '&' . api_get_cidreq() . '">'
             . Display::return_icon('back.png', get_lang('BackToForum'), '', ICON_SIZE_MEDIUM) . '</a>';
     }
     // The reply to thread link should only appear when the forum_category is
@@ -177,8 +177,8 @@ if ($my_message != 'PostDeletedSpecial') {
             // reply link
             if (!api_is_anonymous() && api_is_allowed_to_session_edit(false, true)) {
                 echo '<a href="' . $forumUrl . 'reply.php?' . api_get_cidreq() . '&forum='
-                    . Security::remove_XSS($_GET['forum']) . '&thread='
-                    . Security::remove_XSS($_GET['thread']) . '&action=replythread">'
+                    . intval($_GET['forum']) . '&thread='
+                    . intval($_GET['thread']) . '&action=replythread">'
                     . Display::return_icon('reply_thread.png', get_lang('ReplyToThread'), '', ICON_SIZE_MEDIUM)
                     . '</a>';
             }
@@ -203,7 +203,7 @@ if ($my_message != 'PostDeletedSpecial') {
     // The different views of the thread.
     if ($origin != 'learnpath') {
         $my_url = '<a href="' . $forumUrl . 'viewthread.php?' . api_get_cidreq() . '&' . api_get_cidreq()
-            . '&forum=' . Security::remove_XSS($_GET['forum']) . '&thread=' . Security::remove_XSS($_GET['thread'])
+            . '&forum=' . intval($_GET['forum']) . '&thread=' . intval($_GET['thread'])
             . '&search=' . Security::remove_XSS(urlencode($my_search));
         echo $my_url . '&view=flat">'
             . Display::return_icon('forum_listview.png', get_lang('FlatView'), null, ICON_SIZE_MEDIUM)

+ 4 - 1
main/forum/viewthread_flat.inc.php

@@ -120,7 +120,7 @@ if (isset($current_thread['thread_id'])) {
 
             if ($origin != 'learnpath') {
                 if (api_get_course_setting('allow_user_image_forum')) {
-                    $html .= '<div class="thumbnail">' . display_user_image($row['user_id'], $name) . '</div>';
+                    $html .= '<div class="thumbnail">' . display_user_image($row['user_id'], $name, $origin) . '</div>';
                 }
                 $html .= Display::tag(
                     'h4',
@@ -128,6 +128,9 @@ if (isset($current_thread['thread_id'])) {
                     array('class' => 'title-username')
                 );
             } else {
+                if (api_get_course_setting('allow_user_image_forum')) {
+                    $html .= '<div class="thumbnail">' . display_user_image($row['user_id'], $name, $origin) . '</div>';
+                }
                 $name = Display::tag('strong', "#" . $postCount--, ['class' => 'text-info']) . " | $name";
                 $html .= Display::tag(
                     'p',

+ 4 - 0
main/forum/viewthread_nested.inc.php

@@ -82,6 +82,10 @@ foreach ($rows as $post) {
             array('class' => 'title-username')
         );
     } else {
+        if (api_get_course_setting('allow_user_image_forum')) {
+            $html .= '<div class="thumbnail">' . display_user_image($post['user_id'], $name, $origin) . '</div>';
+        }
+        
         $html .= Display::tag(
             'p',
             $name,

+ 2 - 3
main/group/member_settings.php

@@ -140,9 +140,8 @@ $userGroup = new UserGroup();
 if (!empty($complete_user_list)) {
     usort($complete_user_list, 'sort_users');
     foreach ($complete_user_list as $index => $user) {
-        
-        //prevent invitee users add to groups - see #8091
-        if ($user['status'] != 20) {
+        //prevent invitee users add to groups or tutors - see #8091
+        if ($user['status'] != INVITEE) {
             $officialCode = !empty($user['official_code']) ? ' - '.$user['official_code'] : null;
 
             $groups = $userGroup->getUserGroupListByUser($user['user_id']);

+ 8 - 8
main/group/settings.php

@@ -78,7 +78,7 @@ $group = array(
     $form->createElement('checkbox', 'self_registration_allowed', get_lang('GroupSelfRegistration'), get_lang('GroupAllowStudentRegistration'), 1),
     $form->createElement('checkbox', 'self_unregistration_allowed', null, get_lang('GroupAllowStudentUnregistration'), 1)
 );
-$form->addGroup($group, '', Display::return_icon('user.png', get_lang('GroupSelfRegistration'), array(), ICON_SIZE_SMALL).' '.get_lang('GroupSelfRegistration'), '', false);
+$form->addGroup($group, '', Display::return_icon('user.png', get_lang('GroupSelfRegistration'), array(), ICON_SIZE_SMALL).'<span>'.get_lang('GroupSelfRegistration').'</span>', '', false);
 
 // Documents settings
 $group = array(
@@ -86,7 +86,7 @@ $group = array(
     $form->createElement('radio', 'doc_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
     $form->createElement('radio', 'doc_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE)
 );
-$form->addGroup($group, '', Display::return_icon('folder.png', get_lang('GroupDocument'), array(), ICON_SIZE_SMALL).' '.get_lang('GroupDocument'), '', false);
+$form->addGroup($group, '', Display::return_icon('folder.png', get_lang('GroupDocument'), array(), ICON_SIZE_SMALL).'<span>'.get_lang('GroupDocument').'</span>', '', false);
 
 // Work settings
 $group = array(
@@ -94,7 +94,7 @@ $group = array(
     $form->createElement('radio', 'work_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
     $form->createElement('radio', 'work_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE)
 );
-$form->addGroup($group, '', Display::return_icon('work.png', get_lang('GroupWork'), array(), ICON_SIZE_SMALL).' '.get_lang('GroupWork'), '', false);
+$form->addGroup($group, '', Display::return_icon('works.png', get_lang('GroupWork'), array(), ICON_SIZE_SMALL).'<span>'.get_lang('GroupWork').'</span>', '', false);
 
 // Calendar settings
 $group = array(
@@ -102,7 +102,7 @@ $group = array(
     $form->createElement('radio', 'calendar_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
     $form->createElement('radio', 'calendar_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE)
 );
-$form->addGroup($group, '', Display::return_icon('agenda.png', get_lang('GroupCalendar'), array(), ICON_SIZE_SMALL).' '.get_lang('GroupCalendar'), '', false);
+$form->addGroup($group, '', Display::return_icon('agenda.png', get_lang('GroupCalendar'), array(), ICON_SIZE_SMALL).'<span>'.get_lang('GroupCalendar').'</span>', '', false);
 
 $form->addElement('html', '</div>');
 $form->addElement('html', '<div class="col-md-6">');
@@ -113,7 +113,7 @@ $group = array(
     $form->createElement('radio', 'announcements_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
     $form->createElement('radio', 'announcements_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE)
 );
-$form->addGroup($group, '', Display::return_icon('announce.png', get_lang('GroupAnnouncements'), array(), ICON_SIZE_SMALL).' '.get_lang('GroupAnnouncements'), '', false);
+$form->addGroup($group, '', Display::return_icon('announce.png', get_lang('GroupAnnouncements'), array(), ICON_SIZE_SMALL).'<span>'.get_lang('GroupAnnouncements').'</span>', '', false);
 
 // Forum settings
 $group = array(
@@ -121,7 +121,7 @@ $group = array(
     $form->createElement('radio', 'forum_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
     $form->createElement('radio', 'forum_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE)
 );
-$form->addGroup($group, '', Display::return_icon('forum.png', get_lang('GroupForum'), array(), ICON_SIZE_SMALL).' '.get_lang('GroupForum'), '', false);
+$form->addGroup($group, '', Display::return_icon('forum.png', get_lang('GroupForum'), array(), ICON_SIZE_SMALL).'<span>'.get_lang('GroupForum').'</span>', '', false);
 
 // Wiki settings
 $group = array(
@@ -129,7 +129,7 @@ $group = array(
     $form->createElement('radio', 'wiki_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
     $form->createElement('radio', 'wiki_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE)
 );
-$form->addGroup($group, '', Display::return_icon('wiki.png', get_lang('GroupWiki'), array(), ICON_SIZE_SMALL).' '.get_lang('GroupWiki'), '', false);
+$form->addGroup($group, '', Display::return_icon('wiki.png', get_lang('GroupWiki'), array(), ICON_SIZE_SMALL).'<span>'.get_lang('GroupWiki').'</span>', '', false);
 
 // Chat settings
 $group = array(
@@ -137,7 +137,7 @@ $group = array(
     $form->createElement('radio', 'chat_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
     $form->createElement('radio', 'chat_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE)
 );
-$form->addGroup($group, '', Display::return_icon('chat.png', get_lang('Chat'), array(), ICON_SIZE_SMALL).' '.get_lang('Chat'), '', false);
+$form->addGroup($group, '', Display::return_icon('chat.png', get_lang('Chat'), array(), ICON_SIZE_SMALL).'<span>'.get_lang('Chat').'</span>', '', false);
 
 $form->addElement('html', '</div>');
 $form->addElement('html', '<div class="col-md-12">');

+ 21 - 17
main/group/tutor_settings.php

@@ -132,27 +132,31 @@ if (!empty($complete_user_list)) {
     usort($complete_user_list, 'sort_users');
 
     foreach ($complete_user_list as $index => $user) {
-        $officialCode = !empty($user['official_code']) ? ' - '.$user['official_code'] : null;
-        $groups = $userGroup->getUserGroupListByUser($user['user_id']);
-        $groupNameListToString = '';
-        if (!empty($groups)) {
-            $groupNameList = array_column($groups, 'name');
-            $groupNameListToString = ' - ['.implode(', ', $groupNameList).']';
-        }
-
-        $name = api_get_person_name(
-                $user['firstname'],
-                $user['lastname']
-            ).' ('.$user['username'].')'.$officialCode;
+        //prevent invitee users add to groups or tutors - see #8091
+        if ($user['status'] != INVITEE) {
+            $officialCode = !empty($user['official_code']) ? ' - '.$user['official_code'] : null;
+            
+            $groups = $userGroup->getUserGroupListByUser($user['user_id']);
+            $groupNameListToString = '';
+            if (!empty($groups)) {
+                $groupNameList = array_column($groups, 'name');
+                $groupNameListToString = ' - ['.implode(', ', $groupNameList).']';
+            }
 
-        if ($orderUserListByOfficialCode === 'true') {
-            $officialCode = !empty($user['official_code']) ? $user['official_code']." - " : '? - ';
-            $name = $officialCode." ".api_get_person_name(
+            $name = api_get_person_name(
                     $user['firstname'],
                     $user['lastname']
-                ).' ('.$user['username'].')';
+                ).' ('.$user['username'].')'.$officialCode;
+
+            if ($orderUserListByOfficialCode === 'true') {
+                $officialCode = !empty($user['official_code']) ? $user['official_code']." - " : '? - ';
+                $name = $officialCode." ".api_get_person_name(
+                        $user['firstname'],
+                        $user['lastname']
+                    ).' ('.$user['username'].')';
+            }
+            $possible_users[$user['user_id']] = $name.$groupNameListToString;
         }
-        $possible_users[$user['user_id']] = $name.$groupNameListToString;
     }
 }
 

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

@@ -868,8 +868,8 @@ class AddCourse
             $exercise->exercise = get_lang('ExerciceEx');
             $html = '<table width="100%" border="0" cellpadding="0" cellspacing="0">
                         <tr>
-                        <td width="110" valign="top" align="left">
-                            <img src="' . api_get_path(WEB_CODE_PATH) . 'default_course_document/images/mr_dokeos/thinking.jpg">
+                        <td width="220" valign="top" align="left">
+                            <img src="' . api_get_path(WEB_CODE_PATH) . 'default_course_document/images/mr_chamilo/doubts.png">
                         </td>
                         <td valign="top" align="left">' . get_lang('Antique') . '</td></tr>
                     </table>';

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

@@ -5380,6 +5380,7 @@ function api_get_access_url($id, $returnDefault = true)
             }
         }
     }
+
     return $result;
 }
 

+ 5 - 5
main/inc/lib/formvalidator/FormValidator.class.php

@@ -1367,7 +1367,7 @@ EOT;
             $('#".$inputName."').fileupload({
                 url: url,
                 dataType: 'json',
-                autoUpload: false,
+                autoUpload: true,
                 // Enable image resizing, except for Android and Opera,
                 // which actually support image resizing, but fail to
                 // send Blob objects via XHR requests:
@@ -1378,16 +1378,16 @@ EOT;
                 dropzone: $('#dropzone')
              }).on('fileuploadadd', function (e, data) {
                 data.context = $('<div/>').appendTo('#files');
-
                 $.each(data.files, function (index, file) {
                     var node = $('<p/>').append($('<span/>').text(file.name));
-                    if (!index) {
+                    /*if (!index) {
                         node
                             .append('<br>')
                             .append(uploadButton.clone(true).data(data));
-                    }
+                    }*/
                     node.appendTo(data.context);
-                });
+                }
+            );
             }).on('fileuploadprocessalways', function (e, data) {
                 var index = data.index,
                     file = data.files[index],

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

@@ -2728,7 +2728,7 @@ class GroupManager
         $url = api_get_path(WEB_CODE_PATH).'group/%s?'.api_get_cidreq();
 
         echo '
-            <ul class="nav nav-tabs">
+            <ul class="toolbar-groups nav nav-tabs">
                 <li class="'.$activeSettings.'">
                     <a href="'.sprintf($url, 'settings.php').'">
                     '.Display::return_icon('settings.png').' '.get_lang('Settings').'

+ 6 - 2
main/inc/lib/sub_language.class.php

@@ -16,16 +16,20 @@ class SubLanguageManager
     
     /**
      * Get all the languages
+     * @param bool $onlyActive Whether to return only active languages (default false)
      * @return Array All information about sub-language
      */
-    public static function getAllLanguages()
+    public static function getAllLanguages($onlyActive = false)
     {
         $table = Database :: get_main_table(TABLE_MAIN_LANGUAGE);
         $sql = 'SELECT * FROM ' . $table;
+        if ($onlyActive) {
+            $sql .= ' WHERE available = 1';
+        }
         $rs = Database::query($sql);
         $all_languages = [];
         while ($row = Database::fetch_array($rs, 'ASSOC')) {
-            $all_languages[] = $row;
+            $all_languages[$row['dokeos_folder']] = $row;
         }
         
         return $all_languages;

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

@@ -728,7 +728,7 @@ class UserManager
      * @param int The user ID of the person who registered this user (optional, defaults to null)
      * @param int The department of HR in which the user is registered (optional, defaults to 0)
      * @param array A series of additional fields to add to this user as extra fields (optional, defaults to null)
-     * @return boolean true if the user information was updated
+     * @return boolean|integer False on error, or the user ID if the user information was updated
      * @assert (false, false, false, false, false, false, false, false, false, false, false, false, false) === false
      */
     public static function update_user(

+ 11 - 3
main/lang/brazilian/trad4all.inc.php

@@ -796,7 +796,7 @@ $Reject = "Rejeitar";
 $SendingRequestToFollowingUsers = "Envio de requisição aos seguintes usuários";
 $Accepted = "Aceitado";
 $Rejected = "Rejeitado";
-$ChangeModerator = "Change Moderador";
+$ChangeModerator = "Mudança de Moderador";
 $YouAreNotModeratingThisCourse = "Você não é moderador.";
 $Moderator = "Moderador";
 $ThisRoomIsFullPleaseTryAgain = "Esta sala está cheia Desculpe por favor, tente novamente mais tarde..";
@@ -7534,8 +7534,8 @@ $CropYourPicture = "Cortar sua imagem";
 $DownloadBadge = "Baixar emblema";
 $NoXMLFileFoundInTheZip = "Nenhum arquivo XML encontrado no arquivo zip Este é um requisito para este tipo de importação.";
 $BakedBadgeProblem = "Houve um problema ao incorporar a informação afirmação distintivo na imagem emblema, mas você ainda pode usar esta página como uma prova válida.";
-$ConfirmAssociateForumToLPItem = "Confirme item associado mo Fórum ToLP";
-$ConfirmDissociateForumToLPItem = "Confirme item dissociar do Fórum ToLP";
+$ConfirmAssociateForumToLPItem = "Esta ação irá associar um tópico do fórum para este item caminho de aprendizagem. Você quer prosseguir?";
+$ConfirmDissociateForumToLPItem = "Esta ação irá dissociar a discussão no fórum deste item da rota de aprendizagem. Você quer prosseguir?";
 $DissociateForumToLPItem = "Dissociar o item do fórum desta  Rota de aprendizagem";
 $AssociateForumToLPItem = "Associar um item do fórum para esta  Rota de aprendizagem";
 $ForumDissociated = "Fórum dissociado";
@@ -7543,4 +7543,12 @@ $ClickOrDropOneFileHere = "Clique ou soltar um arquivo aqui";
 $ModuloPercentage = "Modulo:\t\t\t%";
 $LastXDays = "Último % dias";
 $ExportBadges = "Exportação de emblemas";
+$LanguagesDisableAllExceptDefault = "Desativar todas as línguas, exceto o padrão da plataforma.";
+$ThereAreUsersUsingThisLanguagesDisableItManually = "Há usuários que atualmente usam a seguinte linguagem. Por favor, desativar manualmente.";
+$MessagingAllowSendPushNotificationTitle = "Permitir enviar notificações push para o aplicativo móvel Chamilo Mensagens";
+$MessagingAllowSendPushNotificationComment = "Enviar Push Notificações pelo Google Cloud Mensagens";
+$MessagingGDCProjectNumberTitle = "Número do projeto de Google Developer Console";
+$MessagingGDCProjectNumberComment = "Você precisa registrar um projeto no Google Developer Console";
+$MessagingGDCApiKeyTitle = "Key API do Google Developer Console para o Google Cloud Mensagens";
+$MessagingGDCApiKeyComment = "Você precisa ativar a API do Google Cloud Mensagens e criar uma credencial para Android";
 ?>

+ 1 - 1
main/lang/bulgarian/trad4all.inc.php

@@ -2494,7 +2494,7 @@ $AddNewQuestionType = "Добавяне на нов тип въпрос";
 $Numbered = "Номериран";
 $iso639_2_code = "bg";
 $iso639_1_code = "bg";
-$charset = "windows-1251";
+$charset = "utf-8";
 $text_dir = "ltr";
 $left_font_family = "verdana, helvetica, arial, geneva, sans-serif";
 $right_font_family = "helvetica, arial, geneva, sans-serif";

+ 2 - 1
main/lang/english/trad4all.inc.php

@@ -7614,10 +7614,11 @@ $LastXDays = "Last % days";
 $ExportBadges = "Export badges";
 $LanguagesDisableAllExceptDefault = "Disable all languages except the platform default";
 $ThereAreUsersUsingThisLanguagesDisableItManually = "There are users currently using the following language. Please disable manually.";
-$MessagingAllowSendPushNotificationTitle = "Allow send Push Notifications to the Chamilo Messaging mobile app";
+$MessagingAllowSendPushNotificationTitle = "Allow Push Notifications to the Chamilo Messaging mobile app";
 $MessagingAllowSendPushNotificationComment = "Send Push Notifications by Google Cloud Messaging";
 $MessagingGDCProjectNumberTitle = "Project number of Google Developer Console";
 $MessagingGDCProjectNumberComment = "You need register a project on <a href=\"https://console.developers.google.com/\">Google Developer Console</a>";
 $MessagingGDCApiKeyTitle = "API Key of Google Developer Console for Google Cloud Messaging";
 $MessagingGDCApiKeyComment = "You need enable the Google Cloud Messaging API and create one credential for Android";
+$Overwrite = "Overwrite";
 ?>

+ 2 - 0
main/lang/french/trad4all.inc.php

@@ -7601,4 +7601,6 @@ $LastXDays = "Derniers %s jours";
 $ExportBadges = "Exporter badges";
 $LanguagesDisableAllExceptDefault = "Désactiver toutes les langues execpté celle par défaut de la plateforme";
 $ThereAreUsersUsingThisLanguagesDisableItManually = "Des utilisateurs utilisent encore la langue suivante. Veuillez la désactiver manuellement.";
+$MessagingAllowSendPushNotificationTitle = "Permettre l'envoi de notifications Push à l'application mobile Chamilo Messaging";
+$Overwrite = "Écraser";
 ?>

+ 1 - 0
main/lang/japanese/trad4all.inc.php

@@ -1288,6 +1288,7 @@ $CourseResources = "Course resources";
 $ExternalLink = "External link";
 $DropboxAdd = "Add the dropbox page to this chapter.";
 $AddAssignmentPage = "課題ツールをコースに追加";
+$IntroductionText = "このコースへようこそ";
 $CourseDescription = "コースの説明";
 $LinkTarget = "リンク先";
 $AgendaAdd = "イベントを追加";

+ 1 - 1
main/lang/russian/trad4all.inc.php

@@ -1830,7 +1830,7 @@ $AddNewQuestionType = "Добавить новый тип вопроса";
 $Numbered = "Пронумерованный";
 $iso639_2_code = "ru";
 $iso639_1_code = "rus";
-$charset = "iso-8859-5 (стандарт ISO для кодировки русских текстов)";
+$charset = "utf-8";
 $text_dir = "лтр (литера)";
 $left_font_family = "verdana, helvetica, arial, geneva, sans-serif (шрифты)";
 $right_font_family = "helvetica, arial, geneva, sans-serif (шрифты)";

+ 2 - 1
main/lang/simpl_chinese/trad4all.inc.php

@@ -1764,7 +1764,7 @@ $AddNewQuestionType = "添加新的问题类型";
 $Numbered = "数字化的";
 $iso639_2_code = "zh";
 $iso639_1_code = "zho";
-$charset = "字符编码";
+$charset = "utf-8";
 $text_dir = "ltr";
 $left_font_family = "verdana, helvetica, arial, geneva, sans-serif";
 $right_font_family = "helvetica, arial, geneva, sans-serif";
@@ -3583,4 +3583,5 @@ $EditBlocks = "编辑资料块";
 $EndDateMustBeMoreThanStartDate = "结束日期需迟于开始日期";
 $ToolSearch = "搜索";
 $NewImage = "新图片";
+$Administration = "行政";
 ?>

+ 1 - 0
main/lang/spanish/trad4all.inc.php

@@ -7645,4 +7645,5 @@ $MessagingGDCProjectNumberTitle = "Número de proyecto de Google Developer Conso
 $MessagingGDCProjectNumberComment = "Necesita registrar un proyecto en <a href=\"https://console.developers.google.com/\">Google Developer Console</a>";
 $MessagingGDCApiKeyTitle = "API key de Google Developer Console para Google Cloud Messaging";
 $MessagingGDCApiKeyComment = "Necesita habilitar la API de Google Cloud Messaging y crear una credencial para Android";
+$Overwrite = "Sobreescribir";
 ?>

+ 4 - 4
main/newscorm/lp_view_item.php

@@ -83,16 +83,16 @@ if (api_is_in_gradebook()) {
 }
 
 $interbreadcrumb[] = array(
-    'url' => 'lp_controller.php?action=list&'.api_get_cidreq(),
-    'name' => get_lang('LearningPaths'),
+    'url' => api_get_path(WEB_CODE_PATH).'newscorm/lp_controller.php?action=list&'.api_get_cidreq(),
+    'name' => get_lang('LearningPaths')
 );
 $interbreadcrumb[] = array(
     'url' => api_get_self()."?action=build&lp_id=$learnpath_id&".api_get_cidreq(),
-    'name' => $therow['name'],
+    'name' => $therow['name']
 );
 $interbreadcrumb[] = array(
     'url' => api_get_self()."?action=add_item&type=step&lp_id=$learnpath_id&".api_get_cidreq(),
-    'name' => get_lang('NewStep'),
+    'name' => get_lang('NewStep')
 );
 
 // Theme calls

+ 4 - 0
main/template/default/agenda/month.tpl

@@ -245,6 +245,10 @@ $(document).ready(function() {
 			}
 	    },
 		eventClick: function(calEvent, jsEvent, view) {
+            if (!calEvent.end) {
+                calEvent.end = calEvent.start;
+            }
+
             var start_date = calEvent.start.format("YY-MM-DD");
 
             if (calEvent.allDay == 1) {

+ 5 - 1
main/template/default/layout/head.tpl

@@ -2,9 +2,13 @@
 <link href="https://chamilo.org/chamilo-lms/" rel="help" />
 <link href="https://chamilo.org/the-association/" rel="author" />
 <link href="https://chamilo.org/the-association/" rel="copyright" />
+<!-- Force latest IE rendering engine or ChromeFrame if installed -->
+<!--[if IE]>
+<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+<![endif]-->
+
 {{ prefetch }}
 {{ favico }}
-{{ browser_specific_head }}
 <link rel="apple-touch-icon" href="{{ _p.web }}apple-touch-icon.png" />
 <meta name="apple-mobile-web-app-capable" content="yes" />
 <meta name="Generator" content="{{ _s.software_name }} {{ _s.system_version|slice(0,1) }}" />

+ 18 - 24
main/user/user.php

@@ -76,31 +76,19 @@ if (api_is_allowed_to_edit(null, true)) {
             case 'set_tutor':
                 $userId = isset($_GET['user_id']) ? intval($_GET['user_id']) : null;
                 $isTutor = isset($_GET['is_tutor']) ? intval($_GET['is_tutor']) : 0;
+                $userInfo = api_get_user_info($userId);
+                
                 if (!empty($userId)) {
-                    if ($sessionId) {
-                        /*$res = SessionManager::set_coach_to_course_session(
-                            $userId,
-                            $sessionId,
-                            $courseCode,
-                            true
-                        );*/
-                    } else {
-                        /*if (!empty($_POST['promoteCourseAdmin']) && $_POST['promoteCourseAdmin']){
-                            $userProperties['status'] = 1;
-                        } else{
-                            $userProperties['status'] = 5;
+                    if (!$sessionId) {
+                        if ($userInfo['status'] != INVITEE) {
+                            CourseManager::updateUserCourseTutor(
+                                $userId,
+                                $courseId,
+                                $isTutor
+                            );
+                        } else {
+                            Display::addFlash(Display::return_message(get_lang('InviteesCantBeTutors'), 'error'));
                         }
-                        if (!empty($_POST['promoteTutor']) && $_POST['promoteTutor']){
-                            $userProperties['tutor'] = 1;
-                        } else{
-                            $userProperties['tutor'] = 0;
-                        }*/
-
-                        CourseManager::updateUserCourseTutor(
-                            $userId,
-                            $courseId,
-                            $isTutor
-                        );
                     }
                 }
                 break;
@@ -773,6 +761,8 @@ function modify_filter($user_id, $row, $data)
     global $is_allowed_to_track, $charset;
 
     $user_id = $data[0];
+    $userInfo = api_get_user_info($user_id);
+    $isInvitee = $userInfo['status'] == INVITEE ? true : false;
     $course_info = $_course = api_get_course_info();
     $current_user_id = api_get_user_id();
     $sessionId = api_get_session_id();
@@ -806,7 +796,11 @@ function modify_filter($user_id, $row, $data)
                 $text = get_lang('SetTutor');
             }
 
-            $disabled = '';
+            if ($isInvitee) {
+                $disabled = 'disabled';
+            } else {
+                $disabled = '';
+            }
 
             if ($data['user_status_in_course'] == STUDENT) {
 

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

@@ -5796,6 +5796,20 @@ function WSUnsuscribeCoursesFromSession($params)
 
 /** WSListCourses **/
 
+$server->wsdl->addComplexType(
+    'listCourseInput',
+    'complexType',
+    'struct',
+    'all',
+    '',
+    array(
+        'secret_key' => array('name' => 'secret_key', 'type' => 'xsd:string'),
+        'original_course_id_name' => array('name' => 'original_course_id_name', 'type' => 'xsd:string'),
+        'from' => array('name' => 'from', 'type' => 'xsd:int'),
+        'to' => array('name' => 'to', 'type' => 'xsd:int')
+    )
+);
+
 $server->wsdl->addComplexType(
     'course',
     'complexType',
@@ -5828,7 +5842,7 @@ $server->wsdl->addComplexType(
 
 // Register the method to expose
 $server->register('WSListCourses',                                                  // method name
-    array('secret_key' => 'xsd:string', 'original_course_id_name' => 'xsd:string'), // input parameters
+    array('listCourseInput' => 'tns:listCourseInput'), // input parameters
     array('return' => 'tns:courses'),                                               // output parameters
     'urn:WSRegistration',                                                           // namespace
     'urn:WSRegistration#WSListCourses',                                             // soapaction
@@ -5849,7 +5863,15 @@ function WSListCourses($params)
     $courses_result = array();
     $category_names = array();
 
-    $courses = CourseManager::get_courses_list();
+    $from = isset($params['from']) ? $params['from'] : null;
+    $to = isset($params['to']) ? $params['to'] : null;
+
+    error_log(print_r($params,1));
+    error_log($from);
+    error_log($to);
+
+    $courses = CourseManager::get_courses_list($from, $to);
+
     foreach ($courses as $course) {
         $course_tmp = array();
         $course_tmp['id'] = $course['id'];
@@ -5857,16 +5879,19 @@ function WSListCourses($params)
         $course_tmp['title'] = $course['title'];
         $course_tmp['language'] = $course['course_language'];
         $course_tmp['visibility'] = $course['visibility'];
+        $course_tmp['category_name'] = '';
 
         // Determining category name
         if (!empty($course['category_code']) &&
-            $category_names[$course['category_code']]
+            isset($category_names[$course['category_code']])
         ) {
             $course_tmp['category_name'] = $category_names[$course['category_code']];
         } else {
             $category = CourseManager::get_course_category($course['category_code']);
-            $category_names[$course['category_code']] = $category['name'];
-            $course_tmp['category_name'] = $category['name'];
+            if ($category) {
+                $category_names[$course['category_code']] = $category['name'];
+                $course_tmp['category_name'] = $category['name'];
+            }
         }
 
         // Determining number of students registered in course
@@ -5888,7 +5913,6 @@ function WSListCourses($params)
     }
 
     return $courses_result;
-
 }
 
 

+ 92 - 3
tests/datafiller/data_courses.php

@@ -13,7 +13,7 @@ $courses[] = array(
     'code' => 'ENGLISH101',
     'title' => 'English for beginners',
     'description' => 'English course',
-    'category_code' => 'PROJ',
+    'category_code' => 'LANG',
     'course_language' => 'en',
     'user_id' => 1,
     'expiration_date' => '2020-09-01 00:00:00',
@@ -23,7 +23,7 @@ $courses[] = array(
     'code' => 'SPANISH101',
     'title' => 'Español para iniciantes',
     'description' => 'Curso de español',
-    'category_code' => 'PROJ',
+    'category_code' => 'LANG',
     'course_language' => 'es',
     'user_id' => 1,
     'expiration_date' => '2020-09-01 00:00:00',
@@ -33,10 +33,99 @@ $courses[] = array(
     'code' => 'FRENCH101',
     'title' => 'Français pour débutants',
     'description' => 'Cours de français',
-    'category_code' => 'PROJ',
+    'category_code' => 'LANG',
     'course_language' => 'fr',
     'user_id' => 1,
     'expiration_date' => '2020-09-01 00:00:00',
     'exemplary_content' => true,
 );
 
+// 4
+$courses[] = array(
+    'code' => 'HISTLIT',
+    'title' => 'History of litterature',
+    'description' => 'History of English litterature from the Middle Ages to our times',
+    'category_code' => 'PROJ',
+    'course_language' => 'en',
+    'user_id' => 1,
+    'expiration_date' => '2020-09-01 00:00:00',
+    'exemplary_content' => true,
+);
+// 5
+$courses[] = array(
+    'code' => 'SOLARSYSTEM',
+    'title' => 'Our solar system',
+    'description' => 'Introduction to our solar system and the interactions between planets',
+    'category_code' => 'PROJ',
+    'course_language' => 'en',
+    'user_id' => 1,
+    'expiration_date' => '2020-09-01 00:00:00',
+    'exemplary_content' => true,
+);
+// 6
+$courses[] = array(
+    'code' => 'MARNAVIGATION',
+    'title' => 'Maritime Navigation',
+    'description' => 'Preparation course for the International Maritime Navigation exam',
+    'category_code' => 'PROJ',
+    'course_language' => 'en',
+    'user_id' => 1,
+    'expiration_date' => '2020-09-01 00:00:00',
+    'exemplary_content' => true,
+);
+// 7
+$courses[] = array(
+    'code' => 'NATGEO',
+    'title' => 'National Geography',
+    'description' => 'Introduction to geography at a national level',
+    'category_code' => 'PROJ',
+    'course_language' => 'en',
+    'user_id' => 1,
+    'expiration_date' => '2020-09-01 00:00:00',
+    'exemplary_content' => true,
+);
+// 8
+$courses[] = array(
+    'code' => 'JAPANESE101',
+    'title' => '日本語',
+    'description' => 'Japanese course for beginners',
+    'category_code' => 'LANG',
+    'course_language' => 'ja',
+    'user_id' => 1,
+    'expiration_date' => '2020-09-01 00:00:00',
+    'exemplary_content' => true,
+);
+// 9
+$courses[] = array(
+    'code' => 'TIMEMGMT',
+    'title' => 'Time management',
+    'description' => 'Learn to manage your time efficiently',
+    'category_code' => 'PROJ',
+    'course_language' => 'en',
+    'user_id' => 1,
+    'expiration_date' => '2020-09-01 00:00:00',
+    'exemplary_content' => true,
+);
+// 10
+$courses[] = array(
+    'code' => 'SCRUM',
+    'title' => 'SCRUM project management basics',
+    'description' => 'Introduction to SCRUM project management for busy people',
+    'category_code' => 'PROJ',
+    'course_language' => 'en',
+    'user_id' => 1,
+    'expiration_date' => '2020-09-01 00:00:00',
+    'exemplary_content' => true,
+);
+// 11
+$courses[] = array(
+    'code' => 'D2DMATHS',
+    'title' => 'Day to day mathematics',
+    'description' => 'Mathematics for busy people',
+    'category_code' => 'PROJ',
+    'course_language' => 'en',
+    'user_id' => 1,
+    'expiration_date' => '2020-09-01 00:00:00',
+    'exemplary_content' => true,
+);
+

+ 11 - 4
tests/datafiller/fill_courses.php

@@ -14,15 +14,22 @@
  */
 function fill_courses()
 {
-    $eol = PHP_EOL;
-    $courses = array(); //declare only to avoid parsing notice
-    require_once 'data_courses.php'; //fill the $users array
+    $courses = array(); // declare only to avoid parsing notice
+    require_once 'data_courses.php'; // fill the $courses array
     $output = array();
     $output[] = array('title'=>'Courses Filling Report: ');
+    $languages = SubLanguageManager::getAllLanguages(true);
     $i = 1;
     foreach ($courses as $i => $course) {
-        //first check that the first item doesn't exist already
+        // First check that the first item doesn't exist already
     	$output[$i]['line-init'] = $course['title'];
+        // The wanted code is necessary to avoid interpretation
+        $course['wanted_code'] = $course['code'];
+        // Make sure the language defaults to English if others are disabled
+        if (!isset($languages[$course['course_language']])) {
+            $course['course_language'] = 'english';
+        }
+        // Effectively create the course
         $res = CourseManager::create_course($course);
     	$output[$i]['line-info'] = $res ? get_lang('Added') : get_lang('NotInserted');
     	$i++;

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff