Browse Source

Solve merge conflict with 1.9.x - refs BT9022

Imanol Losada 10 years ago
parent
commit
e65f69c5e7
100 changed files with 2478 additions and 1504 deletions
  1. 2 0
      CONTRIBUTING.md
  2. 0 13
      custompages/README
  3. 24 0
      custompages/README.md
  4. 0 0
      custompages/first_login-dist.php
  5. 0 0
      custompages/index-logged-dist.php
  6. 0 0
      custompages/index-unlogged-dist.php
  7. 0 0
      custompages/loggedout-dist.php
  8. 0 0
      custompages/lostpassword-dist.php
  9. 0 0
      custompages/registration-dist.php
  10. 0 0
      custompages/registration-feedback-dist.php
  11. 49 29
      documentation/changelog.html
  12. 19 7
      index.php
  13. 7 0
      main/admin/add_users_to_session.php
  14. 8 11
      main/admin/configure_extensions.php
  15. 468 432
      main/admin/configure_homepage.php
  16. 5 6
      main/admin/course_category.php
  17. 1 1
      main/admin/example_class.csv
  18. 60 1
      main/admin/index.php
  19. 59 53
      main/admin/session_add.php
  20. 3 4
      main/admin/session_edit.php
  21. 6 2
      main/admin/sub_language.class.php
  22. 8 0
      main/admin/user_list.php
  23. 6 6
      main/admin/usergroup_export.php
  24. 26 6
      main/admin/usergroup_import.php
  25. 38 4
      main/calendar/agenda.lib.php
  26. 9 3
      main/calendar/agenda.php
  27. 8 0
      main/calendar/agenda_js.php
  28. 2 4
      main/calendar/agenda_list.php
  29. 1 1
      main/chat/chat_functions.lib.php
  30. 0 1
      main/course_home/activity.php
  31. 11 15
      main/course_home/course_home.php
  32. 3 5
      main/coursecopy/copy_course_session.php
  33. 0 4
      main/coursecopy/copy_course_session_selected.php
  34. 155 17
      main/cron/import_csv.php
  35. 24 0
      main/css/base.css
  36. 15 36
      main/css/chamilo/default.css
  37. 2 3
      main/css/responsive.css
  38. 9 11
      main/document/document.php
  39. 5 0
      main/document/downloadfolder.inc.php
  40. 16 6
      main/exercice/evalmathnotation.php
  41. 6 3
      main/exercice/exercise.class.php
  42. 107 55
      main/exercice/exercise.lib.php
  43. 8 2
      main/exercice/exercise_submit.php
  44. 26 29
      main/exercice/question_admin.inc.php
  45. 13 14
      main/exercice/question_create.php
  46. 175 172
      main/exercice/question_list_admin.inc.php
  47. 102 56
      main/exercice/stats.php
  48. 6 9
      main/exercice/testheaderpage.php
  49. 0 1
      main/exercice/unique_answer.class.php
  50. 4 3
      main/exercice/upload_exercise.php
  51. 27 3
      main/gradebook/exercise_jump.php
  52. 1 0
      main/gradebook/gradebook_add_link.php
  53. 9 1
      main/gradebook/gradebook_display_certificate.php
  54. 0 2
      main/gradebook/gradebook_flatview.php
  55. 5 1
      main/gradebook/index.php
  56. 1 0
      main/gradebook/lib/be/abstractlink.class.php
  57. 2 1
      main/gradebook/lib/be/attendancelink.class.php
  58. 62 29
      main/gradebook/lib/be/category.class.php
  59. 15 5
      main/gradebook/lib/be/evallink.class.php
  60. 48 18
      main/gradebook/lib/be/exerciselink.class.php
  61. 1 1
      main/gradebook/lib/be/learnpathlink.class.php
  62. 20 12
      main/gradebook/lib/be/studentpublicationlink.class.php
  63. 27 8
      main/gradebook/lib/be/surveylink.class.php
  64. 8 6
      main/gradebook/lib/fe/displaygradebook.php
  65. 20 25
      main/gradebook/lib/fe/flatviewtable.class.php
  66. 4 2
      main/gradebook/lib/fe/resulttable.class.php
  67. 2 2
      main/gradebook/lib/fe/usertable.class.php
  68. 40 17
      main/gradebook/lib/flatview_data_generator.class.php
  69. 12 3
      main/gradebook/lib/gradebook_functions.inc.php
  70. 53 21
      main/gradebook/lib/gradebook_functions_users.inc.php
  71. 2 0
      main/gradebook/lib/scoredisplay.class.php
  72. 7 7
      main/gradebook/lib/user_data_generator.class.php
  73. 12 2
      main/gradebook/user_info.php
  74. 4 4
      main/gradebook/user_stats.php
  75. 3 3
      main/group/example.csv
  76. 2 5
      main/group/group.php
  77. 4 23
      main/group/group_overview.php
  78. 3 1
      main/group/import.php
  79. 68 0
      main/inc/ajax/admin.ajax.php
  80. 6 1
      main/inc/ajax/agenda.ajax.php
  81. 29 18
      main/inc/introductionSection.inc.php
  82. 80 39
      main/inc/lib/certificate.lib.php
  83. 34 16
      main/inc/lib/course.lib.php
  84. 3 3
      main/inc/lib/course_category.lib.php
  85. 1 18
      main/inc/lib/dashboard.lib.php
  86. 5 3
      main/inc/lib/database.lib.php
  87. 1 1
      main/inc/lib/diagnoser.lib.php
  88. 15 4
      main/inc/lib/display.lib.php
  89. 25 6
      main/inc/lib/document.lib.php
  90. 54 19
      main/inc/lib/events.lib.inc.php
  91. 22 0
      main/inc/lib/fckeditor/editor/plugins/Abbr/lang/nl.js
  92. 2 2
      main/inc/lib/fckeditor/editor/plugins/ajaxfilemanager/ajax_get_file_listing.php
  93. 3 3
      main/inc/lib/fckeditor/fcktemplates.xml.php
  94. 74 72
      main/inc/lib/fileUpload.lib.php
  95. 8 1
      main/inc/lib/formvalidator/FormValidator.class.php
  96. 124 51
      main/inc/lib/groupmanager.lib.php
  97. 13 3
      main/inc/lib/internationalization.lib.php
  98. 0 8
      main/inc/lib/internationalization_database/name_order_conventions.php
  99. 21 9
      main/inc/lib/internationalization_internal.lib.php
  100. BIN
      main/inc/lib/javascript/emojine/png/1F1F5-1F1F1.png

+ 2 - 0
CONTRIBUTING.md

@@ -9,6 +9,8 @@ If you'd like to contribute, please read the following document:
 * [PSR-1][2]: PSR-1 are standard conventions rules we use as a base (conversion of old code still in progress)
 * [PSR-2][3]: PSR-2 are more detailed standard conventions rules we use as base (conversion of old code still in progress)
 
+We expect contributions to be sent through Pull Requests, a special feature of Github. We recommend you follow this guide to understand a little more about the way it works: https://guides.github.com/activities/contributing-to-open-source/
+
 [1]: https://support.chamilo.org/projects/chamilo-18/wiki/Coding_conventions
 [2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md
 [3]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md

+ 0 - 13
custompages/README

@@ -1,13 +0,0 @@
-CustomPages looks for alternatives in this directory, and displays them if present. The user-provided custom pages must exactly be named as such :
-
-- index-logged.php for the general landing page before login
-- index-unlogged.php for the general landing page when already logged-in
-- registration.php for the registration form
-- registration-feedback.php for the registration success feedback
-- lostpassword.php for the password recovery form
-- lostpassword-feedback.php for the password recovery feedback page
-
-Important note :
-Enable the use_custom_pages setting
-
-If you pull this feature from a repo, not through an upgrade or install process, you have to exectute the following SQL statements in the main database or this option won't appear in the admin interface :

+ 24 - 0
custompages/README.md

@@ -0,0 +1,24 @@
+Custom pages
+=============
+
+CustomPages looks for alternatives in this directory, and displays them if present.
+The user-provided custom pages must exactly be named as such :
+
+- index-logged.php for the general landing page before login
+- index-unlogged.php for the general landing page when already logged-in
+- registration.php for the registration form
+- registration-feedback.php for the registration success feedback
+- lostpassword.php for the password recovery form
+
+
+### Installation
+
+- Enable the use_custom_pages setting
+- Create your own modifications based in the files with the suffix "-dist.php"
+
+### Important notes
+
+- Do not replace the images in the images/ directory.
+  Instead, create new images, as the current ones will be overwritten
+  by each Chamilo upgrade.
+

+ 0 - 0
custompages/first_login.php → custompages/first_login-dist.php


+ 0 - 0
custompages/index-logged.php → custompages/index-logged-dist.php


+ 0 - 0
custompages/index-unlogged.php → custompages/index-unlogged-dist.php


+ 0 - 0
custompages/loggedout.php → custompages/loggedout-dist.php


+ 0 - 0
custompages/lostpassword.php → custompages/lostpassword-dist.php


+ 0 - 0
custompages/registration.php → custompages/registration-dist.php


+ 0 - 0
custompages/registration-feedback.php → custompages/registration-feedback-dist.php


+ 49 - 29
documentation/changelog.html

@@ -44,9 +44,9 @@
 <p><i>Note: most #wxyz references are issue numbers you can find in <a href="http://support.chamilo.org/projects/chamilo-18/issues" target="_blank">our public bug tracking system</a>. Some references marked BT#xyz are developments made externally for BeezNest customers and integrated into Chamilo. The details of these tasks cannot be seen for confidentiality reasons, but the code change is public and can be reviewed by anyone.</i></p>
 <p>&nbsp;</p>
 
-<h1>Chamilo 1.9.10 - Huánuco, 10th of November, 2014</h1>
+<h1>Chamilo 1.9.10 - Huánuco, 25th of January, 2015</h1>
 <h3>Release notes - summary</h3>
-<p>Chamilo 1.9.10 is a patch version with a few minor bugfixes and a new packaging. This will be packaged and promoted as 1.9.8, but the folder inside the 1.9.8 will be called 1.9.10, with a few changes to this changelog file and a few fixes throughout the code (as such, you can just overwrite previous files to upgrade from 1.9.8, 1.9.8.1 or 1.9.8.2 to 1.9.10).</p>
+<p>Chamilo 1.9.10 is a new minor version of the 1.9.x branch, with many bugfixes and a few interesting new features (as such, you can just overwrite previous files to upgrade from 1.9.8, 1.9.8.1 or 1.9.8.2 to 1.9.10).</p>
 <h3>Release name</h3>
 <p><a href="http://es.wikipedia.org/wiki/Departamento_de_Huánuco">Huánuco</a> is
   a small city in the Peruvian Andes, Northeast of Lima. This is a special
@@ -63,46 +63,47 @@
   platform, that will serve its purpose, helping making education better and
   more widely available, better than ever before.</p>
 
-<h3>Possibly breaking changes</h3>
-<p>Two changes have been made to the forum tool code, which might make some of your forums disappear and require a direct database intervention.<br />
-First case: If you use forums with sessions and have placed a session forum inside a base-course forum category, the forum category will now no longer appear in any session, and as such, the session forums contained in that category will disappear. You can easily fix that by checking the c_forum_forum table for any record with session_id != 0 that points to a forum category that has session_id == 0. This is related to issue #7264.<br />
-Second case: if you use group forums and have had issues with posts appearing twice, then this release will fix this bug, but might also make some forum posts disappear. Although we could not reproduce the error, you should be able to fix it by changing the group_id column inside the c_forum_thread table. This is related to issue #7267<br />
-This is an exceptional event in the history of Chamilo, and we believe it should only affect very few portals, but we prefer to take precautionnary measures and warn you upfront.<br />
-</p>
-
-<h3>Security</h3>
+<h3>Security fixes</h3>
 All security issues are published and patches are attached on <a href="https://support.chamilo.org/projects/chamilo-18/wiki/Security_issues">our security issues page</a>. If you think you found an additional security issue you'd like to report, please check our procedure there.
 <ul>
   <li>(8a75f65 - #7242) Fix SQL injection in mySpace/users.php</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/d64a02c156c7adf3983807be860a7848311dbfb3">d64a02c1</a> - <a href="https://support.chamilo.org/issues/7272">#7272</a>) Fix SQL injection threats and replace SESSION variable with api_get_user_id</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/587961662a8f9d035e52f14cd0aa4fee3aee68d8">58796166</a> - <a href="https://support.chamilo.org/issues/7275">#7275</a>) Add security token to course copy tool</li>
-  <li>(#7440) Fix a series of SQL injections due to integer filtering</li>
+  <li>(<a href="https://support.chamilo.org/issues/7440">#7440</a>) Fix a series of SQL injection vulnerabilities due to integer filtering</li>
 </ul>
 
+<h3>Possibly breaking changes</h3>
+<p>Two changes have been made to the forum tool code, which might make some of your forums disappear and require a direct database intervention.<br />
+    First case: If you use forums with sessions and have placed a session forum inside a base-course forum category, the forum category will now no longer appear in any session, and as such, the session forums contained in that category will disappear. You can easily fix that by checking the c_forum_forum table for any record with session_id != 0 that points to a forum category that has session_id == 0. This is related to issue #7264.<br />
+    Second case: In very rare occasions, if you use group forums and have had issues with posts appearing twice, then this release will fix this bug, but might also make some forum posts disappear. Although we could not reproduce the error, you should be able to fix it by changing the group_id column inside the c_forum_thread table. This is related to issue #7267<br />
+    This is an exceptional event in the history of Chamilo, and we believe it should only affect very few portals, but we prefer to take precautionnary measures and warn you upfront.<br />
+</p>
+
 <h3>Notable new Features</h3>
 <ul>
-
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/7e67dd29ccd7198ffb26e06847b48409895bc161">7e67dd29</a> - <a href="https://task.beeznest.com/issues/9018">BT#9018</a>) Add PDF export for student publications list</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/5e8ae687fd8a303e707a6a4fa677313056eb87c7">5e8ae687</a> - <a href="https://support.chamilo.org/issues/7478">#7478</a>) Add cookie warning message to comply with new European legislation</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/e637608c553c1041ae0c7f217d74f748f48bd789">e637608c</a> - <a href="https://task.beeznest.com/issues/8814">BT#8814</a>) Add "Auto attendance" based on course login</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/960899a6b227e1547751fcade680a696dffdcb1e">960899a6</a>) Add possibility to hide previous videoconferences even if recording is not enabled</li>
-  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/3bc8fd6fad15e6d92e8c1fd32e28d531c8c07d1d">3bc8fd6f</a>) Adding $_configuration['document_if_file_exists_option']</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/3bc8fd6fad15e6d92e8c1fd32e28d531c8c07d1d">3bc8fd6f</a>) Add $_configuration['document_if_file_exists_option']</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/73e381620438970423d371e717ad0bb8d5667a29">73e38162</a> - <a href="https://task.beeznest.com/issues/9247">BT#9247</a>) Adding exercise_max_fckeditors_in_page setting</li>
-  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/b14bcb36ad2145721205145561ae9a2d024a3a36">b14bcb36</a>) Adding option $_configuration['certificate_pdf_orientation']</li>
-  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/6bd4b5df0db53da2e586f1dac514873aca11ba7b">6bd4b5df</a> - <a href="https://task.beeznest.com/issues/8814">BT#8814</a>) Adding auto attendance</li>
-  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/7dbed8004f3a7da69a187df1de1cf7034097dfd7">7dbed800</a> - <a href="https://task.beeznest.com/issues/8703">BT#8703</a>) Adding hosting total size checker</li>
-  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/218dc6a4d7f27026b51df142a4b41d944bf44423">218dc6a4</a> - <a href="https://task.beeznest.com/issues/9175">BT#9175</a>) Adding hosting_limit_active_courses setting</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/b14bcb36ad2145721205145561ae9a2d024a3a36">b14bcb36</a>) Add option $_configuration['certificate_pdf_orientation']</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/7dbed8004f3a7da69a187df1de1cf7034097dfd7">7dbed800</a> - <a href="https://task.beeznest.com/issues/8703">BT#8703</a>) Add hosting total size checker</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/218dc6a4d7f27026b51df142a4b41d944bf44423">218dc6a4</a> - <a href="https://task.beeznest.com/issues/9175">BT#9175</a>) Add hosting_limit_active_courses setting</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/1d68db47b2dcb00a36e5b2d90e5be3cd6494cd56">1d68db47</a> - <a href="https://support.chamilo.org/issues/398">#398</a>) Support Opale/Scenarii by adding variable to better support SCORM 1.2 by watching over the definition, by the SCO, of the lesson_status and the call to LMSFinish() or the move to another element</li>
-  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/57750c212909bb4d74fb7b4bbba93b836c69979e">57750c21</a> - <a href="https://task.beeznest.com/issues/8900">BT#8900</a>) Adding progress in learning paths report</li>
-  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/903436eadfd7bc4cb8b20136301ceaba165b4ae1">903436ea</a> - <a href="https://task.beeznest.com/issues/8902">BT#8902</a>) Adding learning paths reduced report</li><li>(<a href="https://github.com/chamilo/chamilo-lms/commit/1a6a4a927eaf9aa919e47852a5ea7d6698063fac">1a6a4a92</a> - <a href="https://support.chamilo.org/issues/7272">#7272</a>) Add possibility for plugins to define main tabs</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/57750c212909bb4d74fb7b4bbba93b836c69979e">57750c21</a> - <a href="https://task.beeznest.com/issues/8900">BT#8900</a>) Add progress in learning paths report</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/903436eadfd7bc4cb8b20136301ceaba165b4ae1">903436ea</a> - <a href="https://task.beeznest.com/issues/8902">BT#8902</a>) Add learning paths reduced report</li><li>(<a href="https://github.com/chamilo/chamilo-lms/commit/1a6a4a927eaf9aa919e47852a5ea7d6698063fac">1a6a4a92</a> - <a href="https://support.chamilo.org/issues/7272">#7272</a>) Add possibility for plugins to define main tabs</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/ef242abd937637ec96973ecd7ad7b431949eab87">ef242abd</a> - <a href="https://support.chamilo.org/issues/7255">#7255</a>) Add multiple file upload in forum, and show list of attachment files from view threads</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c8f940be4aa4587e57fb36bab800b3e90a4f8762">c8f940be</a> - <a href="https://support.chamilo.org/issues/7338">#7338</a>) Add REST web service to get personal messages (from inbox)</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/2db9057d7b589e1d91554f5f39df415c810aeb95">2db9057d</a> - <a href="https://support.chamilo.org/issues/7328">#7328</a>) Add theme_backup and default_template settings</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/8d9a82535e9a1f6e11832f8217809d6e8cae9b36">8d9a8253</a>) Add script to check users data in CSV file</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/f52df87bded7b10787bec5516124024b5ad4edea">f52df87b</a> - <a href="https://task.beeznest.com/issues/8845">BT#8845</a>) Add script to move users from one course to another depending on them having passed an exam or not</li>
-  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/27493b32acc9d6cde3e95b5a34e4c03dcc004589">27493b32</a> - <a href="https://support.chamilo.org/issues/7324">#7324</a>) Add possibility to hide recordings to students in conferences list in BBB plugin</li>
-  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c24c758f7469fd73646892f2d37636d158c9fd8a">c24c758f</a> - <a href="https://task.beeznest.com/issues/8840">BT#8840</a>) Adding $_configuration['auto_detect_language_custom_pages'] to detect the language in custom pages</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/27493b32acc9d6cde3e95b5a34e4c03dcc004589">27493b32</a> - <a href="https://support.chamilo.org/issues/7324">#7324</a>) Add possibility to hide recordings from students in conferences list in BBB plugin</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c24c758f7469fd73646892f2d37636d158c9fd8a">c24c758f</a> - <a href="https://task.beeznest.com/issues/8840">BT#8840</a>) Add $_configuration['auto_detect_language_custom_pages'] to detect the language in custom pages</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/a2ff44cf6978393a3b5577afd408f11d58694c3c">a2ff44cf</a> - <a href="https://support.chamilo.org/issues/7212">#7212</a>) Add calculated answers feature (in beta test)</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/25cd7ddc4928c76591dd983b05abf6a7cf929654">25cd7ddc</a>) Use .gitattributes file to enable special Github features for versions packaging</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/002a0ab5a3901e8f8ef277ba06d841598c7ea93d">002a0ab5</a> - <a href="https://support.chamilo.org/issues/7309">#7309</a>) New icons for questions types</li>
-  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/0d131f9e4ee054d8099cbe470130aaa4e5ac01bc">0d131f9e</a> - <a href="https://task.beeznest.com/issues/8746">BT#8746</a>) Adding option "include all users" to export</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/0d131f9e4ee054d8099cbe470130aaa4e5ac01bc">0d131f9e</a> - <a href="https://task.beeznest.com/issues/8746">BT#8746</a>) Add option "include all users" to export</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/88126fe2e20114c0a62dcf282b37624ac6837965">88126fe2</a> - <a href="https://task.beeznest.com/issues/8796">BT#8796</a>) Add option to prevent multiple simultaneous login option ($_configuration['multiple_connection_not_allowed'])</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/58334f81813bf4f98fd29c1c0b39e8510fb7de2e">58334f81</a> - <a href="https://task.beeznest.com/issues/8746">BT#8746</a>) Add OnlyBestAttempts option to show only the best attempts in exercise results list</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/8ad728a6637a44570712e7c14e66b3b7bcea5f33">8ad728a6</a> - <a href="https://support.chamilo.org/issues/7279">#7279</a>) Add tour plugin</li>
@@ -132,21 +133,40 @@ All security issues are published and patches are attached on <a href="https://s
 
 <h3>Improvements (minor features) and debug</h3>
 <ul>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/110060be24244a8f8cfb9837bf9500aaddf2bc3a">110060be</a> - <a href="https://support.chamilo.org/issues/7462">#7462</a>) Fix pages blocked due to course restriction</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/299ba994390549c0193348c498760e727236609c">299ba994</a> - <a href="https://support.chamilo.org/issues/7477">#7477</a>) Restore admin view in reports (was lost in 1.9.8)</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/7f55f83751bd8d0e641afb85f05093f5e42c8bd6">7f55f837</a>) Rename the custompages php files in order to avoid overwrites</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/306c7b08d9a89cdde94e76cb47c1054eb01688fd">306c7b08</a>) Fix possible error when there are a lot of certicates to load.</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/bc07d715730d3035c2282a9de0ee8a2aba8b9f24">bc07d715</a> - <a href="https://task.beeznest.com/issues/9289">BT#9289</a>) Adds set_time_limit(0) in the certificate generation page</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/f1c9210c4dce32a7b8dca9c3b545bd1e515f3c2b">f1c9210c</a> - <a href="https://task.beeznest.com/issues/9287">BT#9287</a>) Add name_order_conventions configuration option</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/7820985bdda730332f7a0432b53611f904bce811">7820985b</a> - <a href="https://task.beeznest.com/issues/9280">BT#9280</a>) Fix homepage edition</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/e57d9a668f0f8824350e56be4ba6dca9e481b065">e57d9a66</a>) Fix category link now forcing the registration in itemproperty table</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c303f2392ddcf944e3c8afa62fd6db4e5dc5eea9">c303f239</a>) Add id_session in gradebook links</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/94ff182d7f46739afa9dfcb06b2a92d8b23f2efe">94ff182d</a>) Deprecate get_statistic_table() in favour of get_main_table()</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/a4a4118afbeeea1c20b9c5cedf776b7a07ab7832">a4a4118a</a>) Fix gradebook form link</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/4c70421ccf99006f0019805a2f83e4f69fe46f2c">4c70421c</a> - <a href="https://task.beeznest.com/issues/9200">BT#9200</a>) Fix link categories (no visibility is used)</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/57e2ffbed22849e1848cf4dd79bfb4d83e5de636">57e2ffbe</a>) Fix comments in student publication list</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/699f26c5ff54c70b18ae0381a26b43c1188c0f07">699f26c5</a> - <a href="https://support.chamilo.org/issues/7441">#7441</a>) Fix default user list order</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/533b0385015281818a0a8fbfac6171d11f1432e7">533b0385</a> - <a href="https://support.chamilo.org/issues/7457">#7457</a>) Fix deletion of personal files in documents</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/28c6e5e610e294f167c0f687e8de7a4c0746f3fc">28c6e5e6</a> - <a href="https://support.chamilo.org/issues/7447">#7447</a>) Fix api_mail_html (adding error log, adding return)</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/8cb2d42f7d391e47a7ff07675ea4a24ca9480523">8cb2d42f</a> - <a href="https://support.chamilo.org/issues/7455">#7455</a>) Using strict mode when cleaning files</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/4a17ad6ba29c4c6c8a1b52ce00131cefddbd6fb7">4a17ad6b</a> - <a href="https://task.beeznest.com/issues/8897">BT#8897</a>) Fix chapter status when saving sub elements in learning paths</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/4f2ac346557fba49def05489f32afccdc5ea062e">4f2ac346</a> - <a href="https://support.chamilo.org/issues/6064">#6064</a>) Fix language list</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/a667212d82788c6676fa9be76a245c48ba5ce99d">a667212d</a> - <a href="https://support.chamilo.org/issues/398">#398</a>) Fix query bug in learnpathItem::write_to_db()</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/4f2ac346557fba49def05489f32afccdc5ea062e">4f2ac346</a> - <a href="https://support.chamilo.org/issues/6064">#6064</a>) Fixing language list in portal homepage edition</li>
-  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/d36c633267b4ec66dec8e04054be2c1db0aae55f">d36c6332</a> - <a href="https://task.beeznest.com/issues/9250">BT#9250</a>) Adding certificate_filter_by_official_code</li>
-  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/ef1dc064ea934ad27f4972d223de8420c3c42854">ef1dc064</a> - <a href="https://support.chamilo.org/issues/9250">#9250</a>) Adding export certificates by user list</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/d36c633267b4ec66dec8e04054be2c1db0aae55f">d36c6332</a> - <a href="https://task.beeznest.com/issues/9250">BT#9250</a>) Add certificate_filter_by_official_code</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/ef1dc064ea934ad27f4972d223de8420c3c42854">ef1dc064</a> - <a href="https://support.chamilo.org/issues/9250">#9250</a>) Add export certificates by user list</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/d9a6fc7d5a02858e5a5dc0469ed219ee18b0521c">d9a6fc7d</a> - <a href="https://task.beeznest.com/issues/9235">BT#9235</a>) If user selects overwrite then we overwrite the file</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/74c25067aa05e139ab84ab3730d3b1a267fe0730">74c25067</a> - <a href="https://task.beeznest.com/issues/9233">BT#9233</a>) Coach can download files if session is read only</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/5d74663bae828477d30211af5cf51ab65b9302f0">5d74663b</a>) Fixing session list when session is read only and inside a category.</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/52c806a671d8f782f128edeefe8f42977e4c1907">52c806a6</a>) Fix possible issue checking the courses directory during installation on a host with default IP</li>
-  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c916b21c1cf7291a0099caadfa97bd91bda387e4">c916b21c</a>) Adding reporting icon for DRH see 7064</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c916b21c1cf7291a0099caadfa97bd91bda387e4">c916b21c</a>) Add reporting icon for DRH see 7064</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/e316005a56a9dea6f51697a7f5f7a0a15eddcdc7">e316005a</a> - <a href="https://support.chamilo.org/issues/7064">#7064</a>) Drh can see wiki</li>
-  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/0a64437eed2aceb4d4dbae766236409cc9ae88ac">0a64437e</a> - <a href="https://support.chamilo.org/issues/7064">#7064</a>) Adding DRH support for the survey tool</li>
-  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/3adf5c2d5761498fe51242821e342b8010c96498">3adf5c2d</a> - <a href="https://support.chamilo.org/issues/7064">#7064</a>) Adding DRH support in Assignments</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/0a64437eed2aceb4d4dbae766236409cc9ae88ac">0a64437e</a> - <a href="https://support.chamilo.org/issues/7064">#7064</a>) Add DRH support for the survey tool</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/3adf5c2d5761498fe51242821e342b8010c96498">3adf5c2d</a> - <a href="https://support.chamilo.org/issues/7064">#7064</a>) Add DRH support in Assignments</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/1d2626f2f264012e3a071f2e6931210bc61c6ff1">1d2626f2</a> - <a href="https://task.beeznest.com/issues/6986">BT#6986</a>) Fixing hotpotatoe bug while saving inside a LP</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/5e410a7ffed94a7402360f01ee59c87be2f36c53">5e410a7f</a> - <a href="https://task.beeznest.com/issues/6986">BT#6986</a>) Deleting LP objects in course homepage just in case</li>
-  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/dc784cfe99e7e87ec0c026cd7d2c896e13b26e60">dc784cfe</a> - <a href="https://task.beeznest.com/issues/7802">BT#7802</a>) Adding calendar event extra fields</li>
+  <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/dc784cfe99e7e87ec0c026cd7d2c896e13b26e60">dc784cfe</a> - <a href="https://task.beeznest.com/issues/7802">BT#7802</a>) Add calendar event extra fields</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/3684281a884a3f7702d268e2f676f165b19350e9">3684281a</a> - <a href="https://task.beeznest.com/issues/7064">BT#7064</a>) DRH user can see exercise results</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c6209ec7accc6cbf03ed63f550420f310532d71e">c6209ec7</a> - <a href="https://task.beeznest.com/issues/8816">BT#8816</a>) Adding "student_publication_to_take_in_gradebook" setting</li>
   <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/601f44fe751ec172e1d3aed18c4e2bc2232f91e3">601f44fe</a> - <a href="https://task.beeznest.com/issues/8816">BT#8816</a>) Showing feedback if exists</li>
@@ -356,7 +376,7 @@ All security issues are published and patches are attached on <a href="https://s
 <h3>Stylesheets and theming</h3>
 <ul>
   <li>No major style changes in this version, but a lot of visual improvements</li>
-  <li>The possibility to select a template (from main/template/) through the configuration.php file has been added, although no new template is available yet</li>
+  <li>The possibility to select a template (from main/template/) through the configuration.php file has been added, although no new template is available yet (at least now you can create your own and use it)</li>
   <li>Old question types icons were replaced by new icons</li>
   <li>Old session "window" icon was replaced by a new icon</li>
 </ul>

+ 19 - 7
index.php

@@ -118,8 +118,7 @@ if (!empty($_POST['submitAuth'])) {
         }
     }
     // End login -- if ($_POST['submitAuth'])
-}
-else {
+} else {
     // Only if login form was not sent because if the form is sent the user was already on the page.
     event_open();
 }
@@ -142,8 +141,7 @@ if (!api_is_anonymous()) {
 
     if (api_is_platform_admin()) {
         $controller->tpl->assign('course_block', $controller->return_course_block());
-    }
-    else {
+    } else {
         $controller->tpl->assign('teacher_block', $controller->return_teacher_link());
     }
 }
@@ -151,6 +149,22 @@ if (!api_is_anonymous()) {
 $hot_courses = null;
 $announcements_block = null;
 
+
+// Display the Site Use Cookie Warning Validation
+$useCookieValidation = api_get_configuration_value('cookie_warning');
+if ($useCookieValidation) {
+    if (isset($_POST['acceptCookies'])) {
+        api_set_site_use_cookie_warning_cookie();
+    } else if (!api_site_use_cookie_warning_cookie_exist()) {
+        if (Template::isToolBarDisplayedForUser()) {
+            $controller->tpl->assign('toolBarDisplayed', true);
+        } else {
+            $controller->tpl->assign('toolBarDisplayed', false);
+        }
+        $controller->tpl->assign('displayCookieUsageWarning', true);
+    }
+}
+
 // When loading a chamilo page do not include the hot courses and news
 
 if (!isset($_REQUEST['include'])) {
@@ -163,9 +177,7 @@ if (!isset($_REQUEST['include'])) {
 $controller->tpl->assign('hot_courses', $hot_courses);
 $controller->tpl->assign('announcements_block', $announcements_block);
 $controller->tpl->assign('home_page_block', $controller->return_home_page());
-
 $controller->tpl->assign('navigation_course_links', $controller->return_navigation_links());
-
 $controller->tpl->assign('notice_block', $controller->return_notice());
 $controller->tpl->assign('main_navigation_block', $controller->return_navigation_links());
 $controller->tpl->assign('help_block', $controller->return_help());
@@ -183,7 +195,7 @@ if (isset($_GET['firstpage'])) {
     api_set_firstpage_parameter($_GET['firstpage']);
     // if we are already logged, go directly to course
     if (api_user_is_login()) {
-        echo "<script type='text/javascript'>self.location.href='index.php?firstpage=".$_GET['firstpage']."'</script>";
+        echo "<script type='text/javascript'>self.location.href='index.php?firstpage=".Security::remove_XSS($_GET['firstpage'])."'</script>";
     }
 } else {
     api_delete_firstpage_parameter();

+ 7 - 0
main/admin/add_users_to_session.php

@@ -95,6 +95,13 @@ function search_users($needle, $type)
             $order_clause = ' ORDER BY official_code, firstname, lastname, username';
         }
 
+        if (api_is_session_admin()
+            && isset($_configuration['prevent_session_admins_to_manage_all_users'])
+            && $_configuration['prevent_session_admins_to_manage_all_users'] == 'true'
+        ) {
+            $order_clause = " AND user.creator_id = " . api_get_user_id() . $order_clause;
+        }
+
         $cond_user_id = '';
 
         // Only for single & multiple

+ 8 - 11
main/admin/configure_extensions.php

@@ -4,9 +4,7 @@
  * Edition of extensions configuration
  * @package chamilo.admin
  */
-/**
- * Code
- */
+
 // name of the language file that needs to be included
 $language_file='admin';
 $cidReset=true;
@@ -154,17 +152,18 @@ if (isset($_POST['activeExtension'])) {
 $listActiveServices = array();
 
 // get the list of active services
-$sql = 'SELECT variable FROM '.$tbl_settings_current.' WHERE variable LIKE "service_%" AND subkey="active" and selected_value="true"';
+$sql = 'SELECT variable FROM '.$tbl_settings_current.'
+		WHERE variable LIKE "service_%" AND subkey="active" and selected_value="true"';
 
 $rs = Database::query($sql);
 while($row = Database::fetch_array($rs)){
 	$listActiveServices[] = $row['variable'];
 }
 
-$javascript_service_displayed = '';
-if(isset($_GET['display'])){
+/*$javascript_service_displayed = '';
+if (isset($_GET['display'])) {
 	$javascript_service_displayed = 'document.getElementById("extension_content_'.$_GET['display'].'").style.display = "block"';
-}
+}*/
 
 // javascript to handle accordion behaviour
 $javascript_message = '';
@@ -223,8 +222,6 @@ $nameTool = get_lang('ConfigureExtensions');
 Display::display_header($nameTool);
 
 ?>
-
-
 <div id="message" style="display: none">
 	<?php
 	if(!empty($message))
@@ -299,7 +296,7 @@ Display::display_header($nameTool);
 	</div>
 
  */ ?>
-    
+
 	<!-- PPT2LP -->
 	<div id="main_ppt2lp">
 		<div id="extension_header_ppt2lp" class="accordion_header">
@@ -441,7 +438,7 @@ Display::display_header($nameTool);
 	</div>
 	*/
     /*
-   
+
 	<!-- SEARCH -->
 	<div id="main_search">
 		<div id="extension_header_search" class="accordion_header">

+ 468 - 432
main/admin/configure_homepage.php

@@ -1,9 +1,11 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
  * Configure the portal homepage (manages multi-urls and languages)
  * @package chamilo.admin
  */
+
 /**
  * Creates menu tabs for logged and anonymous users
  *
@@ -15,36 +17,36 @@
  */
 function home_tabs($file_logged_in)
 {
-    $post = strpos($file_logged_in, "_logged_in");
-    if ($post !== false) {
-        $file_logged_out = str_replace('_logged_in','', $file_logged_in);
-        //variables initialization
-        $data_logged_out = array();
-        $data_logged_in  = array();
-
-        //we read the file with all links
-        $file = file($file_logged_in);
-        foreach ($file as $line) {
-            $line = str_replace("\n", '',$line);
-            //not logged user only sees public links
-            if (!preg_match('/::private/',$line)) {
-                $data_logged_out[] = $line;
-            }
-            //logged user only sees all links
-            $data_logged_in[] = $line;
-        }
-        //tabs file for logged out users
-        $fp = fopen($file_logged_out, 'w');
-        fputs($fp, implode("\n", $data_logged_out));
-        fclose($fp);
-        //tabs file for logged in users
-        $fp = fopen($file_logged_in, 'w');
-        fputs($fp, implode("\n", $data_logged_in));
-        fclose($fp);
-    }
+	$post = strpos($file_logged_in, "_logged_in");
+	if ($post !== false) {
+		$file_logged_out = str_replace('_logged_in','', $file_logged_in);
+		//variables initialization
+		$data_logged_out = array();
+		$data_logged_in  = array();
+
+		//we read the file with all links
+		$file = file($file_logged_in);
+		foreach ($file as $line) {
+			$line = str_replace("\n", '',$line);
+			//not logged user only sees public links
+			if (!preg_match('/::private/',$line)) {
+				$data_logged_out[] = $line;
+			}
+			//logged user only sees all links
+			$data_logged_in[] = $line;
+		}
+		//tabs file for logged out users
+		$fp = fopen($file_logged_out, 'w');
+		fputs($fp, implode("\n", $data_logged_out));
+		fclose($fp);
+		//tabs file for logged in users
+		$fp = fopen($file_logged_in, 'w');
+		fputs($fp, implode("\n", $data_logged_in));
+		fclose($fp);
+	}
 }
 
-$language_file = array('index','admin', 'accessibility');
+$language_file = array('index', 'admin', 'accessibility');
 $cidReset = true;
 require_once '../inc/global.inc.php';
 
@@ -78,10 +80,17 @@ $tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
 $tool_name = get_lang('ConfigureHomePage');
 $_languages = api_get_languages();
 
-$interbreadcrumb[] = array('url' => 'index.php', 'name' => get_lang('PlatformAdmin'));
+$interbreadcrumb[] = array(
+	'url' => 'index.php',
+	'name' => get_lang('PlatformAdmin')
+);
 
 if (!empty($action)) {
-	$interbreadcrumb[] = array('url' => 'configure_homepage.php', 'name' => get_lang('ConfigureHomePage'));
+	$interbreadcrumb[] = array(
+		'url' => 'configure_homepage.php',
+		'name' => get_lang('ConfigureHomePage')
+	);
+
 	switch ($action) {
 		case 'edit_top':
 			$tool_name = get_lang('EditHomePage');
@@ -134,6 +143,8 @@ if (!empty($_SESSION['user_language_choice'])) {
 	$lang = api_get_setting('platformLanguage');
 }
 
+$languageGet = isset($_GET['language']) ? Security::remove_XSS($_GET['language']) : $lang;
+
 // Ensuring availability of main files in the corresponding language
 
 if (api_is_multiple_url_enabled()) {
@@ -165,29 +176,30 @@ $noticef = 'home_notice'; //noticef for Notice File
 $menutabs= 'home_tabs'; //menutabs for tabs Menu
 $mtloggedin= 'home_tabs_logged_in'; //menutabs for tabs Menu
 $ext 	 = '.html'; //ext for HTML Extension - when used frequently, variables are
-				// faster than hardcoded strings
+// faster than hardcoded strings
 $homef = array($menuf, $newsf, $topf, $noticef, $menutabs, $mtloggedin);
 
 // If language-specific file does not exist, create it by copying default file
 foreach ($homef as $my_file) {
-    if (api_is_multiple_url_enabled()) {
-        if (!file_exists($homep_new.$my_file.'_'.$lang.$ext)) {
-            if (!file_exists($homep.$my_file.$ext)) {
-                touch($homep.$my_file.$ext);
-            }
-            @copy($homep.$my_file.$ext, $homep_new.$my_file.'_'.$lang.$ext);
-        }
-    } else {
-        if (!file_exists($homep.$my_file.'_'.$lang.$ext)) {
-            if (!file_exists($homep.$my_file.$ext)) {
-                touch($homep.$my_file.$ext);
-            }
-            @copy($homep.$my_file.$ext, $homep.$my_file.'_'.$lang.$ext);
-        }
-    }
+	if (api_is_multiple_url_enabled()) {
+		if (!file_exists($homep_new.$my_file.'_'.$lang.$ext)) {
+			if (!file_exists($homep.$my_file.$ext)) {
+				touch($homep.$my_file.$ext);
+			}
+			@copy($homep.$my_file.$ext, $homep_new.$my_file.'_'.$lang.$ext);
+		}
+	} else {
+		if (!file_exists($homep.$my_file.'_'.$lang.$ext)) {
+			if (!file_exists($homep.$my_file.$ext)) {
+				touch($homep.$my_file.$ext);
+			}
+			@copy($homep.$my_file.$ext, $homep.$my_file.'_'.$lang.$ext);
+		}
+	}
 }
+
 if (api_is_multiple_url_enabled()) {
-    $homep = $homep_new;
+	$homep = $homep_new;
 }
 
 // Check WCAG settings and prepare edition using WCAG
@@ -224,25 +236,22 @@ if (!empty($action)) {
 				}
 
 				// Write
-				if (file_exists($homep.$topf.'_'.$lang.$ext)) {
+				if (is_writable($homep)) {
+					// Default
 					if (is_writable($homep.$topf.'_'.$lang.$ext)) {
 						$fp = fopen($homep.$topf.'_'.$lang.$ext, 'w');
 						fputs($fp, $home_top);
 						fclose($fp);
 
-                    foreach ($_languages['name'] as $key => $value) {
-                        $lang_name = $_languages['folder'][$key];
-                        if (isset($_POST[$lang_name])) {
-                            if (file_exists($homep.$topf.'_'.$lang_name.$ext)) {
-                                if (is_writable($homep.$topf.'_'.$lang_name.$ext)) {
-                                    $fp = fopen($homep.$topf.'_'.$lang_name.$ext, 'w');
-                                    fputs($fp, $home_top);
-                                    fclose($fp);
-                                }
-                            }
-                        }
-                    }
-
+						// Language
+						foreach ($_languages['name'] as $key => $value) {
+							$lang_name = $_languages['folder'][$key];
+							if (isset($_POST[$lang_name])) {
+								$fp = fopen($homep.$topf.'_'.$lang_name.$ext, 'w');
+								fputs($fp, $home_top);
+								fclose($fp);
+							}
+						}
 					} else {
 						$errorMsg = get_lang('HomePageFilesNotWritable');
 					}
@@ -252,22 +261,28 @@ if (!empty($action)) {
 					fputs($fp, $home_top);
 					fclose($fp);
 
-                    foreach ($_languages['name'] as $key => $value) {
-                        $lang_name = $_languages['folder'][$key];
-                        if (isset($_POST[$lang_name])) {
-                            if (file_exists($homep.$topf.'_'.$lang_name.$ext)) {
-                                $fp = fopen($homep.$topf.'_'.$lang_name.$ext, 'w');
-                                fputs($fp, $home_top);
-                                fclose($fp);
-                            }
-                        }
-                    }
-                }
-
-                if (EventsMail::check_if_using_class('portal_homepage_edited')) {
-                    EventsDispatcher::events('portal_homepage_edited',array('about_user' => api_get_user_id()));
-                }
-                event_system(LOG_HOMEPAGE_CHANGED, 'edit_top', cut(strip_tags($home_top), 254), api_get_utc_datetime(), api_get_user_id());
+					foreach ($_languages['name'] as $key => $value) {
+						$lang_name = $_languages['folder'][$key];
+						if (isset($_POST[$lang_name])) {
+							if (file_exists($homep.$topf.'_'.$lang_name.$ext)) {
+								$fp = fopen($homep.$topf.'_'.$lang_name.$ext, 'w');
+								fputs($fp, $home_top);
+								fclose($fp);
+							}
+						}
+					}
+				}
+
+				if (EventsMail::check_if_using_class('portal_homepage_edited')) {
+					EventsDispatcher::events('portal_homepage_edited',array('about_user' => api_get_user_id()));
+				}
+				event_system(
+					LOG_HOMEPAGE_CHANGED,
+					'edit_top',
+					cut(strip_tags($home_top), 254),
+					api_get_utc_datetime(),
+					api_get_user_id()
+				);
 				break;
 			case 'edit_notice':
 				// Filter
@@ -283,32 +298,32 @@ if (!empty($action)) {
 						if ($errorMsg == '') {
 							fputs($fp, "<b>$notice_title</b><br />\n$notice_text");
 
-                            foreach ($_languages['name'] as $key => $value) {
-                                $lang_name = $_languages['folder'][$key];
-                                if (isset($_POST[$lang_name])) {
-                                    if (file_exists($homep.$noticef.'_'.$lang_name.$ext)) {
-                                        if (is_writable($homep.$noticef.'_'.$lang_name.$ext)) {
-                                            $fp = fopen($homep.$noticef.'_'.$lang_name.$ext, 'w');
-                                            fputs($fp, "<b>$notice_title</b><br />\n$notice_text");
-                                            fclose($fp);
-                                        }
-                                    }
-                                }
-                            }
-                        } else {
+							foreach ($_languages['name'] as $key => $value) {
+								$lang_name = $_languages['folder'][$key];
+								if (isset($_POST[$lang_name])) {
+									if (file_exists($homep.$noticef.'_'.$lang_name.$ext)) {
+										if (is_writable($homep.$noticef.'_'.$lang_name.$ext)) {
+											$fp = fopen($homep.$noticef.'_'.$lang_name.$ext, 'w');
+											fputs($fp, "<b>$notice_title</b><br />\n$notice_text");
+											fclose($fp);
+										}
+									}
+								}
+							}
+						} else {
 							fputs($fp, '');
 
-                            foreach ($_languages['name'] as $key => $value) {
-                                $lang_name = $_languages['folder'][$key];
-                                if (isset($_POST[$lang_name])) {
-                                    if (file_exists($homep.$noticef.'_'.$lang_name.$ext)) {
-                                        $fp1 = fopen($homep.$noticef.'_'.$lang_name.$ext, 'w');
-                                        fputs($fp1, '');
-                                        fclose($fp1);
-                                    }
-                                }
-                            }
-                        }
+							foreach ($_languages['name'] as $key => $value) {
+								$lang_name = $_languages['folder'][$key];
+								if (isset($_POST[$lang_name])) {
+									if (file_exists($homep.$noticef.'_'.$lang_name.$ext)) {
+										$fp1 = fopen($homep.$noticef.'_'.$lang_name.$ext, 'w');
+										fputs($fp1, '');
+										fclose($fp1);
+									}
+								}
+							}
+						}
 						fclose($fp);
 					} else {
 						$errorMsg .= "<br/>\n".get_lang('HomePageFilesNotWritable');
@@ -319,7 +334,7 @@ if (!empty($action)) {
 					fputs($fp, "<b>$notice_title</b><br />\n$notice_text");
 					fclose($fp);
 				}
-                event_system(LOG_HOMEPAGE_CHANGED, 'edit_notice', cut(strip_tags($notice_title), 254), api_get_utc_datetime(), api_get_user_id());
+				event_system(LOG_HOMEPAGE_CHANGED, 'edit_notice', cut(strip_tags($notice_title), 254), api_get_utc_datetime(), api_get_user_id());
 				break;
 			case 'edit_news':
 				//Filter
@@ -365,7 +380,7 @@ if (!empty($action)) {
 						}
 					}
 				}
-                event_system(LOG_HOMEPAGE_CHANGED, 'edit_news', strip_tags(cut($home_news, 254)), api_get_utc_datetime(), api_get_user_id());
+				event_system(LOG_HOMEPAGE_CHANGED, 'edit_news', strip_tags(cut($home_news, 254)), api_get_utc_datetime(), api_get_user_id());
 				break;
 			case 'insert_tabs':
 			case 'edit_tabs':
@@ -375,7 +390,7 @@ if (!empty($action)) {
 				$insert_where   = intval($_POST['insert_where']);
 				$link_name      = trim(stripslashes($_POST['link_name']));
 				$link_url       = trim(stripslashes($_POST['link_url']));
-                $add_in_tab     = intval($_POST['add_in_tab']);
+				$add_in_tab     = intval($_POST['add_in_tab']);
 
 				// WCAG
 				if (api_get_setting('wcag_anysurfer_public_pages') == 'true') {
@@ -437,33 +452,33 @@ if (!empty($action)) {
 						// If the file doesn't exist, then create it and
 						// fill it with default text
 
-                        $fp = @fopen($homep.$filename, 'w');
-                        if ($fp) {
-                            if (empty($link_html)) {
-                                fputs($fp, get_lang('MyTextHere'));
-                                home_tabs($homep.$filename);
-                            } else {
-                            	fputs($fp, $link_html);
-                            	home_tabs($homep.$filename);
-                            }
-                            fclose($fp);
-                        }
+						$fp = @fopen($homep.$filename, 'w');
+						if ($fp) {
+							if (empty($link_html)) {
+								fputs($fp, get_lang('MyTextHere'));
+								home_tabs($homep.$filename);
+							} else {
+								fputs($fp, $link_html);
+								home_tabs($homep.$filename);
+							}
+							fclose($fp);
+						}
 					}
 					// If the requested action is to edit a link, open the file and
 					// write to it (if the file doesn't exist, create it)
 					if (in_array($action, array('edit_link'))  && !empty($link_html)) {
-						  $fp = @fopen($homep.$filename, 'w');
-						  if ($fp) {
-							 fputs($fp, $link_html);
-							 home_tabs($homep.$filename);
-							 fclose($fp);
-						  }
+						$fp = @fopen($homep.$filename, 'w');
+						if ($fp) {
+							fputs($fp, $link_html);
+							home_tabs($homep.$filename);
+							fclose($fp);
+						}
 					}
 
-                    $class_add_in_tab = 'class="show_menu"';
-                    if (!$add_in_tab) {
-                        $class_add_in_tab = 'class="hide_menu"';
-                    }
+					$class_add_in_tab = 'class="show_menu"';
+					if (!$add_in_tab) {
+						$class_add_in_tab = 'class="hide_menu"';
+					}
 
 					// If the requested action is to create a link, make some room
 					// for the new link in the home_menu array at the requested place
@@ -491,15 +506,15 @@ if (!empty($action)) {
 							home_tabs($homep.$menuf.'_'.$lang.$ext);
 							fclose($fp);
 
-                            foreach ($_languages['name'] as $key => $value) {
-                                $lang_name = $_languages['folder'][$key];
-                                if (isset($_POST[$lang_name])) {
-                                    $fp = fopen($homep.$menuf.'_'.$lang_name.$ext, 'w');
-                                    fputs($fp, $home_menu);
-                                    home_tabs($homep.$menuf.'_'.$lang_name.$ext);
-                                    fclose($fp);
-                                }
-                            }
+							foreach ($_languages['name'] as $key => $value) {
+								$lang_name = $_languages['folder'][$key];
+								if (isset($_POST[$lang_name])) {
+									$fp = fopen($homep.$menuf.'_'.$lang_name.$ext, 'w');
+									fputs($fp, $home_menu);
+									home_tabs($homep.$menuf.'_'.$lang_name.$ext);
+									fclose($fp);
+								}
+							}
 
 							if (file_exists($homep.$menuf.$ext)) {
 								if (is_writable($homep.$menuf.$ext)) {
@@ -519,23 +534,29 @@ if (!empty($action)) {
 						home_tabs($homep.$menuf.'_'.$lang.$ext);
 						fclose($fp);
 
-                        foreach ($_languages['name'] as $key => $value) {
-                            $lang_name = $_languages['folder'][$key];
-                            if (isset($_POST[$lang_name])) {
-                                $fp = fopen($homep.$menuf.'_'.$lang_name.$ext, 'w');
-                                fputs($fp, $home_menu);
-                                home_tabs($homep.$menuf.'_'.$lang_name.$ext);
-                                fclose($fp);
-                            }
-                        }
-                    }
+						foreach ($_languages['name'] as $key => $value) {
+							$lang_name = $_languages['folder'][$key];
+							if (isset($_POST[$lang_name])) {
+								$fp = fopen($homep.$menuf.'_'.$lang_name.$ext, 'w');
+								fputs($fp, $home_menu);
+								home_tabs($homep.$menuf.'_'.$lang_name.$ext);
+								fclose($fp);
+							}
+						}
+					}
 				}
-                event_system(LOG_HOMEPAGE_CHANGED, $action, cut($link_name.':'.$link_url, 254), api_get_utc_datetime(), api_get_user_id());
+			event_system(
+				LOG_HOMEPAGE_CHANGED,
+				$action,
+				cut($link_name . ':' . $link_url, 254),
+				api_get_utc_datetime(),
+				api_get_user_id()
+			);
 				break;
 		} //end of switch($action)
 
 		if (empty($errorMsg)) {
-			header('Location: '.api_get_self());
+			header('Location: '.api_get_self().'?language='.$languageGet);
 			exit();
 		}
 	} else {
@@ -651,7 +672,7 @@ if (!empty($action)) {
 				} elseif (is_file($homep.$mtloggedin.$lang.$ext) && is_readable($homep.$mtloggedin.$lang.$ext)) {
 					$home_menu = @file($homep.$mtloggedin.$lang.$ext);
 				} elseif (touch($homep.$mtloggedin.'_'.$lang.$ext)) {
-                    $home_menu = @file($homep.$mtloggedin.'_'.$lang.$ext);
+					$home_menu = @file($homep.$mtloggedin.'_'.$lang.$ext);
 				} else {
 					$errorMsg = get_lang('HomePageFilesNotReadable');
 				}
@@ -678,11 +699,11 @@ if (!empty($action)) {
 					$errorMsg = get_lang('HomePageFilesNotReadable');
 				}
 
-                if (empty($home_menu)) {
-                    if (file_exists($homep.$menutabs.'_'.$lang.$ext)) {
-                        $home_menu = @file($homep.$menutabs.'_'.$lang.$ext);
-                    }
-                }
+				if (empty($home_menu)) {
+					if (file_exists($homep.$menutabs.'_'.$lang.$ext)) {
+						$home_menu = @file($homep.$menutabs.'_'.$lang.$ext);
+					}
+				}
 
 				if (empty($home_menu)) {
 					$home_menu = array();
@@ -723,11 +744,11 @@ if (!empty($action)) {
 							$target_blank = true;
 						}
 
-                        if (strstr($enreg, 'hide_menu')) {
+						if (strstr($enreg, 'hide_menu')) {
 							$add_in_tab = false;
 						} else {
-                            $add_in_tab = true;
-                        }
+							$add_in_tab = true;
+						}
 
 						// Remove dangerous HTML tags from the link itself (this is an
 						// additional measure in case a link previously contained
@@ -782,32 +803,32 @@ switch ($action) {
 		// Display for edit_notice case
 		?>
 		<form action="<?php echo api_get_self(); ?>?action=<?php echo $action; ?>" method="post" style="margin:0px;">
-		<legend><?php echo $tool_name; ?></legend>
-		<input type="hidden" name="formSent" value="1"/>
-		<?php
-		if (!empty($errorMsg)) {
-			Display::display_normal_message($errorMsg);
-		}
-		?>
-		<table border="0" cellpadding="5" cellspacing="0">
-		<tr><td colspan="2"><?php echo '<span style="font-style: italic;">'.get_lang('LetThoseFieldsEmptyToHideTheNotice').'</span>'; ?></tr>
-		<tr>
-		  <td nowrap="nowrap"><?php echo get_lang('NoticeTitle'); ?> :</td>
-		  <td><input type="text" name="notice_title" size="30" maxlength="50" value="<?php echo $notice_title; ?>" style="width: 350px;"/></td>
-		</tr>
-		<tr>
-		  <td nowrap="nowrap" valign="top"><?php echo get_lang('NoticeText'); ?> :</td>
-		  <td><textarea name="notice_text" cols="30" rows="5" wrap="virtual" style="width: 350px;"><?php echo $notice_text; ?></textarea></td>
-		</tr>
-        <tr>
-          <td><label><?php echo get_lang('ApplyAllLanguages'); ?></label>
-          <td><input type="checkbox" name="all_langs" value="<?php echo get_lang('ApplyAllLanguages'); ?>"/></td>
-        </tr>
-		<tr>
-		  <td>&nbsp;</td>
-		  <td><button class="save" type="submit" value="<?php echo get_lang('Ok'); ?>"><?php echo get_lang('Ok'); ?></button></td>
-		</tr>
-		</table>
+			<legend><?php echo $tool_name; ?></legend>
+			<input type="hidden" name="formSent" value="1"/>
+			<?php
+			if (!empty($errorMsg)) {
+				Display::display_normal_message($errorMsg);
+			}
+			?>
+			<table border="0" cellpadding="5" cellspacing="0">
+				<tr><td colspan="2"><?php echo '<span style="font-style: italic;">'.get_lang('LetThoseFieldsEmptyToHideTheNotice').'</span>'; ?></tr>
+				<tr>
+					<td nowrap="nowrap"><?php echo get_lang('NoticeTitle'); ?> :</td>
+					<td><input type="text" name="notice_title" size="30" maxlength="50" value="<?php echo $notice_title; ?>" style="width: 350px;"/></td>
+				</tr>
+				<tr>
+					<td nowrap="nowrap" valign="top"><?php echo get_lang('NoticeText'); ?> :</td>
+					<td><textarea name="notice_text" cols="30" rows="5" wrap="virtual" style="width: 350px;"><?php echo $notice_text; ?></textarea></td>
+				</tr>
+				<tr>
+					<td><label><?php echo get_lang('ApplyAllLanguages'); ?></label>
+					<td><input type="checkbox" name="all_langs" value="<?php echo get_lang('ApplyAllLanguages'); ?>"/></td>
+				</tr>
+				<tr>
+					<td>&nbsp;</td>
+					<td><button class="save" type="submit" value="<?php echo get_lang('Ok'); ?>"><?php echo get_lang('Ok'); ?></button></td>
+				</tr>
+			</table>
 		</form>
 		<?php
 		break;
@@ -815,7 +836,7 @@ switch ($action) {
 	case 'edit_tabs':
 	case 'insert_link':
 	case 'edit_link':
-       $menuf = ($action == 'insert_tabs' || $action == 'edit_tabs') ? $mtloggedin : $menuf;
+		$menuf = ($action == 'insert_tabs' || $action == 'edit_tabs') ? $mtloggedin : $menuf;
 		if (!empty($errorMsg)) {
 			Display::display_normal_message($errorMsg);
 		}
@@ -830,37 +851,37 @@ switch ($action) {
 
 		$form->addElement('text', 'link_name', get_lang('LinkName'), array('size' => '30', 'maxlength' => '50'));
 		if (!empty($link_name)) {
-        $default['link_name'] = $link_name;
-    	}
+			$default['link_name'] = $link_name;
+		}
 		$default['link_url'] = empty($link_url) ? 'http://' : api_htmlentities($link_url, ENT_QUOTES);
-        $linkUrlComment = ($action == 'insert_tabs') ? get_lang('Optional').'<br />'.get_lang('GlobalLinkUseDoubleColumnPrivateToShowPrivately') : '';
-        $form->addElement('text', 'link_url', array(get_lang('LinkURL'), $linkUrlComment), array('size' => '30', 'maxlength' => '100', 'style' => 'width: 350px;'));
-        
-        $options = array('-1' => get_lang('FirstPlace'));
+		$linkUrlComment = ($action == 'insert_tabs') ? get_lang('Optional').'<br />'.get_lang('GlobalLinkUseDoubleColumnPrivateToShowPrivately') : '';
+		$form->addElement('text', 'link_url', array(get_lang('LinkURL'), $linkUrlComment), array('size' => '30', 'maxlength' => '100', 'style' => 'width: 350px;'));
+
+		$options = array('-1' => get_lang('FirstPlace'));
 
 		$selected = '';
 
 		if ($action == 'insert_link' || $action == 'insert_tabs') {
-            $add_in_tab = 1;
+			$add_in_tab = 1;
 			if (is_array($home_menu)){
 				foreach ($home_menu as $key => $enreg) {
 					if (strlen($enreg = trim(strip_tags($enreg))) > 0) {
-                        $options[$key] = get_lang('After').' &quot;'.$enreg.'&quot;';
-                        $formSentCheck = (!empty($_POST['formSent']) ? true : false);
-                        $selected = $formSentCheck && $insert_where == $key ? $key : '';
+						$options[$key] = get_lang('After').' &quot;'.$enreg.'&quot;';
+						$formSentCheck = (!empty($_POST['formSent']) ? true : false);
+						$selected = $formSentCheck && $insert_where == $key ? $key : '';
 					}
 				}
 			}
-            $default['insert_link'] = $selected;
-            $form->addElement('select', 'insert_where', get_lang('InsertThisLink') , $options);
+			$default['insert_link'] = $selected;
+			$form->addElement('select', 'insert_where', get_lang('InsertThisLink') , $options);
 		}
 
 		$target_blank_checkbox = $form->addElement('checkbox', 'target_blank', null, get_lang('OpenInNewWindow'), 1);
 
-        if ($action == 'insert_tabs' || $action == 'edit_tabs') {
-            $form->addElement('checkbox', 'add_in_tab', null, get_lang('AddInMenu'), 1);
-            $default['add_in_tab'] = $add_in_tab;
-        }
+		if ($action == 'insert_tabs' || $action == 'edit_tabs') {
+			$form->addElement('checkbox', 'add_in_tab', null, get_lang('AddInMenu'), 1);
+			$default['add_in_tab'] = $add_in_tab;
+		}
 
 		if (!empty($target_blank)) { $target_blank_checkbox->setChecked(true); }
 
@@ -873,31 +894,31 @@ switch ($action) {
 			}
 			$form->addElement('style_submit_button', null, get_lang('Save'), 'class="save"');
 		} else {
-            if (in_array($action, array('edit_tabs','insert_tabs'))) {
-                if (api_get_setting('wcag_anysurfer_public_pages')=='true') {
-                    $form->addElement('html', get_lang('Content').' ('.get_lang('Optional').')');
-                    $form->addElement('html', WCAG_Rendering::create_xhtml(isset($_POST['link_html'])?$_POST['link_html']:(!empty($link_html) ? $link_html : '')));
-                } else {
-                    $default['link_html'] = isset($_POST['link_html']) ? $_POST['link_html'] : (!empty($link_html) ? $link_html : '');
-                    $form->add_html_editor('link_html', get_lang('Content'), false, false, array('ToolbarSet' => 'PortalHomePage', 'Width' => '100%', 'Height' => '400'));
-                }
-            }
-            $form->addElement('checkbox', 'all_langs', null, get_lang('ApplyAllLanguages'), array('id' => 'all_langs'));
-            $form->addElement('html','<table id="table_langs" style="margin-left:159px;"><tr>');
-            $i = 0;
-            foreach ($_languages['name'] as $key => $value) {
-                $i++;
-                $lang_name = $_languages['folder'][$key];
-                $html_langs = '<td width="300">';
-                $html_langs .= '<label><input type="checkbox" id="lang" name="'.$lang_name.'" />&nbsp;'.$lang_name.'<label/>';
-                $html_langs .= '</td>';
-                if ($i%5 == 0) {
-                $html_langs .= '</tr><tr>';
-                }
-                $form->addElement('html', $html_langs);
-            }
-            $form->addElement('html','</tr></table><br/>');
-      		$form->addElement('style_submit_button', null, get_lang('Save'), 'class="save"');
+			if (in_array($action, array('edit_tabs','insert_tabs'))) {
+				if (api_get_setting('wcag_anysurfer_public_pages')=='true') {
+					$form->addElement('html', get_lang('Content').' ('.get_lang('Optional').')');
+					$form->addElement('html', WCAG_Rendering::create_xhtml(isset($_POST['link_html'])?$_POST['link_html']:(!empty($link_html) ? $link_html : '')));
+				} else {
+					$default['link_html'] = isset($_POST['link_html']) ? $_POST['link_html'] : (!empty($link_html) ? $link_html : '');
+					$form->add_html_editor('link_html', get_lang('Content'), false, false, array('ToolbarSet' => 'PortalHomePage', 'Width' => '100%', 'Height' => '400'));
+				}
+			}
+			$form->addElement('checkbox', 'all_langs', null, get_lang('ApplyAllLanguages'), array('id' => 'all_langs'));
+			$form->addElement('html','<table id="table_langs" style="margin-left:159px;"><tr>');
+			$i = 0;
+			foreach ($_languages['name'] as $key => $value) {
+				$i++;
+				$lang_name = $_languages['folder'][$key];
+				$html_langs = '<td width="300">';
+				$html_langs .= '<label><input type="checkbox" id="lang" name="'.$lang_name.'" />&nbsp;'.$lang_name.'<label/>';
+				$html_langs .= '</td>';
+				if ($i % 5 == 0) {
+					$html_langs .= '</tr><tr>';
+				}
+				$form->addElement('html', $html_langs);
+			}
+			$form->addElement('html','</tr></table><br/>');
+			$form->addElement('style_submit_button', null, get_lang('Save'), 'class="save"');
 		}
 
 		$form->setDefaults($default);
@@ -920,7 +941,13 @@ switch ($action) {
 		}
 
 		$default = array();
-		$form = new FormValidator('configure_homepage_'.$action, 'post', api_get_self().'?action='.$action, '', array('style' => 'margin: 0px;'));
+		$form = new FormValidator(
+			'configure_homepage_'.$action,
+			'post',
+			api_get_self().'?action='.$action,
+			'',
+			array('style' => 'margin: 0px;')
+		);
 		$renderer =& $form->defaultRenderer();
 		$renderer->setHeaderTemplate('');
 		$renderer->setFormTemplate('<form{attributes}><table border="0" cellpadding="5" cellspacing="0" width="100%">{content}</table></form>');
@@ -944,6 +971,7 @@ switch ($action) {
 			$html .= '</select></td></tr>';
 			$form->addElement('html', $html);
 		}
+
 		if (api_get_setting('wcag_anysurfer_public_pages') == 'true') {
 			//TODO: review these lines
 			// Print WCAG-specific HTML editor
@@ -955,23 +983,28 @@ switch ($action) {
 			$default[$name] = str_replace('{rel_path}', api_get_path(REL_PATH), $open);
 			$form->add_html_editor($name, '', true, false, array('ToolbarSet' => 'PortalHomePage', 'Width' => '100%', 'Height' => '400'));
 		}
-        $form->addElement('checkbox', 'all_langs', null, get_lang('ApplyAllLanguages'),array('id' => 'all_langs'));
-        $form->addElement('html','<table id="table_langs" style="margin-left:5px;"><tr>');
-        $i = 0;
-        foreach ($_languages['name'] as $key => $value) {
-            $i++;
-            $lang_name = $_languages['folder'][$key];
-			//if (file_exists($homep.$topf.'_'.$lang_name.$ext)) {
-                $html_langs = '<td width="300">';
-                $html_langs .= '<label><input type="checkbox" id="lang" name="'.$lang_name.'" />&nbsp;'.$lang_name.'<label/>';
-                $html_langs .= '</td>';
-                if($i%5 == 0) {
-                    $html_langs .= '</tr><tr>';
-                }
-                $form->addElement('html', $html_langs);
-			//}
-        }
-        $form->addElement('html','</tr></table><br/>');
+		$form->addElement('checkbox', 'all_langs', null, get_lang('ApplyAllLanguages'),array('id' => 'all_langs'));
+		$form->addElement('html','<table id="table_langs" style="margin-left:5px;"><tr>');
+
+		$currentLanguage = api_get_interface_language();
+		$i = 0;
+		foreach ($_languages['name'] as $key => $value) {
+			$lang_name = $_languages['folder'][$key];
+			$i++;
+
+			$checked = null;
+			if ($languageGet == $lang_name)  {
+				$checked = "checked";
+			}
+			$html_langs = '<td width="300">';
+			$html_langs .= '<label><input type="checkbox" '.$checked.' id="lang" name="'.$lang_name.'" />&nbsp;'.$value.'<label/>';
+			$html_langs .= '</td>';
+			if ($i % 5 == 0) {
+				$html_langs .= '</tr><tr>';
+			}
+			$form->addElement('html', $html_langs);
+		}
+		$form->addElement('html','</tr></table><br/>');
 		$form->addElement('style_submit_button', null, get_lang('Save'), 'class="save"');
 		$form->setDefaults($default);
 		$form->display();
@@ -980,208 +1013,211 @@ switch ($action) {
 	default: // When no action applies, default page to update campus homepage
 		?>
 		<table border="0" cellpadding="5" cellspacing="0" width="100%">
-		<tr>
-		  <td width="70%" valign="top">
-		  	<div class="actions">
-			<a href="<?php echo api_get_self(); ?>?action=edit_top"><?php Display::display_icon('edit.gif', get_lang('EditHomePage')); ?></a>
-			<a href="<?php echo api_get_self(); ?>?action=edit_top"><?php echo get_lang('EditHomePage'); ?></a>
-		  	</div>
-
-			<table border="0" cellpadding="5" cellspacing="0" width="100%">
 			<tr>
-			  <td colspan="2">
-				<?php
-					//print home_top contents
-					if (file_exists($homep.$topf.'_'.$lang.$ext)) {
-						$home_top_temp = @(string)file_get_contents($homep.$topf.'_'.$lang.$ext);
-					} else {
-						$home_top_temp = @(string)file_get_contents($homep.$topf.$ext);
-					}
-					$open = str_replace('{rel_path}', api_get_path(REL_PATH), $home_top_temp);
-					$open = api_to_system_encoding($open, api_detect_encoding(strip_tags($open)));
-					echo $open;
-				?>
-			  </td>
-			</tr>
-			<tr>
-			<?php
-
-			$access_url_id = 1;
-			// we only show the category options for the main chamilo installation
-			if (api_is_multiple_url_enabled()) {
-				$access_url_id = api_get_current_access_url_id();
-			}
-			echo '<td width="50%">';
-			if ($access_url_id == 1) {
-				echo '<div class="actions">';
-				echo '<a href="course_category.php">'.Display::display_icon('edit.gif', get_lang('Edit')).'</a>
+				<td width="70%" valign="top">
+					<div class="actions">
+						<a href="<?php echo api_get_self(); ?>?action=edit_top&language=<?php echo $languageGet; ?>">
+							<?php Display::display_icon('edit.gif', get_lang('EditHomePage')); ?>
+						</a>
+						<a href="<?php echo api_get_self(); ?>?action=edit_top&language=<?php echo $languageGet; ?>">
+							<?php echo get_lang('EditHomePage'); ?>
+						</a>
+					</div>
+
+					<table border="0" cellpadding="5" cellspacing="0" width="100%">
+						<tr>
+							<td colspan="2">
+								<?php
+								//print home_top contents
+								if (file_exists($homep.$topf.'_'.$lang.$ext)) {
+									$home_top_temp = @(string)file_get_contents($homep.$topf.'_'.$lang.$ext);
+								} else {
+									$home_top_temp = @(string)file_get_contents($homep.$topf.$ext);
+								}
+								$open = str_replace('{rel_path}', api_get_path(REL_PATH), $home_top_temp);
+								$open = api_to_system_encoding($open, api_detect_encoding(strip_tags($open)));
+								echo $open;
+								?>
+							</td>
+						</tr>
+						<tr>
+							<?php
+
+							$access_url_id = 1;
+							// we only show the category options for the main chamilo installation
+							if (api_is_multiple_url_enabled()) {
+								$access_url_id = api_get_current_access_url_id();
+							}
+							echo '<td width="50%">';
+							if ($access_url_id == 1) {
+								echo '<div class="actions">';
+								echo '<a href="course_category.php">'.Display::display_icon('edit.gif', get_lang('Edit')).'</a>
 					  <a href="course_category.php">'.get_lang('EditCategories').'</a>';
-				echo '</div>';
-			}
-			echo '</td>
+								echo '</div>';
+							}
+							echo '</td>
 				  <td width="50%">
 				  <br />';
-			/* <!--<a href="<?php echo api_get_self(); ?>?action=edit_news"><?php Display::display_icon('edit.gif', get_lang('Edit')); ?></a> <a href="<?php echo api_get_self(); ?>?action=edit_news"><?php echo get_lang('EditNews'); ?></a>--> */
-			echo '</td></tr>
+							/* <!--<a href="<?php echo api_get_self(); ?>?action=edit_news"><?php Display::display_icon('edit.gif', get_lang('Edit')); ?></a> <a href="<?php echo api_get_self(); ?>?action=edit_news"><?php echo get_lang('EditNews'); ?></a>--> */
+							echo '</td></tr>
 				<tr>
 				<td width="50%" valign="top">
 				<table border="0" cellpadding="5" cellspacing="0" width="100%">';
-				if ($access_url_id == 1) {
-					if (sizeof($Categories)) {
-						foreach ($Categories as $enreg) {
-							echo '<tr><td>'.Display::return_icon('folder_document.gif', $enreg['name']).'&nbsp;'.$enreg['name'].'</td></tr>';
-						}
-						unset($Categories);
-					} else {
-						echo get_lang('NoCategories');
-					}
-				}
+							if ($access_url_id == 1) {
+								if (sizeof($Categories)) {
+									foreach ($Categories as $enreg) {
+										echo '<tr><td>'.Display::return_icon('folder_document.gif', $enreg['name']).'&nbsp;'.$enreg['name'].'</td></tr>';
+									}
+									unset($Categories);
+								} else {
+									echo get_lang('NoCategories');
+								}
+							}
 
-				echo '</table>';
-				?>
-			  </td>
-			  <!--<td width="50%" valign="top">
+							echo '</table>';
+							?>
+							</td>
+							<!--<td width="50%" valign="top">
 				<?php
-				if (file_exists($homep.$newsf.'_'.$lang.$ext)) {
-					$open = @(string)file_get_contents($homep.$newsf.'_'.$lang.$ext);
-					$open = api_to_system_encoding($open, api_detect_encoding(strip_tags($open)));
-					echo $open;
-				} else {
-					$open = @(string)file_get_contents($homep.$newsf.$ext);
-					$open = api_to_system_encoding($open, api_detect_encoding(strip_tags($open)));
-					echo $open;
-				}
-			?>
+							if (file_exists($homep.$newsf.'_'.$lang.$ext)) {
+								$open = @(string)file_get_contents($homep.$newsf.'_'.$lang.$ext);
+								$open = api_to_system_encoding($open, api_detect_encoding(strip_tags($open)));
+								echo $open;
+							} else {
+								$open = @(string)file_get_contents($homep.$newsf.$ext);
+								$open = api_to_system_encoding($open, api_detect_encoding(strip_tags($open)));
+								echo $open;
+							}
+							?>
 			  </td>-->
-			</tr>
-			</table>
-			<?php
+						</tr>
+					</table>
+					<?php
 
-			// Add new page
-
-			$home_menu = '';
-
-            if (file_exists($homep.$mtloggedin.'_'.$lang.$ext)) {
-                $home_menu = @file($homep.$mtloggedin.'_'.$lang.$ext);
-            } else {
-                $home_menu = @file($homep.$mtloggedin.$ext);
-            }
-
-            if (empty($home_menu)) {
-                if (file_exists($homep.$menutabs.'_'.$lang.$ext)) {
-                    $home_menu = @file($homep.$menutabs.'_'.$lang.$ext);
-                }
-            }
-
-            if (empty($home_menu)) {
-                $home_menu = array();
-            }
-
-            if (!empty($home_menu)) {
-                $home_menu = implode("\n", $home_menu);
-                $home_menu = api_to_system_encoding($home_menu, api_detect_encoding(strip_tags($home_menu)));
-                $home_menu = explode("\n", $home_menu);
-            }
-            $link_list = '';
-            $tab_counter = 0;
-            foreach ($home_menu as $enreg) {
-                $enreg = trim($enreg);
-                if (!empty($enreg)) {
-                    $edit_link   = ' <a href="'.api_get_self().'?action=edit_tabs&amp;link_index='.$tab_counter.'" ><span>'.Display::return_icon('edit.gif', get_lang('Edit')).'</span></a>';
-                    $delete_link = ' <a href="'.api_get_self().'?action=delete_tabs&amp;link_index='.$tab_counter.'"  onclick="javascript: if(!confirm(\''.addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES)).'\')) return false;"><span>'.Display::return_icon('delete.gif', get_lang('Delete')).'</span></a>';
-                    $tab_string = str_replace(array('href="'.api_get_path(WEB_PATH).'index.php?include=', '</li>'),
-                                              array('href="'.api_get_path(WEB_CODE_PATH).'admin/'.basename(api_get_self()).'?action=open_link&link=', $edit_link.$delete_link.'</li>'),
-                                              $enreg);
-                    $tab_string = str_replace(array('<li>', '</li>','class="hide_menu"', 'hide_menu'), '', $tab_string);
-
-                    $link_list .= Display::tag('tr', Display::tag('td', $tab_string));
-                    $tab_counter++;
-                }
-            }
-            ?>
-            <div class="actions">
-                <a href="<?php echo api_get_self(); ?>?action=insert_tabs"><?php Display::display_icon('addd.gif', get_lang('InsertLink')); echo get_lang('InsertLink'); ?></a>
-            </div>
-            <?php
-            echo '<table class="data_table">';
-            echo $link_list;
-            echo '</table>';
-			?>
-		  </td>
-		  <td width="10%" valign="top"></td>
-		  <td width="20%" rowspan="3" valign="top">
-
-		    <div id="login_block" class="well sidebar-nav">
-                <?php echo api_display_language_form(); ?>
-                <form id="formLogin">
-                    <div><label><?php echo get_lang('LoginName'); ?></label></div>
-                    <div><input type="text" id="login" size="15" value="" disabled="disabled" /></div>
-                    <div><label><?php echo get_lang('UserPassword'); ?></label></div>
-                    <div><input type="password" id="password" size="15" value="" disabled="disabled" /></div>
-                    <div><button class="btn" type="button" name="submitAuth" value="<?php echo get_lang('Ok'); ?>" disabled="disabled"><?php echo get_lang('Ok'); ?></button></div>
-                </form>
-			</div>
-
-			<div id="profile_block" class="well sidebar-nav">
-				<h4><?php echo get_lang('MenuUser'); ?></h4>
-				<ul class="nav nav-list">
-				<li><span style="color: #9D9DA1; font-weight: bold;"><?php echo api_ucfirst(get_lang('Registration')); ?></span></li>
-				<li><span style="color: #9D9DA1; font-weight: bold;"><?php echo api_ucfirst(get_lang('LostPassword')); ?></span></li>
-				</ul>
-			</div>
-
-			<div id="notice_block" class="well sidebar-nav">
-                <h4><?php echo get_lang('Notice'); ?>
-                    <a href="<?php echo api_get_self(); ?>?action=edit_notice"><?php Display::display_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL); ?></a>
-                </h4>
-            <?php
-            $home_notice = '';
-            if (file_exists($homep.$noticef.'_'.$lang.$ext)) {
-                $home_notice = @(string)file_get_contents($homep.$noticef.'_'.$lang.$ext);
-            } else {
-                $home_notice = @(string)file_get_contents($homep.$noticef.$ext);
-            }
-            $home_notice = api_to_system_encoding($home_notice, api_detect_encoding(strip_tags($home_notice)));
-            echo '<div class="homepage_notice">';
-            echo $home_notice;
-            echo '</div>';
-            ?>
-            </div>
-           	<div class="well sidebar-nav">
-                <a href="<?php echo api_get_self(); ?>?action=insert_link"><?php Display::display_icon('addd.gif', get_lang('InsertLink')); ?></a>
-                <a href="<?php echo api_get_self(); ?>?action=insert_link"><?php echo get_lang('InsertLink'); ?></a>
-    			<h4><?php echo api_ucfirst(get_lang('General')); ?></h4>
-    				<ul class="menulist">
-    				<?php
-    					$home_menu = '';
-    					if (file_exists($homep.$menuf.'_'.$lang.$ext)) {
-    						$home_menu = @file($homep.$menuf.'_'.$lang.$ext);
-    					} else {
-    						$home_menu = @file($homep.$menuf.$ext);
-    					}
-    					if (empty($home_menu)) {
-    						$home_menu = array();
-    					}
-    					if (!empty($home_menu)) {
-    						$home_menu = implode("\n", $home_menu);
-    						$home_menu = api_to_system_encoding($home_menu, api_detect_encoding(strip_tags($home_menu)));
-    						$home_menu = explode("\n", $home_menu);
-    					}
-    					$i = 0;
-    					foreach ($home_menu as $enreg) {
-    						$enreg = trim($enreg);
-    						if (!empty($enreg)) {
-    							$edit_link = '<a href="'.api_get_self().'?action=edit_link&amp;link_index='.$i.'">'.Display::return_icon('edit.gif', get_lang('Edit')).'</a>';
-    							$delete_link = '<a href="'.api_get_self().'?action=delete_link&amp;link_index='.$i.'" onclick="javascript:if(!confirm(\''.addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES)).'\')) return false;">'.Display::return_icon('delete.gif', get_lang('Delete')).'</a>';
-    							echo str_replace(array('href="'.api_get_path(WEB_PATH).'index.php?include=', '</li>'), array('href="'.api_get_path(WEB_CODE_PATH).'admin/'.basename(api_get_self()).'?action=open_link&link=', '<br />'.$edit_link.' '.$delete_link.'</li>'), $enreg);
-    							$i++;
-    						}
-    					}
-    				?>
-    				</ul>
-			     </div>
-		  </td>
-		</tr>
+					// Add new page
+
+					$home_menu = '';
+
+					if (file_exists($homep.$mtloggedin.'_'.$lang.$ext)) {
+						$home_menu = @file($homep.$mtloggedin.'_'.$lang.$ext);
+					} else {
+						$home_menu = @file($homep.$mtloggedin.$ext);
+					}
+
+					if (empty($home_menu)) {
+						if (file_exists($homep.$menutabs.'_'.$lang.$ext)) {
+							$home_menu = @file($homep.$menutabs.'_'.$lang.$ext);
+						}
+					}
+
+					if (empty($home_menu)) {
+						$home_menu = array();
+					}
+
+					if (!empty($home_menu)) {
+						$home_menu = implode("\n", $home_menu);
+						$home_menu = api_to_system_encoding($home_menu, api_detect_encoding(strip_tags($home_menu)));
+						$home_menu = explode("\n", $home_menu);
+					}
+					$link_list = '';
+					$tab_counter = 0;
+					foreach ($home_menu as $enreg) {
+						$enreg = trim($enreg);
+						if (!empty($enreg)) {
+							$edit_link   = ' <a href="'.api_get_self().'?action=edit_tabs&amp;link_index='.$tab_counter.'" ><span>'.Display::return_icon('edit.gif', get_lang('Edit')).'</span></a>';
+							$delete_link = ' <a href="'.api_get_self().'?action=delete_tabs&amp;link_index='.$tab_counter.'"  onclick="javascript: if(!confirm(\''.addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES)).'\')) return false;"><span>'.Display::return_icon('delete.gif', get_lang('Delete')).'</span></a>';
+							$tab_string = str_replace(array('href="'.api_get_path(WEB_PATH).'index.php?include=', '</li>'),
+								array('href="'.api_get_path(WEB_CODE_PATH).'admin/'.basename(api_get_self()).'?action=open_link&link=', $edit_link.$delete_link.'</li>'),
+								$enreg);
+							$tab_string = str_replace(array('<li>', '</li>','class="hide_menu"', 'hide_menu'), '', $tab_string);
+
+							$link_list .= Display::tag('tr', Display::tag('td', $tab_string));
+							$tab_counter++;
+						}
+					}
+					?>
+					<div class="actions">
+						<a href="<?php echo api_get_self(); ?>?action=insert_tabs"><?php Display::display_icon('addd.gif', get_lang('InsertLink')); echo get_lang('InsertLink'); ?></a>
+					</div>
+					<?php
+					echo '<table class="data_table">';
+					echo $link_list;
+					echo '</table>';
+					?>
+				</td>
+				<td width="10%" valign="top"></td>
+				<td width="20%" rowspan="3" valign="top">
+					<div id="login_block" class="well sidebar-nav">
+						<?php echo api_display_language_form(); ?>
+						<form id="formLogin">
+							<div><label><?php echo get_lang('LoginName'); ?></label></div>
+							<div><input type="text" id="login" size="15" value="" disabled="disabled" /></div>
+							<div><label><?php echo get_lang('UserPassword'); ?></label></div>
+							<div><input type="password" id="password" size="15" value="" disabled="disabled" /></div>
+							<div><button class="btn" type="button" name="submitAuth" value="<?php echo get_lang('Ok'); ?>" disabled="disabled"><?php echo get_lang('Ok'); ?></button></div>
+						</form>
+					</div>
+
+					<div id="profile_block" class="well sidebar-nav">
+						<h4><?php echo get_lang('MenuUser'); ?></h4>
+						<ul class="nav nav-list">
+							<li><span style="color: #9D9DA1; font-weight: bold;"><?php echo api_ucfirst(get_lang('Registration')); ?></span></li>
+							<li><span style="color: #9D9DA1; font-weight: bold;"><?php echo api_ucfirst(get_lang('LostPassword')); ?></span></li>
+						</ul>
+					</div>
+
+					<div id="notice_block" class="well sidebar-nav">
+						<h4><?php echo get_lang('Notice'); ?>
+							<a href="<?php echo api_get_self(); ?>?action=edit_notice"><?php Display::display_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL); ?></a>
+						</h4>
+						<?php
+						$home_notice = '';
+						if (file_exists($homep.$noticef.'_'.$lang.$ext)) {
+							$home_notice = @(string)file_get_contents($homep.$noticef.'_'.$lang.$ext);
+						} else {
+							$home_notice = @(string)file_get_contents($homep.$noticef.$ext);
+						}
+						$home_notice = api_to_system_encoding($home_notice, api_detect_encoding(strip_tags($home_notice)));
+						echo '<div class="homepage_notice">';
+						echo $home_notice;
+						echo '</div>';
+						?>
+					</div>
+					<div class="well sidebar-nav">
+						<a href="<?php echo api_get_self(); ?>?action=insert_link"><?php Display::display_icon('addd.gif', get_lang('InsertLink')); ?></a>
+						<a href="<?php echo api_get_self(); ?>?action=insert_link"><?php echo get_lang('InsertLink'); ?></a>
+						<h4><?php echo api_ucfirst(get_lang('General')); ?></h4>
+						<ul class="menulist">
+							<?php
+							$home_menu = '';
+							if (file_exists($homep.$menuf.'_'.$lang.$ext)) {
+								$home_menu = @file($homep.$menuf.'_'.$lang.$ext);
+							} else {
+								$home_menu = @file($homep.$menuf.$ext);
+							}
+							if (empty($home_menu)) {
+								$home_menu = array();
+							}
+							if (!empty($home_menu)) {
+								$home_menu = implode("\n", $home_menu);
+								$home_menu = api_to_system_encoding($home_menu, api_detect_encoding(strip_tags($home_menu)));
+								$home_menu = explode("\n", $home_menu);
+							}
+							$i = 0;
+							foreach ($home_menu as $enreg) {
+								$enreg = trim($enreg);
+								if (!empty($enreg)) {
+									$edit_link = '<a href="'.api_get_self().'?action=edit_link&amp;link_index='.$i.'">'.Display::return_icon('edit.gif', get_lang('Edit')).'</a>';
+									$delete_link = '<a href="'.api_get_self().'?action=delete_link&amp;link_index='.$i.'" onclick="javascript:if(!confirm(\''.addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES)).'\')) return false;">'.Display::return_icon('delete.gif', get_lang('Delete')).'</a>';
+									echo str_replace(array('href="'.api_get_path(WEB_PATH).'index.php?include=', '</li>'), array('href="'.api_get_path(WEB_CODE_PATH).'admin/'.basename(api_get_self()).'?action=open_link&link=', '<br />'.$edit_link.' '.$delete_link.'</li>'), $enreg);
+									$i++;
+								}
+							}
+							?>
+						</ul>
+					</div>
+				</td>
+			</tr>
 		</table>
 		<?php
 		break;

+ 5 - 6
main/admin/course_category.php

@@ -3,9 +3,7 @@
 /**
  * 	@package chamilo.admin
  */
-/**
- * Code
- */
+
 // name of the language file that needs to be included
 $language_file = 'admin';
 $cidReset = true;
@@ -75,7 +73,7 @@ if ($action == 'add' || $action == 'edit') {
         echo '<div class="actions">';
         echo Display::url(
             Display::return_icon('folder_up.png', get_lang("Back"), '', ICON_SIZE_MEDIUM),
-            api_get_path(WEB_CODE_PATH).'admin/course_category.php?category='.$category
+            api_get_path(WEB_CODE_PATH).'admin/course_category.php?category='.Security::remove_XSS($category)
         );
         echo '</div>';
 
@@ -83,10 +81,11 @@ if ($action == 'add' || $action == 'edit') {
         if (!empty($category)) {
             $form_title .= ' ' . get_lang('Into') . ' ' . Security::remove_XSS($category);
         }
-        $url = api_get_self().'?action='.Security::remove_XSS($action).'&category='.Security::remove_XSS($category).'&id='.$categoryId;
+        $url = api_get_self().'?action='.Security::remove_XSS($action).'&category='.Security::remove_XSS($category).'&id='.Security::remove_XSS($category);
         $form = new FormValidator('course_category', 'post', $url);
         $form->addElement('header', '', $form_title);
         $form->addElement('hidden', 'formSent', 1);
+
         $form->addElement('text', 'code', get_lang("CategoryCode"));
         $form->addElement('text', 'name', get_lang("CategoryName"));
         $form->addRule('name', get_lang('PleaseEnterCategoryInfo'), 'required');
@@ -130,7 +129,7 @@ if ($action == 'add' || $action == 'edit') {
     if (empty($parentInfo) || $parentInfo['auth_cat_child'] == 'TRUE') {
         echo Display::url(
             Display::return_icon('new_folder.png', get_lang("AddACategory"), '', ICON_SIZE_MEDIUM),
-            api_get_path(WEB_CODE_PATH).'admin/course_category.php?action=add&category='.$category
+            api_get_path(WEB_CODE_PATH).'admin/course_category.php?action=add&category='.Security::remove_XSS($category)
         );
     }
 

+ 1 - 1
main/admin/example_class.csv

@@ -1,3 +1,3 @@
-name;description
+name;description;
 Class A4;20 students in general courses
 Class B5;20 students from technical background

+ 60 - 1
main/admin/index.php

@@ -26,6 +26,20 @@ api_protect_admin_script(true);
 
 $nameTools = get_lang('PlatformAdmin');
 
+if (api_is_multiple_url_enabled()) {
+    $accessUrlId = api_get_current_access_url_id();
+
+    if ($accessUrlId != -1) {
+        $urlInfo = api_get_access_url($accessUrlId);
+        $url = api_remove_trailing_slash(preg_replace('/https?:\/\//i', '', $urlInfo['url']));
+        $cleanUrl = str_replace('/', '-', $url);
+
+        $adminExtraContentDir = api_get_path(SYS_PATH) . "home/$cleanUrl/admin/";
+    }
+} else {
+    $adminExtraContentDir = api_get_path(SYS_PATH) . "home/admin/";
+}
+
 // Displaying the header
 $message = '';
 
@@ -67,7 +81,15 @@ $blocks['users']['icon']  = Display::return_icon('members.gif', get_lang('Users'
 $blocks['users']['label'] = api_ucfirst(get_lang('Users'));
 $blocks['users']['class'] = 'block-admin-users';
 
+$usersBlockExtraFile = "{$adminExtraContentDir}block-admin-users_extra.html";
+
+if (file_exists($usersBlockExtraFile)) {
+    $blocks['users']['extraContent'] = file_get_contents($usersBlockExtraFile);
+}
+
 if (api_is_platform_admin()) {
+    $blocks['users']['editable'] = true;
+
     $search_form = '
             <form method="get" class="form-search" action="user_list.php">
                 <input class="span3" type="text" name="keyword" value="">
@@ -108,6 +130,13 @@ if (api_is_platform_admin()) {
     $blocks['courses']['icon']  = Display::return_icon('course.gif', get_lang('Courses'), array(), ICON_SIZE_MEDIUM, false);
     $blocks['courses']['label'] = api_ucfirst(get_lang('Courses'));
     $blocks['courses']['class'] = 'block-admin-courses';
+    $blocks['courses']['editable'] = true;
+
+    $coursesBlockExtraFile = "{$adminExtraContentDir}block-admin-courses_extra.html";
+
+    if (file_exists($coursesBlockExtraFile)) {
+        $blocks['courses']['extraContent'] = file_get_contents($coursesBlockExtraFile);
+    }
 
     $search_form = ' <form method="get" class="form-search" action="course_list.php">
 							<input class="span3" type="text" name="keyword" value="">
@@ -147,7 +176,13 @@ if (api_is_platform_admin()) {
     $blocks['platform']['icon']  = Display::return_icon('platform.png', get_lang('Platform'), array(), ICON_SIZE_MEDIUM, false);
     $blocks['platform']['label'] = api_ucfirst(get_lang('Platform'));
     $blocks['platform']['class'] = 'block-admin-platform';
+    $blocks['platform']['editable'] = true;
 
+    $platformBlockExtraFile = "{$adminExtraContentDir}block-admin-platform_extra.html";
+
+    if (file_exists($platformBlockExtraFile)) {
+        $blocks['platform']['extraContent'] = file_get_contents($platformBlockExtraFile);
+    }
 
     $search_form = ' <form method="get" action="settings.php" class="form-search">
 							<input class="span3" type="text" name="search_field" value="" >
@@ -156,7 +191,6 @@ if (api_is_platform_admin()) {
 	            		</form>';
 	$blocks['platform']['search_form'] = $search_form;
 
-
     $items = array();
     $items[] = array('url'=>'settings.php', 				'label' => get_lang('PlatformConfigSettings'));
     $items[] = array('url'=>'settings.php?category=Plugins','label' => get_lang('Plugins'));
@@ -195,6 +229,15 @@ $blocks['sessions']['icon']  = Display::return_icon('session.png', get_lang('Ses
 $blocks['sessions']['label'] = api_ucfirst(get_lang('Sessions'));
 $blocks['sessions']['class'] = 'block-admin-sessions';
 
+$sessionsBlockExtraFile = "{$adminExtraContentDir}block-admin-sessions_extra.html";
+
+if (file_exists($sessionsBlockExtraFile)) {
+    $blocks['sessions']['extraContent'] = file_get_contents($sessionsBlockExtraFile);
+}
+
+if (api_is_platform_admin()) {
+    $blocks['sessions']['editable'] = true;
+}
 
 $search_form = ' <form method="GET" class="form-search" action="session_list.php">
                     <input class="span3" type="text" name="keyword" value="">
@@ -338,6 +381,22 @@ if (api_is_platform_admin()) {
 $admin_ajax_url = api_get_path(WEB_AJAX_PATH).'admin.ajax.php';
 
 $tpl = new Template();
+
+// Display the Site Use Cookie Warning Validation
+$useCookieValidation = api_get_configuration_value('cookie_warning');
+if ($useCookieValidation) {
+    if (isset($_POST['acceptCookies'])) {
+        api_set_site_use_cookie_warning_cookie();
+    } else if (!api_site_use_cookie_warning_cookie_exist()) {
+        if (Template::isToolBarDisplayedForUser()) {
+            $tpl->assign('toolBarDisplayed', true);
+        } else {
+            $tpl->assign('toolBarDisplayed', false);
+        }
+        $tpl->assign('displayCookieUsageWarning', true);
+    }
+}
+
 $tpl->assign('web_admin_ajax_url', $admin_ajax_url);
 $tpl->assign('blocks', $blocks);
 // The template contains the call to the AJAX version checker

+ 59 - 53
main/admin/session_add.php

@@ -96,55 +96,65 @@ function fill_coach_field (username) {
 
 
 if (isset($_POST['formSent']) && $_POST['formSent']) {
-	$formSent = 1;
-    $name = $_POST['name'];
-    $year_start = $_POST['year_start'];
-    $month_start = $_POST['month_start'];
-    $day_start = $_POST['day_start'];
-    $year_end = $_POST['year_end'];
-    $month_end = $_POST['month_end'];
-    $day_end = $_POST['day_end'];
-    $nb_days_acess_before = $_POST['nb_days_acess_before'];
-    $nb_days_acess_after = $_POST['nb_days_acess_after'];
-    $coach_username = $_POST['coach_username'];
-    $id_session_category = $_POST['session_category'];
-    $id_visibility = $_POST['session_visibility'];
-    $end_limit = $_POST['end_limit'];
-    $start_limit = $_POST['start_limit'];
-    $duration = isset($_POST['duration']) ? $_POST['duration'] : null;
-
-    if (empty($end_limit) && empty($start_limit)) {
-        $nolimit = 1;
+    $check = Security::check_token('post');
+    Security::clear_token();
+    if ($check) {
+        $formSent = 1;
+        $name = $_POST['name'];
+        $year_start = $_POST['year_start'];
+        $month_start = $_POST['month_start'];
+        $day_start = $_POST['day_start'];
+        $year_end = $_POST['year_end'];
+        $month_end = $_POST['month_end'];
+        $day_end = $_POST['day_end'];
+        $nb_days_acess_before = $_POST['nb_days_acess_before'];
+        $nb_days_acess_after = $_POST['nb_days_acess_after'];
+        $coach_username = $_POST['coach_username'];
+        $id_session_category = $_POST['session_category'];
+        $id_visibility = $_POST['session_visibility'];
+        $end_limit = $_POST['end_limit'];
+        $start_limit = $_POST['start_limit'];
+        $duration = isset($_POST['duration']) ? $_POST['duration'] : null;
+
+        if (empty($end_limit) && empty($start_limit)) {
+            $nolimit = 1;
+        } else {
+            $nolimit = null;
+        }
+
+        $return = SessionManager::create_session(
+            $name,
+            $year_start,
+            $month_start,
+            $day_start,
+            $year_end,
+            $month_end,
+            $day_end,
+            $nb_days_acess_before,
+            $nb_days_acess_after,
+            $nolimit,
+            $coach_username,
+            $id_session_category,
+            $id_visibility,
+            $start_limit,
+            $end_limit,
+            $duration
+        );
+
+        if ($return == strval(intval($return))) {
+            // integer => no error on session creation
+            header('Location: add_courses_to_session.php?id_session=' . $return . '&add=true&msg=');
+            exit();
+        }
     } else {
-    	$nolimit = null;
+        header('Location: '.api_get_self());
+        exit();
     }
-
-    $return = SessionManager::create_session(
-        $name,
-        $year_start,
-        $month_start,
-        $day_start,
-        $year_end,
-        $month_end,
-        $day_end,
-        $nb_days_acess_before,
-        $nb_days_acess_after,
-        $nolimit,
-        $coach_username,
-        $id_session_category,
-        $id_visibility,
-        $start_limit,
-        $end_limit,
-        $duration
-    );
-
-	if ($return == strval(intval($return))) {
-		// integer => no error on session creation
-		header('Location: add_courses_to_session.php?id_session='.$return.'&add=true&msg=');
-		exit();
-	}
 }
 
+$token = Security::get_token();
+
+
 global $_configuration;
 $defaultBeforeDays = isset($_configuration['session_days_before_coach_access']) ?
     $_configuration['session_days_before_coach_access'] : 0;
@@ -168,16 +178,16 @@ if (!empty($return)) {
 echo '<div class="actions">';
 echo '<a href="../admin/index.php">'.Display::return_icon('back.png', get_lang('BackTo').' '.get_lang('PlatformAdmin'),'',ICON_SIZE_MEDIUM).'</a>';
 echo '</div>';
-
 ?>
 <form class="form-horizontal" method="post" name="form" action="<?php echo api_get_self(); ?>" style="margin:0px;">
+    <input type="hidden" name="sec_token" value="<?php echo $token; ?>">
     <input type="hidden" name="formSent" value="1">
     <div class="control-group">
         <label class="control-label">
             <?php echo get_lang('SessionName') ?>
         </label>
         <div class="controls">
-            <input type="text" name="name" class="span4" maxlength="50" value="<?php if($formSent) echo api_htmlentities($name,ENT_QUOTES,$charset); ?>">
+            <input type="text" name="name" class="span4" maxlength="50" value="<?php if($formSent) echo Security::remove_XSS($name); ?>">
         </div>
     </div>
 
@@ -250,8 +260,8 @@ $Categories = SessionManager::get_all_session_category();
             <a href="javascript://" onclick="if(document.getElementById('options').style.display == 'none'){document.getElementById('options').style.display = 'block';}else{document.getElementById('options').style.display = 'none';}"><?php echo get_lang('DefineSessionOptions') ?></a>
         <div style="display: <?php if($formSent && ($nb_days_acess_before!=0 || $nb_days_acess_after!=0)) echo 'block'; else echo 'none'; ?>;" id="options">
             <br />
-            <input type="text" name="nb_days_acess_before" value="<?php echo $nb_days_acess_before; ?>" style="width: 30px;">&nbsp;<?php echo get_lang('DaysBefore') ?><br /><br />
-            <input type="text" name="nb_days_acess_after" value="<?php echo $nb_days_acess_after; ?>" style="width: 30px;">&nbsp;<?php echo get_lang('DaysAfter') ?>
+            <input type="text" name="nb_days_acess_before" value="<?php echo intval($nb_days_acess_before); ?>" style="width: 30px;">&nbsp;<?php echo get_lang('DaysBefore') ?><br /><br />
+            <input type="text" name="nb_days_acess_after" value="<?php echo intval($nb_days_acess_after); ?>" style="width: 30px;">&nbsp;<?php echo get_lang('DaysAfter') ?>
             <br />
         </div>
         </div>
@@ -326,12 +336,8 @@ for ($i=$thisYear-5;$i <= ($thisYear+5);$i++) {
 ?>
     </select>
     </div>
-
         </div>
     </div>
-
-
-
  <div class="control-group">
         <div class="controls">
             <label for="end_limit">

+ 3 - 4
main/admin/session_edit.php

@@ -4,9 +4,6 @@
  * Sessions edition script
  * @package chamilo.admin
  */
-/**
- * Code
- */
 
 // name of the language file that needs to be included
 $language_file ='admin';
@@ -129,9 +126,11 @@ Display::display_header($tool_name);
 if (!empty($return)) {
     Display::display_error_message($return,false);
 }
+
+$page = isset($_GET['page']) && $_GET['page'] == 'resume_session.php' ? 'resume_session.php' : null;
 ?>
 
-<form class="form-horizontal" method="post" name="form" action="<?php echo api_get_self(); ?>?page=<?php echo Security::remove_XSS($_GET['page']) ?>&id=<?php echo $id; ?>" style="margin:0px;">
+<form class="form-horizontal" method="post" name="form" action="<?php echo api_get_self(); ?>?page=<?php echo $page; ?>&id=<?php echo $id; ?>" style="margin:0px;">
 <fieldset>
     <legend><?php echo $tool_name; ?></legend>
     <input type="hidden" name="formSent" value="1">

+ 6 - 2
main/admin/sub_language.class.php

@@ -412,8 +412,9 @@ class SubLanguageManager
         // select language - if case several languages match, get the last (more recent) one
         $sql = "SELECT english_name
                 FROM " . $adminLanguagesTable . "
-                WHERE isocode ='$isocode'
-                    AND available = 1
+                WHERE
+                    isocode ='$isocode' AND
+                    available = 1
                 ORDER BY id
                 DESC LIMIT 1";
         $res = Database::query($sql);
@@ -434,7 +435,9 @@ class SubLanguageManager
         if (empty($preferences)) {
             return false;
         }
+
         $preferencesArray = explode(',', $preferences);
+
         if (count($preferencesArray) > 0) {
             foreach ($preferencesArray as $pref) {
                 $s = strpos($pref, ';');
@@ -444,6 +447,7 @@ class SubLanguageManager
                     $code = $pref;
                 }
                 $name = self::getLanguageFromIsocode($code);
+
                 if ($name !== false) {
                     return $name;
                 }

+ 8 - 0
main/admin/user_list.php

@@ -446,6 +446,14 @@ function get_user_data($from, $number_of_items, $column, $direction) {
     $from 	= intval($from);
     $number_of_items = intval($number_of_items);
 
+    global $_configuration;
+    if (api_is_session_admin()
+        && isset($_configuration['prevent_session_admins_to_manage_all_users'])
+        && $_configuration['prevent_session_admins_to_manage_all_users'] == 'true'
+    ) {
+        $sql .= " WHERE u.creator_id = " . api_get_user_id();
+    }
+
 	$sql .= " ORDER BY col$column $direction ";
 	$sql .= " LIMIT $from,$number_of_items";
 

+ 6 - 6
main/admin/usergroup_export.php

@@ -1,11 +1,10 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
  *	@package chamilo.admin
  */
-/**
- * Code
- */
+
 // name of the language file that needs to be included
 $language_file = 'admin';
 $cidReset = true;
@@ -29,14 +28,15 @@ $form->addElement('header', $tool_name);
 $form->addElement('style_submit_button', 'submit', get_lang('Export'), 'class="save"');
 
 if ($form->validate()) {
-    $user_group = new UserGroup;
-    $header = array(array('id', 'name', 'description'));
-    $data = $user_group->get_all_for_export();
+    $userGroup = new UserGroup();
+    $header = array(array('id', 'name', 'description', 'users'));
+    $data = $userGroup->getDataToExport();
     $data = array_merge($header, $data);
     $filename = 'export_classes_'.api_get_local_time();
     Export::export_table_csv($data, $filename);
     exit;
 }
+
 Display :: display_header($tool_name);
 $form->display();
 Display::display_footer();

+ 26 - 6
main/admin/usergroup_import.php

@@ -1,5 +1,6 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
  *  This tool allows platform admins to add classes by uploading a CSV file
  *  @todo Add some langvars to DLTT
@@ -13,7 +14,7 @@ function validate_data($classes) {
     $errors = array();
     $usergroup = new UserGroup();
     foreach ($classes as $index => $class) {
-        // 1. Check wheter ClassName is available.
+        // 1. Check of class name is available.
         if (!isset($class['name']) || strlen(trim($class['name'])) == 0) {
             $class['line'] = $index + 2;
             $class['error'] = get_lang('MissingClassName');
@@ -41,15 +42,34 @@ function validate_data($classes) {
  */
 function save_data($classes)
 {
-    $number_of_added_classes = 0;
+    $count = 0;
     $usergroup = new UserGroup();
     foreach ($classes as $index => $class) {
+        $usersToAdd = isset($class['users']) ? $class['users'] : null;
+        unset($class['users']);
         $id = $usergroup->save($class);
         if ($id) {
-            $number_of_added_classes++;
+            if (!empty($usersToAdd)) {
+                $usersToAddList = explode(',', $usersToAdd);
+                $userIdList = array();
+                foreach ($usersToAddList as $username) {
+                    $userInfo = api_get_user_info_from_username($username);
+                    $userIdList[] = $userInfo['user_id'];
+                }
+                if (!empty($userIdList)) {
+                    $usergroup->subscribe_users_to_usergroup(
+                        $id,
+                        $userIdList,
+                        false
+                    );
+                }
+            }
+
+            $count++;
         }
     }
-    return $number_of_added_classes;
+
+    return $count;
 }
 
 // Language files that should be included.
@@ -113,8 +133,8 @@ $form->display();
 <p><?php echo get_lang('CSVMustLookLike') . ' (' . get_lang('MandatoryFields') . ')'; ?> :</p>
 
 <pre>
-<b>name;description</b>
-"User group 1";"Description"
+<b>name;description;</b>users
+"User group 1";"Description";admin,username1,username2
 </pre>
 <?php
 // Displaying the footer.

+ 38 - 4
main/calendar/agenda.lib.php

@@ -16,6 +16,7 @@ class Agenda
     public $senderId;
     /** @var array */
     public $course;
+    public $comment;
 
     /**
      * Constructor
@@ -67,7 +68,11 @@ class Agenda
      */
     public function setType($type)
     {
-        $this->type = $type;
+        $typeList = $this->getTypes();
+
+        if (in_array($type, $typeList)) {
+            $this->type = $type;
+        }
     }
 
     /**
@@ -114,6 +119,7 @@ class Agenda
      * @param int $parentEventId
      * @param array $attachmentArray $_FILES['']
      * @param string $attachmentComment
+     * @param string $eventComment
      *
      * @return int
      */
@@ -127,7 +133,8 @@ class Agenda
         $addAsAnnouncement = false,
         $parentEventId = null,
         $attachmentArray = array(),
-        $attachmentComment = null
+        $attachmentComment = null,
+        $eventComment = null
     ) {
         $start = api_get_utc_datetime($start);
         $end = api_get_utc_datetime($end);
@@ -160,6 +167,12 @@ class Agenda
                     'c_id' => $this->course['real_id']
                 );
 
+                $allow = api_get_configuration_value('allow_agenda_event_comment');
+
+                if ($allow) {
+                    $attributes['comment'] = $eventComment;
+                }
+
                 if (!empty($parentEventId)) {
                     $attributes['parent_event_id'] = $parentEventId;
                 }
@@ -533,6 +546,7 @@ class Agenda
      * @param int $editRepeatType
      * @param array $attachmentArray
      * @param string $attachmentComment
+     * @param string $comment
      *
      * @return bool
      */
@@ -545,7 +559,8 @@ class Agenda
         $content,
         $usersToSend = array(),
         $attachmentArray = array(),
-        $attachmentComment = null
+        $attachmentComment = null,
+        $comment = null
     ) {
         $start = api_get_utc_datetime($start);
         $end = api_get_utc_datetime($end);
@@ -594,6 +609,12 @@ class Agenda
                         'all_day' => $allDay
                     );
 
+                    $allow = api_get_configuration_value('allow_agenda_event_comment');
+
+                    if ($allow) {
+                        $attributes['comment'] = $comment;
+                    }
+
                     Database::update(
                         $this->tbl_course_agenda,
                         $attributes,
@@ -1322,6 +1343,7 @@ class Agenda
         }
 
         $sql .= $dateCondition;
+        $allowComments = api_get_configuration_value('allow_agenda_event_comment');
 
         $result = Database::query($sql);
         if (Database::num_rows($result)) {
@@ -1428,9 +1450,16 @@ class Agenda
                 $event['parent_event_id'] = $row['parent_event_id'];
                 $event['has_children'] = $this->hasChildren($row['id'], $course_id) ? 1 : 0;
 
+                if ($allowComments) {
+                    $event['comment'] = $row['comment'];
+                } else {
+                    $event['comment'] = null;
+                }
+
                 $this->events[] = $event;
             }
         }
+
         return $this->events;
     }
 
@@ -1822,6 +1851,11 @@ class Agenda
         );
 
         if ($this->type == 'course') {
+            $allow = api_get_configuration_value('allow_agenda_event_comment');
+
+            if ($allow) {
+                $form->addElement('textarea', 'comment', get_lang('Comment'));
+            }
 
             $form->addElement('file', 'user_upload', get_lang('AddAnAttachment'));
             if ($showAttachmentForm) {
@@ -1839,7 +1873,7 @@ class Agenda
                 }
             }
 
-            $form->addElement('textarea', 'file_comment', get_lang('Comment'));
+            $form->addElement('textarea', 'file_comment', get_lang('FileComment'));
         }
 
         if (empty($id)) {

+ 9 - 3
main/calendar/agenda.php

@@ -114,6 +114,8 @@ if (api_is_allowed_to_edit(false, true) OR
                 $attachment = $sendAttachment ? $_FILES['user_upload'] : null;
                 $attachmentComment = isset($values['file_comment']) ? $values['file_comment'] : null;
 
+                $comment = isset($values['comment']) ? $values['comment'] : null;
+
                 $startDate = $values['date_range_start'];
                 $endDate = $values['date_range_end'];
 
@@ -127,7 +129,8 @@ if (api_is_allowed_to_edit(false, true) OR
                     $sendEmail,
                     null,
                     $attachment,
-                    $attachmentComment
+                    $attachmentComment,
+                    $comment
                 );
 
                 if (!empty($values['repeat']) && !empty($eventId)) {
@@ -174,6 +177,7 @@ if (api_is_allowed_to_edit(false, true) OR
                 $sendAttachment = isset($_FILES['user_upload']) ? true : false;
                 $attachment = $sendAttachment ? $_FILES['user_upload'] : null;
                 $attachmentComment = isset($values['file_comment']) ? $values['file_comment'] : null;
+                $comment = isset($values['comment']) ? $values['comment'] : null;
 
                 // This is a sub event. Delete the current and create another BT#7803
 
@@ -190,7 +194,8 @@ if (api_is_allowed_to_edit(false, true) OR
                         false,
                         null,
                         $attachment,
-                        $attachmentComment
+                        $attachmentComment,
+                        $comment
                     );
 
                     $message = Display::return_message(get_lang('Updated'), 'confirmation');
@@ -209,7 +214,8 @@ if (api_is_allowed_to_edit(false, true) OR
                     $values['content'],
                     $values['users_to_send'],
                     $attachment,
-                    $attachmentComment
+                    $attachmentComment,
+                    $comment
                 );
 
                 if (!empty($values['repeat']) && !empty($eventId)) {

+ 8 - 0
main/calendar/agenda_js.php

@@ -1,5 +1,6 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
  * @package chamilo.calendar
  */
@@ -221,10 +222,15 @@ $form->addElement('label', get_lang('Date'), '<span id="start_date"></span><span
 $form->addElement('text', 'title', get_lang('Title'), array('id' => 'title'));
 $form->addElement('textarea', 'content', get_lang('Description'), array('id' => 'content'));
 
+$allowEventComment = api_get_configuration_value('allow_agenda_event_comment');
+
 if ($agenda->type == 'course') {
     $form->addElement('html', '<div id="add_as_announcement_div" style="display: none">');
     $form->addElement('checkbox', 'add_as_annonuncement', null, get_lang('AddAsAnnouncement'));
     $form->addElement('html', '</div>');
+    if ($allowEventComment) {
+        $form->addElement('textarea', 'comment', get_lang('Comment'), array('id' => 'comment'));
+    }
 }
 
 $tpl->assign('form_add', $form->return_form());
@@ -234,6 +240,8 @@ $content = $tpl->fetch('default/agenda/month.tpl');
 
 $message = Session::read('message');
 $tpl->assign('message', $message);
+$tpl->assign('allow_agenda_event_comment', $allowEventComment);
+
 Session::erase('message');
 
 $tpl->assign('content', $content);

+ 2 - 4
main/calendar/agenda_list.php

@@ -3,9 +3,7 @@
 /**
  * @package chamilo.calendar
  */
-/**
- * INIT SECTION
- */
+
 // name of the language file that needs to be included
 $language_file = array('agenda', 'group', 'announcements');
 
@@ -20,7 +18,7 @@ $interbreadcrumb[] = array(
 
 $agenda = new Agenda();
 $type = isset($_REQUEST['type']) ? $_REQUEST['type'] : null;
-$agenda->type = $type;
+$agenda->setType($type);
 $events = $agenda->get_events(
     null,
     null,

+ 1 - 1
main/chat/chat_functions.lib.php

@@ -157,7 +157,7 @@ function saveMessage($message, $userId, $_course, $session_id, $group_id, $previ
     if (!api_is_anonymous()) {
         if (!empty($message)) {
             Emojione\Emojione::$imagePathPNG = api_get_path(WEB_LIBRARY_PATH).'javascript/emojione/png/';
-            Emojione\Emojione::$imagePathSVG = api_get_path(WEB_LIBRARY_PATH).'javascript/emojione/svg/';
+            //Emojione\Emojione::$imagePathSVG = api_get_path(WEB_LIBRARY_PATH).'javascript/emojione/svg/';
             Emojione\Emojione::$ascii = true;
 
             // Parsing emojis

+ 0 - 1
main/course_home/activity.php

@@ -65,7 +65,6 @@ if ($enabled == 'true') {
 //	COURSE ADMIN ONLY VIEW
 
 // 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="courseadminview" style="border:0px; margin-top: 0px;padding:0px;">
 		<div class="normal-message" id="id_normal_message" style="display:none">';

+ 11 - 15
main/course_home/course_home.php

@@ -28,13 +28,10 @@
 *	@package chamilo.course_home
 */
 
-/* 		INIT SECTION		*/
-
-
 use \ChamiloSession as Session;
 
 // Name of the language file that needs to be included.
-$language_file = array('course_home','courses');
+$language_file = array('course_home', 'courses');
 $use_anonymous = true;
 
 // Inlcuding the global initialization file.
@@ -48,9 +45,7 @@ require_once dirname(__FILE__).'/../inc/global.inc.php';
 //unset($_SESSION['lpobject']);
 
 $htmlHeadXtra[] ='<script>
-
 /* option show/hide thematic-block */
-
 $(document).ready(function(){
     $("#thematic-show").click(function(){
         $(".btn-hide-thematic").hide();
@@ -64,7 +59,6 @@ $(document).ready(function(){
     });
 });
 
-
 $(document).ready(function() {
 	$(".make_visible_and_invisible").attr("href", "javascript:void(0);");
 	$(".make_visible_and_invisible > img").click(function () {
@@ -119,7 +113,6 @@ $(document).ready(function() {
 	});
 });
 
-
 </script>';
 
 // The section for the tabs
@@ -140,11 +133,11 @@ define('TOOL_DRH', 'tool_drh');
 define('TOOL_STUDENT_VIEW', 'toolstudentview');
 define('TOOL_ADMIN_VISIBLE', 'tooladminvisible');
 
-$user_id 		= api_get_user_id();
-$course_code 	= api_get_course_id();
+$user_id = api_get_user_id();
+$course_code = api_get_course_id();
 $show_message = '';
 
-//Deleting group session
+// Deleting group session
 Session::erase('toolgroup');
 Session::erase('_gid');
 
@@ -255,12 +248,15 @@ $content = Display::return_introduction_section(TOOL_COURSE_HOMEPAGE, array(
 	the setting homepage_view is adjustable through
 	the platform administration section */
 
-//require_once api_get_path(LIBRARY_PATH).'course_home.lib.php';
-
 if ($show_autolunch_lp_warning) {
-    $show_message .= Display::return_message(get_lang('TheLPAutoLaunchSettingIsONStudentsWillBeRedirectToAnSpecificLP'),'warning');
+    $show_message .= Display::return_message(
+        get_lang('TheLPAutoLaunchSettingIsONStudentsWillBeRedirectToAnSpecificLP'),
+        'warning'
+    );
 }
-if (api_get_setting('homepage_view') == 'activity' || api_get_setting('homepage_view') == 'activity_big') {
+if (api_get_setting('homepage_view') == 'activity' ||
+    api_get_setting('homepage_view') == 'activity_big'
+) {
 	require 'activity.php';
 } elseif (api_get_setting('homepage_view') == '2column') {
 	require '2column.php';

+ 3 - 5
main/coursecopy/copy_course_session.php

@@ -1,5 +1,6 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
  * Copy resources from one course in a session to another one.
  *
@@ -7,10 +8,6 @@
  * @author Julio Montoya <gugli100@gmail.com> Lots of bug fixes/improvements
  * @package chamilo.backup
  */
-/**
- * Code
- */
-/*  INIT SECTION  */
 
 // Language files that need to be included
 $language_file = array('coursebackup', 'admin');
@@ -18,7 +15,8 @@ $language_file = array('coursebackup', 'admin');
 $cidReset = true;
 require_once '../inc/global.inc.php';
 $current_course_tool  = TOOL_COURSE_MAINTENANCE;
-api_protect_course_script(true, true);
+
+api_protect_global_admin_script();
 
 require_once api_get_path(LIBRARY_PATH).'fileManage.lib.php';
 require_once api_get_path(LIBRARY_PATH).'xajax/xajax.inc.php';

+ 0 - 4
main/coursecopy/copy_course_session_selected.php

@@ -8,10 +8,6 @@
  * @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com> Code conventions
  * @package chamilo.backup
  */
-/**
- * Code
- */
-/* INIT SECTION */
 
 // Language files that need to be included
 $language_file = array('coursebackup', 'admin');

+ 155 - 17
main/cron/import_csv.php

@@ -109,7 +109,10 @@ class ImportCsv
                     $isStatic = strpos($method, 'Static');
 
                     if (method_exists($this, $method)) {
-                        if ($method == 'importUnsubscribeStatic' || empty($isStatic)) {
+                        if (($method == 'importUnsubscribeStatic' ||
+                            $method == 'importSubscribeStatic') ||
+                            empty($isStatic)
+                        ) {
                             $fileToProcess[$parts[1]][] = array(
                                 'method' => $method,
                                 'file' => $path.$fileInfo['basename']
@@ -144,8 +147,10 @@ class ImportCsv
                 'teachers',
                 'courses',
                 'sessions',
+                'subscribe-static',
                 'unsubscribe-static'
             );
+
             foreach ($sections as $section) {
                 $this->logger->addInfo("-- Import $section --");
 
@@ -169,6 +174,7 @@ class ImportCsv
                 'sessions-static',
                 'calendar-static',
             );
+
             foreach ($sections as $section) {
                 $this->logger->addInfo("-- Import static files $section --");
 
@@ -644,17 +650,47 @@ class ImportCsv
     {
         $data = Import::csv_to_array($file);
 
+        if ($this->getDumpValues()) {
+            // Remove all calendar items
+            $truncateTables = array(
+                Database::get_course_table(TABLE_AGENDA),
+                Database::get_course_table(TABLE_AGENDA_ATTACHMENT),
+                Database::get_course_table(TABLE_AGENDA_REPEAT),
+                Database::get_course_table(TABLE_AGENDA_REPEAT_NOT),
+                Database::get_main_table(TABLE_PERSONAL_AGENDA),
+                Database::get_main_table(TABLE_PERSONAL_AGENDA_REPEAT_NOT),
+                Database::get_main_table(TABLE_PERSONAL_AGENDA_REPEAT)
+            );
+
+            foreach ($truncateTables as $table) {
+                $sql = "TRUNCATE $table";
+                Database::query($sql);
+            }
+
+            $table = Database::get_course_table(TABLE_ITEM_PROPERTY);
+            $sql = "DELETE FROM $table WHERE tool = 'calendar_event'";
+            Database::query($sql);
+        }
+
         if (!empty($data)) {
             $this->logger->addInfo(count($data) . " records found.");
             $eventsToCreate = array();
             $errorFound = false;
             foreach ($data as $row) {
-                $sessionId = SessionManager::get_session_id_from_original_id(
-                    $row['external_sessionID'],
-                    $this->extraFieldIdNameList['session']
-                );
+                $sessionId = null;
+                $externalSessionId = null;
+                if (isset($row['external_sessionID'])) {
+                    $externalSessionId = $row['external_sessionID'];
+                    $sessionId = SessionManager::get_session_id_from_original_id(
+                        $externalSessionId,
+                        $this->extraFieldIdNameList['session']
+                    );
+                }
 
-                $courseCode = $row['coursecode'];
+                $courseCode  = null;
+                if (isset($row['coursecode'])) {
+                    $courseCode = $row['coursecode'];
+                }
                 $courseInfo = api_get_course_info($courseCode);
 
                 if (empty($courseInfo)) {
@@ -662,7 +698,7 @@ class ImportCsv
                 }
 
                 if (empty($sessionId)) {
-                    $this->logger->addInfo("external_sessionID: ".$row['external_sessionID']." does not exists.");
+                    $this->logger->addInfo("external_sessionID: ".$externalSessionId." does not exists.");
                 }
                 $teacherId = null;
 
@@ -793,6 +829,12 @@ class ImportCsv
                 $agenda->setSessionId($event['session_id']);
                 $agenda->setSenderId($event['sender_id']);
 
+                $eventComment = $event['comment'];
+
+                // To use the event comment you need
+                // ALTER TABLE c_calendar_event ADD COLUMN comment TEXT;
+                // add in configuration.php allow_agenda_event_comment = true
+
                 if (empty($courseInfo)) {
                     $this->logger->addInfo(
                         "No course found for added: #".$event['course_id']." Skipping ..."
@@ -814,7 +856,11 @@ class ImportCsv
                     $event['title'],
                     $content,
                     array('everyone'), // send to
-                    false //$addAsAnnouncement = false
+                    false, //$addAsAnnouncement = false
+                    null, //  $parentEventId
+                    array(), //$attachmentArray = array(),
+                    null, //$attachmentComment = null,
+                    $eventComment
                 );
 
                 if (!empty($eventId)) {
@@ -970,7 +1016,6 @@ class ImportCsv
                     // 2014-06-30
                     $dateStart = explode('/', $session['DateStart']);
                     $dateEnd = explode('/', $session['DateEnd']);
-                    //$visibility = $session['visibility'];
                     $visibility = $this->defaultSessionVisibility;
 
                     $coachId = null;
@@ -988,12 +1033,13 @@ class ImportCsv
                             $dateEnd[0],
                             $dateEnd[1],
                             $dateEnd[2],
-                            null, //$session['nb_days_access_before_beginning'],
-                            null, //$session['nb_days_access_after_end'],
+                            $this->daysCoachAccessBeforeBeginning,
+                            $this->daysCoachAccessAfterBeginning,
                             null,
                             $coachUserName,
                             $categoryId,
-                            $visibility
+                            $visibility,
+                            1
                         );
 
                         if (is_numeric($result)) {
@@ -1005,6 +1051,28 @@ class ImportCsv
                             );
                         }
                     } else {
+
+                        $sessionInfo = api_get_session_info($sessionId);
+                        $accessBefore = null;
+                        $accessAfter = null;
+
+                        if (empty($sessionInfo['nb_days_access_before_beginning']) ||
+                            (!empty($sessionInfo['nb_days_access_before_beginning']) &&
+                                $sessionInfo['nb_days_access_before_beginning'] < $this->daysCoachAccessBeforeBeginning)
+                        ) {
+                            $accessBefore = intval($this->daysCoachAccessBeforeBeginning);
+                        }
+
+                        $accessAfter = null;
+                        if (empty($sessionInfo['nb_days_access_after_end']) ||
+                            (!empty($sessionInfo['nb_days_access_after_end']) &&
+                                $sessionInfo['nb_days_access_after_end'] < $this->daysCoachAccessAfterBeginning)
+                        ) {
+                            $accessAfter = intval($this->daysCoachAccessAfterBeginning);
+                        }
+
+                        $showDescription = isset($sessionInfo['show_description']) ? $sessionInfo['show_description'] : 1;
+
                         $result = SessionManager::edit_session(
                             $sessionId,
                             $session['SessionName'],
@@ -1014,12 +1082,16 @@ class ImportCsv
                             $dateEnd[0],
                             $dateEnd[1],
                             $dateEnd[2],
-                            null,//$session['nb_days_access_before_beginning'],
-                            null,//$session['nb_days_access_after_end'],
+                            $accessBefore,
+                            $accessAfter,
                             null,
                             $coachId,
                             $categoryId,
-                            $visibility
+                            $visibility,
+                            true, //$start_limit =
+                            true, //$end_limit =
+                            null, //$description
+                            $showDescription // $showDescription = null,
                         );
 
                         if (is_numeric($result)) {
@@ -1143,7 +1215,10 @@ class ImportCsv
             $avoid,
             false, // deleteUsersNotInList
             false, // updateCourseCoaches
-            true // sessionWithCoursesModifier
+            true, // sessionWithCoursesModifier
+            true, //$addOriginalCourseTeachersAsCourseSessionCoaches
+            true, //$removeAllTeachersFromCourse
+            1 // $showDescription
         );
 
         if (!empty($result['error_message'])) {
@@ -1156,6 +1231,67 @@ class ImportCsv
         }
     }
 
+    /**
+     * @param string $file
+     */
+    private function importSubscribeStatic($file)
+    {
+        $data = Import::csv_reader($file);
+
+        if (!empty($data)) {
+            $this->logger->addInfo(count($data) . " records found.");
+            foreach ($data as $row) {
+                $chamiloUserName = $row['UserName'];
+                $chamiloCourseCode = $row['CourseCode'];
+                $chamiloSessionId = $row['SessionID'];
+                $type = $row['Type'];
+
+                $sessionInfo = api_get_session_info($chamiloSessionId);
+
+                if (empty($sessionInfo)) {
+                    $this->logger->addError('Session does not exists: '.$chamiloSessionId);
+                    continue;
+                }
+
+                $courseInfo = api_get_course_info($chamiloCourseCode);
+                if (empty($courseInfo)) {
+                    $this->logger->addError('Course does not exists: '.$courseInfo);
+                    continue;
+                }
+
+                $userId = Usermanager::get_user_id_from_username($chamiloUserName);
+
+                if (empty($userId)) {
+                    $this->logger->addError('User does not exists: '.$chamiloUserName);
+                    continue;
+                }
+                $status = null;
+                switch ($type) {
+                    case 'student':
+                        SessionManager::subscribe_users_to_session_course(
+                            array($userId),
+                            $chamiloSessionId,
+                            $courseInfo['code'],
+                            null,
+                            false
+                        );
+                        break;
+                    case 'teacher':
+                        SessionManager::set_coach_to_course_session(
+                            $userId,
+                            $chamiloSessionId,
+                            $courseInfo['code']
+                        );
+                        break;
+                }
+
+                $this->logger->addError(
+                    "User '$chamiloUserName' with status $type was added to session: #$chamiloSessionId - Course: " . $courseInfo['code']
+                );
+            }
+        }
+    }
+
     /**
      * @param string $file
      */
@@ -1191,7 +1327,9 @@ class ImportCsv
                 }
 
                 CourseManager::unsubscribe_user($userId, $courseInfo['code'], $chamiloSessionId);
-                $this->logger->addError("User '$chamiloUserName' was removed from session: #$chamiloSessionId, Course: ".$courseInfo['code']);
+                $this->logger->addError(
+                    "User '$chamiloUserName' was removed from session: #$chamiloSessionId, Course: ".$courseInfo['code']
+                );
             }
         }
     }

+ 24 - 0
main/css/base.css

@@ -5291,3 +5291,27 @@ i.size-32.icon-new-work{
     margin-right: auto;
     max-width: 100%;
 }
+
+/* display the cookie usage warning validation */
+.cookieUsageValidation {
+    padding: 5px;
+    background-color: #333333;
+    color:#E0E0E0;
+    text-align:center;
+}
+
+.displayUnderToolbar
+{
+    height: 52px;
+}
+
+#settings .span6 .well_border .edit-block {
+    display: none;
+}
+#settings .span6 .well_border:hover .edit-block {
+    display: block;
+}
+
+#settings .span6:nth-child(2n+1) {
+    clear:left
+}

+ 15 - 36
main/css/chamilo/default.css

@@ -35,18 +35,11 @@ a:active {
     color: #FFFFFF;
 }
 .subnav .navbar-inner {
-    -webkit-border-radius: 2px;
-    -moz-border-radius: 2px;
-    border-radius: 2px;
-    border: 1px solid #178ACC;
-    background: #4fb2ea; /* Old browsers */
-    background: -moz-linear-gradient(top, #4fb2ea 0%, #0191c7 100%); /* FF3.6+ */
-    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4fb2ea), color-stop(100%,#0191c7)); /* Chrome,Safari4+ */
-    background: -webkit-linear-gradient(top, #4fb2ea 0%,#0191c7 100%); /* Chrome10+,Safari5.1+ */
-    background: -o-linear-gradient(top, #4fb2ea 0%,#0191c7 100%); /* Opera 11.10+ */
-    background: -ms-linear-gradient(top, #4fb2ea 0%,#0191c7 100%); /* IE10+ */
-    background: linear-gradient(to bottom, #4fb2ea 0%,#0191c7 100%); /* W3C */
-    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4fb2ea', endColorstr='#0191c7',GradientType=0 ); /* IE6-9 */    
+    -webkit-border-radius: 0px;
+    -moz-border-radius: 02px;
+    border-radius: 0px;
+    border: none;
+    background: #00a9e0; /* Old browsers */
 }
 
 .subnav .nav > li > a {
@@ -314,10 +307,10 @@ a.thumbnail:hover{
 }
 
 .well {
-  background-color: rgba(96,165,209, 0.1);
-  border: 1px solid rgba(96,165,209, 0.1);
+  background-color: rgba(255,255,255, 0.1);
+  border: 1px solid #EAEAEA;
   border-radius: 8px;
-  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05) inset;
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.09) inset;
   margin-bottom: 20px;
   min-height: 20px;
   padding: 20px 10px;
@@ -361,8 +354,8 @@ a.thumbnail:hover{
   padding-bottom: 0px;
 }
 .well_border{
-  background-color: rgba(96,165,209, 0.1);
-  border: 1px solid rgba(96,165,209, 0.1);
+  background-color: rgba(255,255,255, 0.1);
+  border: 1px solid #EAEAEA;
   border-radius: 8px;
   box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05) inset;
   margin-bottom: 20px;
@@ -633,16 +626,9 @@ a.thumbnail:hover{
  *****************************************************/
 footer {
     height: 7em;
-    background: #4fb2ea; /* Old browsers */
-    background: -moz-linear-gradient(top, #4fb2ea 0%, #0191c7 100%); /* FF3.6+ */
-    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4fb2ea), color-stop(100%,#0191c7)); /* Chrome,Safari4+ */
-    background: -webkit-linear-gradient(top, #4fb2ea 0%,#0191c7 100%); /* Chrome10+,Safari5.1+ */
-    background: -o-linear-gradient(top, #4fb2ea 0%,#0191c7 100%); /* Opera 11.10+ */
-    background: -ms-linear-gradient(top, #4fb2ea 0%,#0191c7 100%); /* IE10+ */
-    background: linear-gradient(to bottom, #4fb2ea 0%,#0191c7 100%); /* W3C */
-    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4fb2ea', endColorstr='#0191c7',GradientType=0 ); /* IE6-9 */
+    background: #00a9e0; /* Old browsers */
     color:#ffffff;
-    border-top: 1px solid #0191C7;
+    border-top: none;
 }
 footer .container .row {
   padding-top: 5px;
@@ -997,14 +983,7 @@ RESPONSIVE CSS
   color: #FFFFFF;
 }
 .navbar-inner{
-  background: #2bb8ef; /* Old browsers */
-  background: -moz-linear-gradient(top, #2bb8ef 0%, #0191c7 100%); /* FF3.6+ */
-  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#2bb8ef), color-stop(100%,#0191c7)); /* Chrome,Safari4+ */
-  background: -webkit-linear-gradient(top, #2bb8ef 0%,#0191c7 100%); /* Chrome10+,Safari5.1+ */
-  background: -o-linear-gradient(top, #2bb8ef 0%,#0191c7 100%); /* Opera 11.10+ */
-  background: -ms-linear-gradient(top, #2bb8ef 0%,#0191c7 100%); /* IE10+ */
-  background: linear-gradient(to bottom, #2bb8ef 0%,#0191c7 100%); /* W3C */
-  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#2bb8ef', endColorstr='#0191c7',GradientType=0 ); /* IE6-9 */
+  background: #00A9E0; /* Old browsers */
 }
 
 .dropdown-menu li > a:hover, .dropdown-menu .active > a, .dropdown-menu .active > a:hover {
@@ -1036,8 +1015,8 @@ RESPONSIVE CSS
         padding-top: 10px;
     }
     #profile_block .nav-list li, #course_block .nav-list li{
-        padding-bottom: 5px;
-        padding-top: 5px;
+        padding-bottom: 10px;
+        padding-top: 10px;
     }
     #top_main_content .menu-column #user_image_block{
       box-shadow: none;

+ 2 - 3
main/css/responsive.css

@@ -228,8 +228,8 @@ The more frequent ones have been marked with *
       width: auto;
     }
     #profile_block .nav-list li, #course_block .nav-list li {
-        padding-bottom: 3px;
-        padding-top: 3px;
+        padding-bottom: 10px;
+        padding-top: 10px;
     }
     .well_border .row .span2 .thumbnail {
     background-color: #FFFFFF;
@@ -731,7 +731,6 @@ The more frequent ones have been marked with *
       box-shadow: none;
     }
     #top_main_content .menu-column .block_user_info {
-        float: left;
         width: 280px;
     }
     .section-mycampus .hot-course-box, .section-mycourses .course-box {

+ 9 - 11
main/document/document.php

@@ -749,13 +749,13 @@ if ($sessionId == 0) {
     if (!file_exists($base_work_dir.'/shared_folder')) {
         $usf_dir_title = get_lang('UserFolders');
         $usf_dir_name = '/shared_folder';
-        $groupId = 0;
+        //$groupId = 0;
         $visibility = 0;
         create_unexisting_directory(
             $courseInfo,
             api_get_user_id(),
             $sessionId,
-            $groupId,
+            0,
             $to_user_id,
             $base_work_dir,
             $usf_dir_name,
@@ -767,13 +767,13 @@ if ($sessionId == 0) {
     if (!file_exists($base_work_dir.'/shared_folder/sf_user_'.$userId)) {
         $usf_dir_title = $userInfo['complete_name'];
         $usf_dir_name = '/shared_folder/sf_user_'.$userId;
-        $groupId = 0;
+        //$groupId = 0;
         $visibility = 1;
         create_unexisting_directory(
             $courseInfo,
             api_get_user_id(),
             $sessionId,
-            $groupId,
+            0,
             $to_user_id,
             $base_work_dir,
             $usf_dir_name,
@@ -786,13 +786,13 @@ if ($sessionId == 0) {
     if (!file_exists($base_work_dir.'/shared_folder_session_'.$sessionId)) {
         $usf_dir_title = get_lang('UserFolders').' ('.api_get_session_name($sessionId).')';
         $usf_dir_name = '/shared_folder_session_'.$sessionId;
-        $groupId = 0;
+        //$groupId = 0;
         $visibility = 0;
         create_unexisting_directory(
             $courseInfo,
             api_get_user_id(),
             $sessionId,
-            $groupId,
+            0,
             $to_user_id,
             $base_work_dir,
             $usf_dir_name,
@@ -804,13 +804,13 @@ if ($sessionId == 0) {
     if (!file_exists($base_work_dir.'/shared_folder_session_'.$sessionId.'/sf_user_'.$userId)) {
         $usf_dir_title = $userInfo['complete_name'].'('.api_get_session_name($sessionId).')';
         $usf_dir_name = '/shared_folder_session_'.$sessionId.'/sf_user_'.$userId;
-        $groupId = 0;
+        //$groupId = 0;
         $visibility = 1;
         create_unexisting_directory(
             $courseInfo,
             $userId,
             $sessionId,
-            $groupId,
+            0,
             $to_user_id,
             $base_work_dir,
             $usf_dir_name,
@@ -1298,8 +1298,7 @@ if ($is_allowed_to_edit ||
 /* 	VISIBILITY COMMANDS */
 if ($is_allowed_to_edit) {
     if ((isset($_GET['set_invisible']) && !empty($_GET['set_invisible'])) ||
-        (isset($_GET['set_visible']) && !empty($_GET['set_visible'])) &&
-        $_GET['set_visible'] != '*' && $_GET['set_invisible'] != '*'
+        (isset($_GET['set_visible']) && !empty($_GET['set_visible']))
     ) {
         // Make visible or invisible?
         if (isset($_GET['set_visible'])) {
@@ -1334,7 +1333,6 @@ if ($is_allowed_to_edit) {
             null,
             $sessionId)
         ) {
-            //don't use ViMod because firt is load ViMdod (Gradebook). VisibilityChanged (trad4all)
             $message = Display::return_message(get_lang('VisibilityChanged'), 'confirmation');
         } else {
             $message = Display::return_message(get_lang('ViModProb'), 'error');

+ 5 - 0
main/document/downloadfolder.inc.php

@@ -93,6 +93,11 @@ function fixDocumentNameCallback($p_event, &$p_header)
         $documentData['to_group_id']
     );
 
+    // Changes file.phps to file.php
+    $basename = basename($documentNameFixed);
+    $basenamePHPFixed = str_replace('.phps', '.php', $basename);
+    $documentNameFixed = str_replace($basename, $basenamePHPFixed, $basenamePHPFixed);
+
     $p_header['stored_filename'] = $documentNameFixed;
 
     return 1;

+ 16 - 6
main/exercice/evalmathnotation.php

@@ -18,21 +18,31 @@ get_lang('PiNumberPi')."\n".
 get_lang('SineSin')."\n".
 get_lang('HyperbolicSineSinh')."\n".
 get_lang('ArcsineArcsin')."\n".
-get_lang('InverseSineAsin')."\n".
 get_lang('HyperbolicArcsineArcsinh')."\n".
-get_lang('InverseHyperbolicSineAsinh')."\n".
 "\n".
 get_lang('CosineCos')."\n".
 get_lang('HyperbolicCosineCosh')."\n".
 get_lang('ArccosineArccos')."\n".
-get_lang('InverseCosineAcos')."\n".
 get_lang('HyperbolicArccosineArccosh')."\n".
-get_lang('InverseHyperbolicCosineAcosh')."\n".
 "\n".
 get_lang('TangentTan')."\n".
 get_lang('HyperbolicTangentTanh')."\n".
 get_lang('ArctangentArctan')."\n".
-get_lang('InverseTangentAtan')."\n".
 get_lang('HyperbolicArctangentArctanh')."\n".
-get_lang('InverseHyperbolicTangentAtanh').
+"\n".
+get_lang('CotangentCot')."\n".
+get_lang('HyperbolicCotangentCoth')."\n".
+get_lang('ArccotangentArccot')."\n".
+get_lang('HyperbolicArccotangentArccoth')."\n".
+"\n".
+get_lang('SecantSec')."\n".
+get_lang('HyperbolicSecantSech')."\n".
+get_lang('ArcsecantArcsec')."\n".
+get_lang('HyperbolicArcsecantArcsech')."\n".
+"\n".
+get_lang('CosecantCsc')."\n".
+get_lang('HyperbolicCosecantCsch')."\n".
+get_lang('ArccosecantArccsc')."\n".
+get_lang('HyperbolicArccosecantArccsch')."\n".
+"\n".
 "</pre>";

+ 6 - 3
main/exercice/exercise.class.php

@@ -58,6 +58,7 @@ class Exercise
     public $edit_exercise_in_lp = false;
     public $is_gradebook_locked = false;
     public $exercise_was_added_in_lp = false;
+    public $lpList = array();
     public $force_edit_exercise_in_lp = false;
     public $sessionId = 0;
 
@@ -148,7 +149,8 @@ class Exercise
 
             $this->review_answers = (isset($object->review_answers) && $object->review_answers == 1) ? true : false;
 
-            $sql = "SELECT max_score FROM $table_lp_item
+            $sql = "SELECT lp_id, max_score
+                    FROM $table_lp_item
                     WHERE   c_id = {$this->course_id} AND
                             item_type = '".TOOL_QUIZ."' AND
                             path = '".$id."'";
@@ -156,6 +158,7 @@ class Exercise
 
             if (Database::num_rows($result) > 0) {
                 $this->exercise_was_added_in_lp = true;
+                $this->lpList = Database::store_result($result, 'ASSOC');
             }
 
             $this->force_edit_exercise_in_lp = isset($_configuration['force_edit_exercise_in_lp']) ? $_configuration['force_edit_exercise_in_lp'] : false;
@@ -2341,14 +2344,14 @@ class Exercise
                             $choice[$ind] = 1;
                         }
 
-                        $studentChoice = $choice[$numAnswer];
+                        $studentChoice = isset($choice[$numAnswer]) ? $choice[$numAnswer] : null;
                         $real_answers[$answerId] = (bool)$studentChoice;
 
                         if ($studentChoice) {
                             $questionScore  +=$answerWeighting;
                         }
                     } else {
-                        $studentChoice = $choice[$numAnswer];
+                        $studentChoice = isset($choice[$numAnswer]) ? $choice[$numAnswer] : null;
                         $real_answers[$answerId] = (bool)$studentChoice;
 
                         if (isset($studentChoice)) {

+ 107 - 55
main/exercice/exercise.lib.php

@@ -2211,25 +2211,33 @@ function get_exercises_to_be_taken($course_code, $session_id)
  **/
 function get_student_stats_by_question($question_id,  $exercise_id, $course_code, $session_id)
 {
-    $track_exercises	= Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
-    $track_attempt		= Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
-
-    $question_id 		= intval($question_id);
-    $exercise_id 		= intval($exercise_id);
-    $course_code 		= Database::escape_string($course_code);
-    $session_id 		= intval($session_id);
-
-    $sql = "SELECT MAX(marks) as max , MIN(marks) as min, AVG(marks) as average
-    		FROM $track_exercises e INNER JOIN $track_attempt a ON (a.exe_id = e.exe_id)
-    		WHERE 	exe_exo_id 		= $exercise_id AND
-    				course_code 	= '$course_code' AND
-    				e.session_id 	= $session_id AND
-    				question_id 	= $question_id AND status = '' LIMIT 1";
+    $track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
+    $track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
+
+    $question_id = intval($question_id);
+    $exercise_id = intval($exercise_id);
+    $course_code = Database::escape_string($course_code);
+    $session_id = intval($session_id);
+
+    $sql = "SELECT MAX(marks) as max, MIN(marks) as min, AVG(marks) as average
+    		FROM $track_exercises e
+    		INNER JOIN $track_attempt a
+    		ON (
+    		    a.exe_id = e.exe_id AND
+    		    e.exe_cours_id = a.course_code AND
+    		    e.session_id  = a.session_id
+            )
+    		WHERE
+    		    exe_exo_id 	= $exercise_id AND
+                course_code = '$course_code' AND
+                e.session_id = $session_id AND
+                question_id = $question_id AND
+                status = ''
+            LIMIT 1";
     $result = Database::query($sql);
     $return = array();
     if ($result) {
         $return = Database::fetch_array($result, 'ASSOC');
-
     }
 
     return $return;
@@ -2244,30 +2252,46 @@ function get_student_stats_by_question($question_id,  $exercise_id, $course_code
  */
 function get_number_students_question_with_answer_count($question_id, $exercise_id, $course_code, $session_id)
 {
-    $track_exercises = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
-    $track_attempt = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
-    $course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
+    $track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
+    $track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
+    $courseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
+    $courseUserSession = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
 
     $question_id = intval($question_id);
     $exercise_id = intval($exercise_id);
     $course_code = Database::escape_string($course_code);
     $session_id = intval($session_id);
 
+    if (empty($session_id)) {
+        $courseCondition =  "
+            INNER JOIN $courseUser cu
+            ON cu.course_code = a.course_code AND cu.user_id  = exe_user_id";
+        $courseConditionWhere = " AND relation_type <> 2 AND cu.status = ".STUDENT;
+    } else {
+        $courseCondition =  "
+            INNER JOIN $courseUserSession cu
+            ON cu.course_code = a.course_code AND cu.id_user = exe_user_id";
+        $courseConditionWhere = " AND cu.status = 0 ";
+    }
+
     $sql = "SELECT DISTINCT exe_user_id
     		FROM $track_exercises e
     		INNER JOIN $track_attempt a
-    		ON (a.exe_id = e.exe_id)
-    		INNER JOIN $course_user cu
-            ON cu.course_code = a.course_code AND cu.user_id  = exe_user_id
+    		ON (
+    		    a.exe_id = e.exe_id AND
+    		    e.exe_cours_id = a.course_code AND
+    		    e.session_id  = a.session_id
+            )
+    		$courseCondition
     		WHERE
-    		    exe_exo_id 		= $exercise_id AND
-                a.course_code 	= '$course_code' AND
-                e.session_id 	= $session_id AND
-                question_id 	= $question_id AND
-                answer          <> '0' AND
-                cu.status       = ".STUDENT." AND
-                relation_type  <> 2 AND
-                e.status        = ''";
+    		    exe_exo_id = $exercise_id AND
+                a.course_code = '$course_code' AND
+                e.session_id = $session_id AND
+                question_id = $question_id AND
+                answer <> '0' AND
+                e.status = ''
+                $courseConditionWhere
+            ";
     $result = Database::query($sql);
     $return = 0;
     if ($result) {
@@ -2287,32 +2311,44 @@ function get_number_students_question_with_answer_count($question_id, $exercise_
  */
 function get_number_students_answer_hotspot_count($answer_id, $question_id,  $exercise_id, $course_code, $session_id)
 {
-    $track_exercises	= Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
-    $track_hotspot		= Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
-    $course_user        = Database::get_main_table(TABLE_MAIN_COURSE_USER);
+    $track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
+    $track_hotspot = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
+    $courseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
+    $courseUserSession = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
 
-    $question_id 		= intval($question_id);
-    $answer_id          = intval($answer_id);
-    $exercise_id 		= intval($exercise_id);
-    $course_code 		= Database::escape_string($course_code);
-    $session_id 		= intval($session_id);
+    $question_id = intval($question_id);
+    $answer_id = intval($answer_id);
+    $exercise_id = intval($exercise_id);
+    $course_code = Database::escape_string($course_code);
+    $session_id = intval($session_id);
+
+    if (empty($session_id)) {
+        $courseCondition =  "
+            INNER JOIN $courseUser cu
+            ON cu.course_code = a.hotspot_course_code AND cu.user_id  = exe_user_id";
+        $courseConditionWhere = " AND relation_type <> 2 AND cu.status = ".STUDENT;
+    } else {
+        $courseCondition =  "
+            INNER JOIN $courseUserSession cu
+            ON cu.course_code = a.hotspot_course_code AND cu.id_user = exe_user_id";
+        $courseConditionWhere = " AND cu.status = 0 ";
+    }
 
     $sql = "SELECT DISTINCT exe_user_id
     		FROM $track_exercises e
     		INNER JOIN $track_hotspot a
     		ON (a.hotspot_exe_id = e.exe_id)
-    		INNER JOIN $course_user cu
-    		ON cu.course_code = a.hotspot_course_code AND cu.user_id  = exe_user_id
+    		$courseCondition
     		WHERE
     		    exe_exo_id              = $exercise_id AND
                 a.hotspot_course_code 	= '$course_code' AND
                 e.session_id            = $session_id AND
                 hotspot_answer_id       = $answer_id AND
                 hotspot_question_id     = $question_id AND
-                cu.status               = ".STUDENT." AND
                 hotspot_correct         =  1 AND
-                relation_type           <> 2 AND
-                e.status                = ''";
+                e.status                = ''
+                $courseConditionWhere
+            ";
 
     $result = Database::query($sql);
     $return = 0;
@@ -2345,7 +2381,8 @@ function get_number_students_answer_count(
 ) {
     $track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
     $track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
-    $course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
+    $courseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
+    $courseUserSession = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
 
     $question_id = intval($question_id);
     $answer_id = intval($answer_id);
@@ -2364,21 +2401,36 @@ function get_number_students_answer_count(
             $select_condition = " DISTINCT exe_user_id ";
     }
 
+    if (empty($session_id)) {
+        $courseCondition =  "
+            INNER JOIN $courseUser cu
+            ON cu.course_code = a.course_code AND cu.user_id  = exe_user_id";
+        $courseConditionWhere = " AND relation_type <> 2 AND cu.status = ".STUDENT;
+    } else {
+        $courseCondition =  "
+            INNER JOIN $courseUserSession cu
+            ON cu.course_code = a.course_code AND cu.id_user = exe_user_id";
+        $courseConditionWhere = " AND cu.status = 0 ";
+    }
+
     $sql = "SELECT $select_condition
     		FROM $track_exercises e
     		INNER JOIN $track_attempt a
-    		ON (a.exe_id = e.exe_id)
-    		INNER JOIN $course_user cu
-            ON cu.course_code = a.course_code AND cu.user_id  = exe_user_id
+    		ON (
+    		    a.exe_id = e.exe_id AND
+    		    e.exe_cours_id = a.course_code AND
+    		    e.session_id  = a.session_id
+            )
+    		$courseCondition
     		WHERE
-    		    exe_exo_id 		= $exercise_id AND
-                a.course_code 	= '$course_code' AND
-                e.session_id 	= $session_id AND
+    		    exe_exo_id = $exercise_id AND
+                a.course_code = '$course_code' AND
+                e.session_id = $session_id AND
                 $answer_condition
-                question_id 	= $question_id AND
-                cu.status        = ".STUDENT." AND
-                relation_type <> 2 AND
-                e.status = ''";
+                question_id = $question_id AND
+                e.status = ''
+                $courseConditionWhere
+            ";
     $result = Database::query($sql);
     $return = 0;
     if ($result) {
@@ -2530,8 +2582,8 @@ function check_fill_in_blanks($answer, $user_answer)
  */
 function get_number_students_finish_exercise($exercise_id, $course_code, $session_id)
 {
-    $track_exercises = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
-    $track_attempt = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
+    $track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
+    $track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
 
     $exercise_id = intval($exercise_id);
     $course_code = Database::escape_string($course_code);

+ 8 - 2
main/exercice/exercise_submit.php

@@ -48,9 +48,16 @@ if ($debug) {
 // Notice for unauthorized people.
 api_protect_course_script(true);
 
+$origin = isset($_REQUEST['origin']) ? Security::remove_XSS($_REQUEST['origin']) : '';
+
 $is_allowedToEdit = api_is_allowed_to_edit(null,true);
+$glossaryExtraTools = api_get_setting('show_glossary_in_extra_tools');
 
-if (api_get_setting('show_glossary_in_extra_tools') == 'true') {
+$showGlossary = in_array($glossaryExtraTools, array('true', 'exercise', 'exercise_and_lp'));
+if ($origin == 'learnpath') {
+    $showGlossary = in_array($glossaryExtraTools, array('true', 'lp', 'exercise_and_lp'));
+}
+if ($showGlossary) {
     $htmlHeadXtra[] = api_get_js('glossary.js');
     $htmlHeadXtra[] = api_get_js('jquery.highlight.js');
 }
@@ -68,7 +75,6 @@ $learnpath_id = isset($_REQUEST['learnpath_id']) ? intval($_REQUEST['learnpath_i
 $learnpath_item_id = isset($_REQUEST['learnpath_item_id']) ? intval($_REQUEST['learnpath_item_id']) : 0;
 $learnpath_item_view_id	= isset($_REQUEST['learnpath_item_view_id']) ? intval($_REQUEST['learnpath_item_view_id']) : 0;
 
-$origin = isset($_REQUEST['origin']) ? Security::remove_XSS($_REQUEST['origin']) : '';
 $reminder = isset($_REQUEST['reminder']) ? intval($_REQUEST['reminder']) : 0;
 $remind_question_id = isset($_REQUEST['remind_question_id']) ? intval($_REQUEST['remind_question_id']) : 0;
 $exerciseId = isset($_REQUEST['exerciseId']) ? intval($_REQUEST['exerciseId']) : 0;

+ 26 - 29
main/exercice/question_admin.inc.php

@@ -1,15 +1,13 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
-*	Statement (?) administration
-*	This script allows to manage the statements of questions.
-* 	It is included from the script admin.php
-*	@package chamilo.exercise
-* 	@author Olivier Brouckaert
-* 	@version $Id: question_admin.inc.php 22126 2009-07-15 22:38:39Z juliomontoya $
-*/
-/**
- * Code
+ *	Statement (?) administration
+ *	This script allows to manage the statements of questions.
+ * 	It is included from the script admin.php
+ *	@package chamilo.exercise
+ * 	@author Olivier Brouckaert
+ * 	@version $Id: question_admin.inc.php 22126 2009-07-15 22:38:39Z juliomontoya $
  */
 
 // INIT QUESTION
@@ -44,7 +42,6 @@ if (is_object($objQuestion)) {
 	$objQuestion->createForm($form);
 
 	// answer form elements
-
 	$objQuestion->createAnswersForm($form);
 
 	// this variable  $show_quiz_edition comes from admin.php blocks the exercise/quiz modifications
@@ -56,29 +53,29 @@ if (is_object($objQuestion)) {
 	if (isset($_POST['submitQuestion']) && $form->validate()) {
 
 		// question
-	    $objQuestion->processCreation($form, $objExercise);
+		$objQuestion->processCreation($form, $objExercise);
 
-	    // answers
-	    $nb_answers = isset($nb_answers) ? $nb_answers : 0;
-	    $objQuestion->processAnswersCreation($form, $nb_answers);
+		// answers
+		$nb_answers = isset($nb_answers) ? $nb_answers : 0;
+		$objQuestion->processAnswersCreation($form, $nb_answers);
 
-        // TODO: maybe here is the better place to index this tool, including answers text
+		// TODO: maybe here is the better place to index this tool, including answers text
 
-	    // redirect
-	    if ($objQuestion->type != HOT_SPOT && $objQuestion->type != HOT_SPOT_DELINEATION) {
-	    	if(isset($_GET['editQuestion'])) {
-	    		echo '<script type="text/javascript">window.location.href="admin.php?exerciseId='.$exerciseId.'&message=ItemUpdated"</script>';
-	    	} else {
-	    		//New question
-	    		echo '<script type="text/javascript">window.location.href="admin.php?exerciseId='.$exerciseId.'&message=ItemAdded"</script>';
-	    	}
-	    } else {
-	    	echo '<script type="text/javascript">window.location.href="admin.php?exerciseId='.$exerciseId.'&hotspotadmin='.$objQuestion->id.'"</script>';
-	    }
+		// redirect
+		if ($objQuestion->type != HOT_SPOT && $objQuestion->type != HOT_SPOT_DELINEATION) {
+			if(isset($_GET['editQuestion'])) {
+				echo '<script type="text/javascript">window.location.href="admin.php?exerciseId='.$exerciseId.'&message=ItemUpdated"</script>';
+			} else {
+				//New question
+				echo '<script type="text/javascript">window.location.href="admin.php?exerciseId='.$exerciseId.'&message=ItemAdded"</script>';
+			}
+		} else {
+			echo '<script type="text/javascript">window.location.href="admin.php?exerciseId='.$exerciseId.'&hotspotadmin='.$objQuestion->id.'"</script>';
+		}
 	} else {
-        if (isset($questionName)) {
-		    echo '<h3>'.$questionName.'</h3>';
-        }
+		if (isset($questionName)) {
+			echo '<h3>'.$questionName.'</h3>';
+		}
 		if (!empty($pictureName)) {
 			echo '<img src="../document/download.php?doc_url=%2Fimages%2F'.$pictureName.'" border="0">';
 		}

+ 13 - 14
main/exercice/question_create.php

@@ -1,12 +1,11 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
  * Exercise
  * @package chamilo.exercise
  */
-/**
- * Code
- */
+
 // name of the language file that needs to be included
 $language_file='exercice';
 
@@ -36,7 +35,7 @@ $form->addElement('header','',get_lang('AddQuestionToExercise'));
 
 $question_list = Question::get_question_type_list();
 $question_list_options = array();
-foreach ($question_list as $key=> $value) {    
+foreach ($question_list as $key=> $value) {
     $question_list_options[$key] = addslashes(get_lang($value[1]));
 }
 $form->addElement('select', 'question_type_hidden', get_lang('QuestionType'), $question_list_options, array('id' => 'question_type_hidden'));
@@ -72,26 +71,26 @@ $form->addRule('question_type_hidden', get_lang('InvalidQuestionType'), 'validqu
 if ($form->validate()) {
 	$values = $form->exportValues();
     $answer_type = $values['question_type_hidden'];
-    
+
 	// check feedback_type from current exercise for type of question delineation
-	$exercise_id = intval($values['exercice']);	
+	$exercise_id = intval($values['exercice']);
 	$sql = "SELECT feedback_type FROM $tbl_exercices WHERE c_id = $course_id AND id = '$exercise_id'";
 	$rs_feedback_type = Database::query($sql);
 	$row_feedback_type = Database::fetch_row($rs_feedback_type);
 	$feedback_type = $row_feedback_type[0];
-	
+
 	// if question type does not belong to self-evaluation (immediate feedback) it'll send an error
-	if (($answer_type == HOT_SPOT_DELINEATION && $feedback_type != 1) || 
+	if (($answer_type == HOT_SPOT_DELINEATION && $feedback_type != 1) ||
 		($feedback_type == 1 && ($answer_type != HOT_SPOT_DELINEATION && $answer_type != UNIQUE_ANSWER))) {
 		header('Location: question_create.php?'.api_get_cidreq().'&error=true');
-		exit;		
-	}	
+		exit;
+	}
 	header('Location: admin.php?exerciseId='.$values['exercice'].'&newQuestion=yes&isContent='.$values['is_content'].'&answerType='.$answer_type);
 	exit;
 } else {
 	// header
 	Display::display_header($nameTools);
-	
+
 	echo '<div class="actions">';
 	echo '<a href="exercice.php?show=test">'.Display :: return_icon('back.png', get_lang('BackToExercisesList'),'',ICON_SIZE_MEDIUM).'</a>';
 	echo '</div>';
@@ -104,13 +103,13 @@ if ($form->validate()) {
 }
 
 function check_question_type($parameter) {
-    $question_list = Question::get_question_type_list();    
+    $question_list = Question::get_question_type_list();
 	foreach ($question_list as $key => $value) {
 		$valid_question_types[] = $key;
-	}    
+	}
 	if (in_array($parameter, $valid_question_types)) {
 		return true;
 	} else {
 		return false;
 	}
-}
+}

+ 175 - 172
main/exercice/question_list_admin.inc.php

@@ -1,128 +1,127 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
-*	Code library for HotPotatoes integration.
-*	@package chamilo.exercise
-*	@author Olivier Brouckaert & Julio Montoya & Hubert Borderiou 21-10-2011 (Question by category)
+ *	Code library for HotPotatoes integration.
+ *	@package chamilo.exercise
+ *	@author Olivier Brouckaert & Julio Montoya & Hubert Borderiou 21-10-2011 (Question by category)
 
-*	QUESTION LIST ADMINISTRATION
-*
-*	This script allows to manage the question list
-*	It is included from the script admin.php
-*/
+ *	QUESTION LIST ADMINISTRATION
+ *
+ *	This script allows to manage the question list
+ *	It is included from the script admin.php
+ */
 
 // deletes a question from the exercise (not from the data base)
 if ($deleteQuestion) {
-	// if the question exists
-	if ($objQuestionTmp = Question::read($deleteQuestion)) {
-		$objQuestionTmp->delete($exerciseId);
+    // if the question exists
+    if ($objQuestionTmp = Question::read($deleteQuestion)) {
+        $objQuestionTmp->delete($exerciseId);
 
-		// if the question has been removed from the exercise
-		if ($objExercise->removeFromList($deleteQuestion)) {
-			$nbrQuestions--;
-		}
-	}
-	// destruction of the Question object
-	unset($objQuestionTmp);
+        // if the question has been removed from the exercise
+        if ($objExercise->removeFromList($deleteQuestion)) {
+            $nbrQuestions--;
+        }
+    }
+    // destruction of the Question object
+    unset($objQuestionTmp);
 }
 $ajax_url = api_get_path(WEB_AJAX_PATH)."exercise.ajax.php?".api_get_cidreq()."&exercise_id=".intval($exerciseId);
 ?>
-<style>
-    .ui-state-highlight { height: 30px; line-height: 1.2em; }
-    /*Fixes edition buttons*/
-    .ui-accordion-icons .ui-accordion-header .edition a {
-        padding-left:4px;
-    }
-</style>
+    <style>
+        .ui-state-highlight { height: 30px; line-height: 1.2em; }
+        /*Fixes edition buttons*/
+        .ui-accordion-icons .ui-accordion-header .edition a {
+            padding-left:4px;
+        }
+    </style>
 
-<div id="dialog-confirm" title="<?php echo get_lang("ConfirmYourChoice"); ?>" style="display:none;">
-    <p>
+    <div id="dialog-confirm" title="<?php echo get_lang("ConfirmYourChoice"); ?>" style="display:none;">
+        <p>
         <span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0; display:none;">
         </span>
-        <?php echo get_lang("AreYouSureToDelete"); ?>
-    </p>
-</div>
-
-<script>
-$(function() {
-    $( "#dialog:ui-dialog" ).dialog( "destroy" );
-    $( "#dialog-confirm" ).dialog({
-            autoOpen: false,
-            show: "blind",
-            resizable: false,
-            height:150,
-            modal: false
-     });
+            <?php echo get_lang("AreYouSureToDelete"); ?>
+        </p>
+    </div>
 
-    $(".opener").click(function() {
-        var targetUrl = $(this).attr("href");
-        $( "#dialog-confirm" ).dialog({
-        	modal: true,
-            buttons: {
-                "<?php echo get_lang("Yes"); ?>": function() {
-                    location.href = targetUrl;
-                    $( this ).dialog( "close" );
-
-                },
-                "<?php echo get_lang("No"); ?>": function() {
-                    $( this ).dialog( "close" );
-                }
-            }
-        });
-        $( "#dialog-confirm" ).dialog("open");
-        return false;
-    });
+    <script>
+        $(function() {
+            $( "#dialog:ui-dialog" ).dialog( "destroy" );
+            $( "#dialog-confirm" ).dialog({
+                autoOpen: false,
+                show: "blind",
+                resizable: false,
+                height:150,
+                modal: false
+            });
 
-    var stop = false;
-    $( "#question_list h3" ).click(function( event ) {
-        if ( stop ) {
-            event.stopImmediatePropagation();
-            event.preventDefault();
-            stop = false;
-        }
-    });
+            $(".opener").click(function() {
+                var targetUrl = $(this).attr("href");
+                $( "#dialog-confirm" ).dialog({
+                    modal: true,
+                    buttons: {
+                        "<?php echo get_lang("Yes"); ?>": function() {
+                            location.href = targetUrl;
+                            $( this ).dialog( "close" );
 
-    var icons = {
-            header: "ui-icon-circle-arrow-e",
-            headerSelected: "ui-icon-circle-arrow-s"
-    };
+                        },
+                        "<?php echo get_lang("No"); ?>": function() {
+                            $( this ).dialog( "close" );
+                        }
+                    }
+                });
+                $( "#dialog-confirm" ).dialog("open");
+                return false;
+            });
 
+            var stop = false;
+            $( "#question_list h3" ).click(function( event ) {
+                if ( stop ) {
+                    event.stopImmediatePropagation();
+                    event.preventDefault();
+                    stop = false;
+                }
+            });
 
-    /* We can add links in the accordion header */
-    $("div > div > div > .edition > div > a").click(function() {
-        //Avoid the redirecto when selecting the delete button
-        if (this.id.indexOf('delete') == -1) {
-            newWind = window.open(this.href,"_self");
-            newWind.focus();
-            return false;
-        }
-    });
+            var icons = {
+                header: "ui-icon-circle-arrow-e",
+                headerSelected: "ui-icon-circle-arrow-s"
+            };
 
-    $( "#question_list" ).accordion({
-        icons: icons,
-        autoHeight: false,
-        active: false, // all items closed by default
-        collapsible: true,
-        header: ".header_operations"
-    })
+            /* We can add links in the accordion header */
+            $("div > div > div > .edition > div > a").click(function() {
+                //Avoid the redirecto when selecting the delete button
+                if (this.id.indexOf('delete') == -1) {
+                    newWind = window.open(this.href,"_self");
+                    newWind.focus();
+                    return false;
+                }
+            });
 
-    .sortable({
-        cursor: "move", // works?
-        update: function(event, ui) {
-            var order = $(this).sortable("serialize") + "&a=update_question_order&exercise_id=<?php echo intval($_GET['exerciseId']);?>";
-            $.post("<?php echo $ajax_url ?>", order, function(reponse){
-                $("#message").html(reponse);
+            $( "#question_list" ).accordion({
+                icons: icons,
+                autoHeight: false,
+                active: false, // all items closed by default
+                collapsible: true,
+                header: ".header_operations"
+            })
+            .sortable({
+                cursor: "move", // works?
+                update: function(event, ui) {
+                    var order = $(this).sortable("serialize") + "&a=update_question_order&exercise_id=<?php echo intval($_GET['exerciseId']);?>";
+                    $.post("<?php echo $ajax_url ?>", order, function(reponse){
+                        $("#message").html(reponse);
+                    });
+                },
+                axis: "y",
+                placeholder: "ui-state-highlight", //defines the yellow highlight
+                handle: ".moved", //only the class "moved"
+                stop: function() {
+                    stop = true;
+                }
             });
-        },
-        axis: "y",
-        placeholder: "ui-state-highlight", //defines the yellow highlight
-        handle: ".moved", //only the class "moved"
-        stop: function() {
-            stop = true;
-        }
-    });
-});
-</script>
+        });
+    </script>
 <?php
 
 //we filter the type of questions we can add
@@ -136,7 +135,7 @@ unset($_SESSION['less_answer']);
 // If we are in a test
 $inATest = isset($exerciseId) && $exerciseId > 0;
 if (!$inATest) {
-	echo "<p class='warning-message'>".get_lang("ChoiceQuestionType")."</p>";
+    echo "<p class='warning-message'>".get_lang("ChoiceQuestionType")."</p>";
 } else {
     // Title line
     echo "<div>";
@@ -149,7 +148,7 @@ if (!$inATest) {
     echo "<div style='clear:both'>&nbsp;</div>";
 
     echo '<div id="question_list">';
-	if ($nbrQuestions) {
+    if ($nbrQuestions) {
         //Always getting list from DB
         $questionList = $objExercise->selectQuestionList(true);
 
@@ -161,65 +160,69 @@ if (!$inATest) {
         $styleScore = "width:4%; float:left; padding-top:8px; text-align:center;";
 
         if (is_array($questionList)) {
-			foreach ($questionList as $id) {
-				//To avoid warning messages
-				if (!is_numeric($id)) {
-					continue;
-				}
-				$objQuestionTmp = Question::read($id);
-				$question_class = get_class($objQuestionTmp);
+            foreach ($questionList as $id) {
+                //To avoid warning messages
+                if (!is_numeric($id)) {
+                    continue;
+                }
+                $objQuestionTmp = Question::read($id);
+                $question_class = get_class($objQuestionTmp);
 
-				$clone_link = '<a href="'.api_get_self().'?'.api_get_cidreq().'&clone_question='.$id.'">'.Display::return_icon('cd.gif',get_lang('Copy'), array(), ICON_SIZE_SMALL).'</a>';
-				/*$edit_link  = '<a href="'.api_get_self().'?'.api_get_cidreq().'&type='.$objQuestionTmp->selectType().'&myid=1&editQuestion='.$id.'">'.Display::return_icon('edit.png',get_lang('Modify'), array(), ICON_SIZE_SMALL).'</a>';
+                $clone_link = '<a href="'.api_get_self().'?'.api_get_cidreq().'&clone_question='.$id.'">'.Display::return_icon('cd.gif',get_lang('Copy'), array(), ICON_SIZE_SMALL).'</a>';
+                /*$edit_link  = '<a href="'.api_get_self().'?'.api_get_cidreq().'&type='.$objQuestionTmp->selectType().'&myid=1&editQuestion='.$id.'">'.Display::return_icon('edit.png',get_lang('Modify'), array(), ICON_SIZE_SMALL).'</a>';
 
                 if ($objQuestionTmp->type == CALCULATED_ANSWER && $objQuestionTmp->isAnswered()) {
                     $edit_link  = '<a>'.Display::return_icon('edit_na.png',get_lang('Modify'), array(), ICON_SIZE_SMALL).'</a>';
                 }*/
 
                 $edit_link = ($objQuestionTmp->type == CALCULATED_ANSWER && $objQuestionTmp->isAnswered()) ?
-                '<a>'.Display::return_icon(
-                    'edit_na.png',
-                    get_lang('QuestionEditionNotAvailableBecauseItIsAlreadyAnsweredHoweverYouCanCopyItAndModifyTheCopy'),
-                    array(),
-                    ICON_SIZE_SMALL
-                ).'</a>' :
-                '<a href="'.api_get_self().'?'.api_get_cidreq().'&type='.
-                $objQuestionTmp->selectType().'&myid=1&editQuestion='.$id.'">'.
-                Display::return_icon(
-                    'edit.png',
-                    get_lang('Modify'),
-                    array(),
-                    ICON_SIZE_SMALL
-                ).'</a>';
+                    '<a>'.Display::return_icon(
+                        'edit_na.png',
+                        get_lang('QuestionEditionNotAvailableBecauseItIsAlreadyAnsweredHoweverYouCanCopyItAndModifyTheCopy'),
+                        array(),
+                        ICON_SIZE_SMALL
+                    ).'</a>' :
+                    '<a href="'.api_get_self().'?'.api_get_cidreq().'&type='.
+                    $objQuestionTmp->selectType().'&myid=1&editQuestion='.$id.'">'.
+                    Display::return_icon(
+                        'edit.png',
+                        get_lang('Modify'),
+                        array(),
+                        ICON_SIZE_SMALL
+                    ).'</a>';
                 $delete_link = null;
-				if ($objExercise->edit_exercise_in_lp == true) {
-				     $delete_link = '<a id="delete_'.$id.'" class="opener"  href="'.api_get_self().'?'.api_get_cidreq().'&exerciseId='.$exerciseId.'&deleteQuestion='.$id.'" >'.Display::return_icon('delete.png',get_lang('RemoveFromTest'), array(), ICON_SIZE_SMALL).'</a>';
-				}
+                if ($objExercise->edit_exercise_in_lp == true) {
+                    $delete_link = '<a id="delete_'.$id.'" class="opener"  href="'.api_get_self().'?'.api_get_cidreq().'&exerciseId='.$exerciseId.'&deleteQuestion='.$id.'" >'.Display::return_icon('delete.png',get_lang('RemoveFromTest'), array(), ICON_SIZE_SMALL).'</a>';
+                }
 
-				$edit_link   = Display::tag('div', $edit_link,   array('style'=>'float:left; padding:0px; margin:0px'));
-				$clone_link  = Display::tag('div', $clone_link,  array('style'=>'float:left; padding:0px; margin:0px'));
-				$delete_link = Display::tag('div', $delete_link, array('style'=>'float:left; padding:0px; margin:0px'));
-				$actions     = Display::tag('div', $edit_link.$clone_link.$delete_link, array('class'=>'edition','style'=>'width:100px; right:10px; margin-top: 0px; position: absolute; top: 10%;'));
+                $edit_link   = Display::tag('div', $edit_link,   array('style'=>'float:left; padding:0px; margin:0px'));
+                $clone_link  = Display::tag('div', $clone_link,  array('style'=>'float:left; padding:0px; margin:0px'));
+                $delete_link = Display::tag('div', $delete_link, array('style'=>'float:left; padding:0px; margin:0px'));
+                $actions     = Display::tag('div', $edit_link.$clone_link.$delete_link, array('class'=>'edition','style'=>'width:100px; right:10px; margin-top: 0px; position: absolute; top: 10%;'));
 
                 $title = Security::remove_XSS($objQuestionTmp->selectTitle());
                 $move = Display::return_icon('all_directions.png',get_lang('Move'), array('class'=>'moved', 'style'=>'margin-bottom:-0.5em;'));
 
                 // Question name
-                $questionName = Display::tag('div', '<a href="#" title = "'.htmlentities($title).'">'.$move.' '.cut($title, 42).'</a>', array('style'=>$styleQuestion));
+                $questionName = Display::tag(
+                    'div',
+                    '<a href="#" title = "'.Security::remove_XSS($title).'">'.$move.' '.cut($title, 42).'</a>',
+                    array('style'=>$styleQuestion)
+                );
 
-				// Question type
-				list($typeImg, $typeExpl) = $objQuestionTmp->get_type_icon_html();
-				$questionType = Display::tag('div', Display::return_icon($typeImg, $typeExpl, array(), ICON_SIZE_MEDIUM), array('style'=>$styleType));
+                // Question type
+                list($typeImg, $typeExpl) = $objQuestionTmp->get_type_icon_html();
+                $questionType = Display::tag('div', Display::return_icon($typeImg, $typeExpl, array(), ICON_SIZE_MEDIUM), array('style'=>$styleType));
 
-				// Question category
-				$txtQuestionCat = Security::remove_XSS(Testcategory::getCategoryNameForQuestion($objQuestionTmp->id));
-				if (empty($txtQuestionCat)) {
-					$txtQuestionCat = "-";
-				}
-				$questionCategory = Display::tag('div', '<a href="#" style="padding:0px; margin:0px;" title="'.$txtQuestionCat.'">'.cut($txtQuestionCat, 42).'</a>', array('style'=>$styleCat));
+                // Question category
+                $txtQuestionCat = Security::remove_XSS(Testcategory::getCategoryNameForQuestion($objQuestionTmp->id));
+                if (empty($txtQuestionCat)) {
+                    $txtQuestionCat = "-";
+                }
+                $questionCategory = Display::tag('div', '<a href="#" style="padding:0px; margin:0px;" title="'.$txtQuestionCat.'">'.cut($txtQuestionCat, 42).'</a>', array('style'=>$styleCat));
 
-				// Question level
-				$txtQuestionLevel = $objQuestionTmp->level;
+                // Question level
+                $txtQuestionLevel = $objQuestionTmp->level;
                 if (empty($objQuestionTmp->level)) {
                     $txtQuestionLevel = '-';
                 }
@@ -229,32 +232,32 @@ if (!$inATest) {
                 $questionScore = Display::tag('div', $objQuestionTmp->selectWeighting(), array('style'=>$styleScore));
 
                 echo '<div id="question_id_list_'.$id.'" >';
-                    echo '<div class="header_operations">';
-                        echo $questionName;
-                        echo $questionType;
-                        echo $questionCategory;
-                        echo $questionLevel;
-                        echo $questionScore;
-                        echo $actions;
-                    echo '</div>';
-                    echo '<div class="question-list-description-block">';
-                        echo '<p>';
-                        //echo get_lang($question_class.$label);
-                        echo get_lang($question_class);
-                        echo '<br />';
-                        //echo get_lang('Level').': '.$objQuestionTmp->selectLevel();
-                        echo '<br />';
-                        showQuestion($id, false, null, null, false, true, false, true, $objExercise->feedback_type, true);
-                        echo '</p>';
-                    echo '</div>';
+                echo '<div class="header_operations">';
+                echo $questionName;
+                echo $questionType;
+                echo $questionCategory;
+                echo $questionLevel;
+                echo $questionScore;
+                echo $actions;
+                echo '</div>';
+                echo '<div class="question-list-description-block">';
+                echo '<p>';
+                //echo get_lang($question_class.$label);
+                echo get_lang($question_class);
+                echo '<br />';
+                //echo get_lang('Level').': '.$objQuestionTmp->selectLevel();
+                echo '<br />';
+                showQuestion($id, false, null, null, false, true, false, true, $objExercise->feedback_type, true);
+                echo '</p>';
+                echo '</div>';
                 echo '</div>';
                 unset($objQuestionTmp);
-			}
-		}
-	}
+            }
+        }
+    }
 
-	if (!$nbrQuestions) {
-	  	echo Display::display_warning_message(get_lang('NoQuestion'));
-	}
-	echo '</div>'; //question list div
+    if (!$nbrQuestions) {
+        echo Display::display_warning_message(get_lang('NoQuestion'));
+    }
+    echo '</div>'; //question list div
 }

+ 102 - 56
main/exercice/stats.php

@@ -9,7 +9,7 @@ require_once '../inc/global.inc.php';
 require_once 'exercise.lib.php';
 $this_section = SECTION_COURSES;
 
-$exercise_id = (isset($_GET['exerciseId']) && !empty($_GET['exerciseId'])) ? intval($_GET['exerciseId']) : 0;
+$exercise_id = isset($_GET['exerciseId']) && !empty($_GET['exerciseId']) ? intval($_GET['exerciseId']) : 0;
 $gradebook = isset($gradebook) ? $gradebook : null;
 
 $objExercise = new Exercise();
@@ -19,23 +19,22 @@ if (!$result) {
 	api_not_allowed(true);
 }
 
-$session_id = api_get_session_id();
+$sessionId = api_get_session_id();
+$courseCode = api_get_course_id();
 
-if (empty($session_id)) {
-    $students = CourseManager :: get_student_list_from_course_code(api_get_course_id(), false);
+if (empty($sessionId)) {
+    $students = CourseManager :: get_student_list_from_course_code($courseCode, false);
 } else {
-    $students = CourseManager :: get_student_list_from_course_code(api_get_course_id(), true, $session_id);
+    $students = CourseManager :: get_student_list_from_course_code($courseCode, true, $sessionId);
 }
 $count_students = count($students);
-
 $question_list = $objExercise->get_validated_question_list();
 
 $data = array();
-//Question title 	# of students who tool it 	Lowest score 	Average 	Highest score 	Maximum score
+// Question title 	# of students who tool it 	Lowest score 	Average 	Highest score 	Maximum score
 $headers = array(
 	get_lang('Question'),
     get_lang('QuestionType'),
-	//get_lang('NumberOfStudentsWhoTryTheExercise'),
     get_lang('NumberStudentWhoSelectedIt'),
 	get_lang('LowestScore'),
 	get_lang('AverageScore'),
@@ -45,28 +44,42 @@ $headers = array(
 
 if (!empty($question_list)) {
 	foreach ($question_list as $question_id) {
-		$question_obj   = Question::read($question_id);
-		$exercise_stats = get_student_stats_by_question($question_id, $exercise_id, api_get_course_id(), api_get_session_id());
-        $count_users    = get_number_students_question_with_answer_count($question_id, $exercise_id, api_get_course_id(), api_get_session_id());
-
-		$data[$question_id]['name'] 						= cut($question_obj->question, 100);
-        $data[$question_id]['type'] 						= $question_obj->get_question_type_name();
-		//$data[$question_id]['students_who_try_exercise'] 	= $exercise_stats['users'];
+        $question_obj = Question::read($question_id);
+
+        $exercise_stats = get_student_stats_by_question(
+            $question_id,
+            $exercise_id,
+            $courseCode,
+            $sessionId
+        );
+
+        $count_users = get_number_students_question_with_answer_count(
+            $question_id,
+            $exercise_id,
+            $courseCode,
+            $sessionId
+        );
+
+        $data[$question_id]['name'] = cut($question_obj->question, 100);
+        $data[$question_id]['type'] = $question_obj->get_question_type_name();
         $percentange = 0;
         if ($count_students) {
-            $percentange = $count_users/$count_students*100;
+            $percentange = $count_users / $count_students*100;
         }
 
-        $data[$question_id]['students_who_try_exercise'] 	= Display::bar_progress($percentange, false, $count_users .' / '.$count_students);
-
-		$data[$question_id]['lowest_score'] 				= round($exercise_stats['min'], 2);
-		$data[$question_id]['average_score'] 				= round($exercise_stats['average'], 2);
-		$data[$question_id]['highest_score'] 				= round($exercise_stats['max'], 2);
-		$data[$question_id]['max_score'] 					= round($question_obj->weighting, 2);
+        $data[$question_id]['students_who_try_exercise'] = Display::bar_progress(
+            $percentange,
+            false,
+            $count_users .' / '.$count_students
+        );
+        $data[$question_id]['lowest_score'] = round($exercise_stats['min'], 2);
+        $data[$question_id]['average_score'] = round($exercise_stats['average'], 2);
+        $data[$question_id]['highest_score'] = round($exercise_stats['max'], 2);
+        $data[$question_id]['max_score'] = round($question_obj->weighting, 2);
 	}
 }
 
-//Format A table
+// Format A table
 $table = new HTML_Table(array('class' => 'data_table'));
 $row = 0;
 $column = 0;
@@ -87,7 +100,7 @@ foreach ($data as $row_table) {
 }
 $content = $table->toHtml();
 
-//Format B
+// Format B
 
 $headers = array(
 	get_lang('Question'),
@@ -102,19 +115,23 @@ if (!empty($question_list)) {
     $id = 0;
 	foreach ($question_list as $question_id) {
 		$question_obj = Question::read($question_id);
-		$exercise_stats = get_student_stats_by_question($question_id, $exercise_id, api_get_course_id(), api_get_session_id());
+        $exercise_stats = get_student_stats_by_question(
+            $question_id,
+            $exercise_id,
+            $courseCode,
+            $sessionId
+        );
 
         $answer = new Answer($question_id);
 		$answer_count = $answer->selectNbrAnswers();
 
         for ($answer_id = 1; $answer_id <= $answer_count; $answer_id++) {
-            $answer_info    = $answer->selectAnswer($answer_id);
-            $is_correct     = $answer->isCorrect($answer_id);
+            $answer_info = $answer->selectAnswer($answer_id);
+            $is_correct = $answer->isCorrect($answer_id);
             $correct_answer = $is_correct == 1 ? get_lang('Yes') : get_lang('No');
             $real_answer_id = $answer->selectAutoId($answer_id);
 
-            //$data[$id]['name'] .=$answer_count;
-            //Overwriting values depending of the question
+            // Overwriting values depending of the question
             switch ($question_obj->type) {
                 case FILL_IN_BLANKS :
                     $answer_info_db = $answer_info;
@@ -124,9 +141,9 @@ if (!empty($question_list)) {
                     $counter = 0;
                     foreach ($answers as $answer_item) {
                         if ($counter == 0) {
-                            $data[$id]['name']      = cut($question_obj->question, 100);
+                            $data[$id]['name'] = cut($question_obj->question, 100);
                         } else {
-                            $data[$id]['name']      = '-';
+                            $data[$id]['name'] = '-';
                         }
                         $data[$id]['answer'] 	= $answer_item;
 
@@ -135,13 +152,22 @@ if (!empty($question_list)) {
 
                         $data[$id]['correct'] 	= '-';
 
-                        $count = get_number_students_answer_count($real_answer_id, $question_id, $exercise_id, api_get_course_id(), api_get_session_id(), FILL_IN_BLANKS, $answer_info_db, $answer_item);
+                        $count = get_number_students_answer_count(
+                            $real_answer_id,
+                            $question_id,
+                            $exercise_id,
+                            $courseCode,
+                            $sessionId,
+                            FILL_IN_BLANKS,
+                            $answer_info_db,
+                            $answer_item
+                        );
 
                         $percentange = 0;
                         if (!empty($count_students)) {
                             $percentange = $count/$count_students*100;
                         }
-                        $data[$id]['attempts'] 	= Display::bar_progress($percentange, false, $count .' / '.$count_students);
+                        $data[$id]['attempts'] = Display::bar_progress($percentange, false, $count .' / '.$count_students);
 
                         $id++;
                         $counter++;
@@ -150,9 +176,9 @@ if (!empty($question_list)) {
                 case MATCHING:
                     if ($is_correct == 0) {
                         if ($answer_id == 1) {
-                            $data[$id]['name']      = cut($question_obj->question, 100);
+                            $data[$id]['name'] = cut($question_obj->question, 100);
                         } else {
-                            $data[$id]['name']      = '-';
+                            $data[$id]['name'] = '-';
                         }
                         $correct = '';
 
@@ -163,48 +189,67 @@ if (!empty($question_list)) {
                                  break;
                              }
                         }
-                        $data[$id]['answer'] 	= $correct;
-                        $data[$id]['correct'] 	= $answer_info;
-
-                        $count = get_number_students_answer_count($answer_id, $question_id, $exercise_id, api_get_course_id(), api_get_session_id(), MATCHING);
+                        $data[$id]['answer'] = $correct;
+                        $data[$id]['correct'] = $answer_info;
+
+                        $count = get_number_students_answer_count(
+                            $answer_id,
+                            $question_id,
+                            $exercise_id,
+                            $courseCode,
+                            $sessionId,
+                            MATCHING
+                        );
                         $percentange = 0;
                         if (!empty($count_students)) {
                             $percentange = $count/$count_students*100;
                         }
-                        $data[$id]['attempts'] 	= Display::bar_progress($percentange, false, $count .' / '.$count_students);
+                        $data[$id]['attempts'] = Display::bar_progress($percentange, false, $count .' / '.$count_students);
                     }
                     break;
                 case HOT_SPOT:
                     if ($answer_id == 1) {
-                        $data[$id]['name']      = cut($question_obj->question, 100);
+                        $data[$id]['name'] = cut($question_obj->question, 100);
                     } else {
-                        $data[$id]['name']      = '-';
+                        $data[$id]['name'] = '-';
                     }
-                    $data[$id]['answer'] 	= $answer_info;
-                    $data[$id]['correct'] 	= '-';
-
-                    $count = get_number_students_answer_hotspot_count($answer_id, $question_id, $exercise_id, api_get_course_id(), api_get_session_id());
+                    $data[$id]['answer'] = $answer_info;
+                    $data[$id]['correct'] = '-';
+
+                    $count = get_number_students_answer_hotspot_count(
+                        $answer_id,
+                        $question_id,
+                        $exercise_id,
+                        $courseCode,
+                        $sessionId
+                    );
                     $percentange = 0;
                     if (!empty($count_students)) {
                         $percentange = $count/$count_students*100;
                     }
-                    $data[$id]['attempts'] 	= Display::bar_progress($percentange, false, $count .' / '.$count_students);
+                    $data[$id]['attempts'] = Display::bar_progress($percentange, false, $count .' / '.$count_students);
                     break;
                 default:
                     if ($answer_id == 1) {
-                        $data[$id]['name']      = cut($question_obj->question, 100);
+                        $data[$id]['name'] = cut($question_obj->question, 100);
                     } else {
-                        $data[$id]['name']      = '-';
+                        $data[$id]['name'] = '-';
                     }
-                    $data[$id]['answer'] 	= $answer_info;
-                    $data[$id]['correct'] 	= $correct_answer;
-
-                    $count = get_number_students_answer_count($real_answer_id, $question_id, $exercise_id, api_get_course_id(), api_get_session_id());
+                    $data[$id]['answer'] = $answer_info;
+                    $data[$id]['correct'] = $correct_answer;
+
+                    $count = get_number_students_answer_count(
+                        $real_answer_id,
+                        $question_id,
+                        $exercise_id,
+                        $courseCode,
+                        $sessionId
+                    );
                     $percentange = 0;
                     if (!empty($count_students)) {
                         $percentange = $count/$count_students*100;
                     }
-                    $data[$id]['attempts'] 	= Display::bar_progress($percentange, false, $count .' / '.$count_students);
+                    $data[$id]['attempts'] = Display::bar_progress($percentange, false, $count .' / '.$count_students);
             }
             $id++;
         }
@@ -212,7 +257,7 @@ if (!empty($question_list)) {
 	}
 }
 
-//Format A table
+// Format A table
 $table = new HTML_Table(array('class' => 'data_table'));
 $row = 0;
 $column = 0;
@@ -243,7 +288,8 @@ $tpl = new Template(get_lang('ReportByQuestion'));
 //$actions[]= array(get_lang('Back'), Display::return_icon('back.png', get_lang('Back'), 'exercise_report.php?'.$exercise_id));
 //$tpl->set_actions($actions);
 
-$actions = '<a href="exercise_report.php?exerciseId='.intval($_GET['exerciseId']).'">' . Display :: return_icon('back.png', get_lang('GoBackToQuestionList'),'',ICON_SIZE_MEDIUM).'</a>';
+$actions = '<a href="exercise_report.php?exerciseId='.intval($_GET['exerciseId']).'">' .
+    Display :: return_icon('back.png', get_lang('GoBackToQuestionList'),'',ICON_SIZE_MEDIUM).'</a>';
 $actions = Display::div($actions, array('class'=> 'actions'));
 $content = $actions.$content;
 $tpl->assign('content', $content);

+ 6 - 9
main/exercice/testheaderpage.php

@@ -1,13 +1,12 @@
-<?php //$id: $
+<?php
 /* For licensing terms, see /license.txt */
+
 /**
 *	Code library for HotPotatoes integration.
 *	@package chamilo.exercise
 * 	@author Istvan Mandak
 */
-/**
- * Code
- */
+
 // name of the language file that needs to be included
 $language_file='exercice';
 
@@ -16,9 +15,7 @@ require '../inc/global.inc.php';
 require_once(api_get_path(SYS_CODE_PATH).'exercice/hotpotatoes.lib.php');
 $documentPath= api_get_path(SYS_COURSE_PATH).$_course['path']."/document";
 $my_file = Security::remove_XSS($_GET['file']);
-
 $my_file=str_replace(array('../','\\..','\\0','..\\'),array('','','',''),urldecode($my_file));
-
 $title = GetQuizName($my_file,$documentPath);
 if ($title =='') {
 	$title = basename($my_file);
@@ -31,9 +28,9 @@ if (isset($_SESSION['gradebook'])){
 
 if (!empty($gradebook) && $gradebook=='view') {
 	$interbreadcrumb[]= array (
-			'url' => '../gradebook/'.$_SESSION['gradebook_dest'],
-			'name' => get_lang('ToolGradebook')
-		);
+		'url' => '../gradebook/'.$_SESSION['gradebook_dest'],
+		'name' => get_lang('ToolGradebook')
+	);
 }
 $interbreadcrumb[]= array ("url"=>"./exercice.php", "name"=> get_lang('Exercices'));
 Display::display_header($nameTools,"Exercise");

+ 0 - 1
main/exercice/unique_answer.class.php

@@ -12,7 +12,6 @@
  * @author Julio Montoya
  * @package chamilo.exercise
  **/
-
 class UniqueAnswer extends Question
 {
     static $typePicture = 'mcua.png';

+ 4 - 3
main/exercice/upload_exercise.php

@@ -1,5 +1,6 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
  * 	Upload quiz: This script shows the upload quiz feature
  *  Initial work by Isaac flores on Nov 4 of 2010
@@ -327,15 +328,15 @@ function lp_upload_quiz_action_handling() {
                     $globalScore = null;
                     $objAnswer = new Answer($question_id, $courseId);
                     $globalScore = $score_list[$i][3];
-                    
-                    // Calculate the number of correct answers to divide the 
+
+                    // Calculate the number of correct answers to divide the
                     // score between them when importing from CSV
                     $numberRightAnswers = 0;
                     foreach ($answers_data as $answer_data) {
                         if (strtolower($answer_data[3]) == 'x') {
                             $numberRightAnswers++;
                         }
-                    }                    
+                    }
                     foreach ($answers_data as $answer_data) {
                         $answerValue = $answer_data[2];
                         $correct = 0;

+ 27 - 3
main/gradebook/exercise_jump.php

@@ -15,7 +15,7 @@ api_block_anonymous_users();
 $this_section=SECTION_COURSES;
 
 $course_code = api_get_course_id();
-$course_info = Database::get_course_info($course_code);
+$course_info = api_get_course_info($course_code);
 $course_title = $course_info['title'];
 $course_code = $return_result['code'];
 $gradebook = Security::remove_XSS($_GET['gradebook']);
@@ -39,9 +39,33 @@ if (isset($_GET['doexercise'])) {
     header('Location: '.$doExerciseUrl);
     exit;
 } else {
+    $url = api_get_path(WEB_CODE_PATH).'exercice/overview.php?session_id='.$session_id.'&cidReq='.Security::remove_XSS($cidReq);
     if (isset($_GET['gradebook'])) {
-        $add_url = '&gradebook=view&exerciseId='.intval($_GET['exerciseId']);
+        $url .= '&gradebook=view&exerciseId='.intval($_GET['exerciseId']);
+
+        // Check if exercise is inserted inside a LP, if that's the case
+        $exerciseId = $_GET['exerciseId'];
+        $exercise = new Exercise();
+        $exercise->read($exerciseId);
+        if (!empty($exercise->id)) {
+            if ($exercise->exercise_was_added_in_lp) {
+                if (!empty($exercise->lpList)) {
+                    $count = count($exercise->lpList);
+                    if ($count == 1) {
+                        // If the exercise was added once redirect to the LP
+                        $firstLp = current($exercise->lpList);
+                        if (isset($firstLp['lp_id'])) {
+                            $url = api_get_path(WEB_CODE_PATH) . 'newscorm/lp_controller.php?' . api_get_cidreq() . '&lp_id=' . $firstLp['lp_id'] . '&action=view&isStudentView=true';
+                        }
+                    } else {
+                        // If the exercise was added multiple times show the LP list
+                        $url = api_get_path(WEB_CODE_PATH) . 'newscorm/lp_controller.php?' . api_get_cidreq().'&action=list';
+                    }
+                }
+            }
+        }
     }
-    header('Location: '.api_get_path(WEB_CODE_PATH).'exercice/overview.php?session_id='.$session_id.'&cidReq='.Security::remove_XSS($cidReq).'&'.$add_url);
+
+    header('Location: '.$url);
     exit;
 }

+ 1 - 0
main/gradebook/gradebook_add_link.php

@@ -160,6 +160,7 @@ $(document).ready( function() {
 
 Display::display_header(get_lang('MakeLink'));
 if (isset($typeform)) {
+    echo Display::return_message(get_lang('LearningPathGradebookWarning'), 'warning');
     $typeform->display();
 }
 if (isset($addform)) {

+ 9 - 1
main/gradebook/gradebook_display_certificate.php

@@ -13,6 +13,9 @@ $current_course_tool  = TOOL_GRADEBOOK;
 
 api_protect_course_script();
 
+set_time_limit(0);
+ini_set('max_execution_time', 0);
+
 require_once 'lib/gradebook_functions.inc.php';
 require_once 'lib/be.inc.php';
 require_once 'lib/gradebook_data_generator.class.php';
@@ -104,7 +107,12 @@ if (!empty($cats)) {
 
     $total_resource_weight = 0;
     if (!empty($datagen)) {
-        $data_array = $datagen->get_data(GradebookDataGenerator :: GDG_SORT_NAME,0,null,true);
+        $data_array = $datagen->get_data(
+            GradebookDataGenerator :: GDG_SORT_NAME,
+            0,
+            null,
+            true
+        );
 
         if (!empty($data_array)) {
             $newarray = array();

+ 0 - 2
main/gradebook/gradebook_flatview.php

@@ -99,7 +99,6 @@ if ($simple_search_form->validate() && (empty($keyword))) {
 
 if (!empty($keyword)) {
     $users = find_students($keyword);
-
 } else {
     if (isset($alleval) && isset($alllinks)) {
         $users = get_all_users($alleval, $alllinks);
@@ -107,7 +106,6 @@ if (!empty($keyword)) {
         $users = null;
     }
 }
-
 $offset = isset($_GET['offset']) ? $_GET['offset'] : '0';
 
 // Main course category

+ 5 - 1
main/gradebook/index.php

@@ -1,5 +1,6 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
  * Gradebook controller
  * @package chamilo.gradebook
@@ -126,7 +127,9 @@ if (isset($_GET['isStudentView'])) {
     }
 }
 
-if ((isset($_GET['selectcat']) && $_GET['selectcat']>0) && (isset($_SESSION['studentview']) && $_SESSION['studentview']=='studentview')) {
+if ((isset($_GET['selectcat']) && $_GET['selectcat']>0) &&
+    (isset($_SESSION['studentview']) && $_SESSION['studentview']=='studentview')
+) {
     Display :: display_header();
     //Introduction tool: student view
     Display::display_introduction_section(TOOL_GRADEBOOK, array('ToolbarSet' => 'AssessmentsIntroduction'));
@@ -735,6 +738,7 @@ $no_qualification = false;
 
 // Show certificate link.
 $certificate = array();
+
 if ($category != '0') {
     $cat = new Category();
     $category_id   = intval($_GET['selectcat']);

+ 1 - 0
main/gradebook/lib/be/abstractlink.class.php

@@ -228,6 +228,7 @@ abstract class AbstractLink implements GradebookItem
 
         $result = Database::query($sql);
         $links = AbstractLink::create_objects_from_sql_result($result);
+
         return $links;
     }
 

+ 2 - 1
main/gradebook/lib/be/attendancelink.class.php

@@ -196,7 +196,8 @@ class AttendanceLink extends AbstractLink
 		return false;
 	}
 
-	public function get_name() {
+	public function get_name()
+	{
 		$this->get_attendance_data();
 		$attendance_title = isset($this->attendance_data['name']) ? $this->attendance_data['name'] : '';
 		$attendance_qualify_title = isset($this->attendance_data['attendance_qualify_title']) ? $this->attendance_data['attendance_qualify_title'] : '';

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

@@ -292,7 +292,6 @@ class Category implements GradebookItem
                 // otherwise a special parameter is given to ask explicitely
                 $sql .= " AND (session_id IS NULL OR session_id = 0) ";
             } else {*/
-
             if (empty($session_id)) {
                 $sql .= ' AND (session_id IS NULL OR session_id = 0) ';
             } else {
@@ -326,14 +325,15 @@ class Category implements GradebookItem
                 $sql .= ' '.$order_by;
             }
         }
+
         $result = Database::query($sql);
-        $allcat = array();
 
+        $categories = array();
         if (Database::num_rows($result) > 0) {
-            $allcat = Category::create_category_objects_from_sql_result($result);
+            $categories = Category::create_category_objects_from_sql_result($result);
         }
 
-        return $allcat;
+        return $categories;
     }
 
     /**
@@ -697,14 +697,20 @@ class Category implements GradebookItem
 
     /**
      * Checks if the certificate is available for the given user in this category
-     * @param    integer    User ID
-     * @return    boolean    True if conditions match, false if fails
+     * @param   integer    $user_id User ID
+     * @return  boolean    True if conditions match, false if fails
      */
     public function is_certificate_available($user_id)
     {
         $score = $this->calc_score($user_id, $this->course_code);
-        if (isset($score)) {
-            $certification_score = ($score[0]/$score[1])*100; //get a percentage score to compare to minimum certificate score
+
+        if (isset($score) && isset($score[0])) {
+            // Get a percentage score to compare to minimum certificate score
+            //$certification_score = $score[0] / $score[1] * 100;
+
+            // Get real score not a percentage.
+            $certification_score = $score[0];
+
             if ($certification_score >= $this->certificate_min_score) {
                 return true;
             }
@@ -731,7 +737,7 @@ class Category implements GradebookItem
      */
     public function calc_score($stud_id = null, $course_code = '', $session_id = null)
     {
-        // get appropriate subcategories, evaluations and links
+        // Get appropriate subcategories, evaluations and links
         if (!empty($course_code)) {
             $cats  = $this->get_subcategories($stud_id, $course_code, $session_id);
             $evals = $this->get_evaluations($stud_id, false, $course_code);
@@ -782,18 +788,17 @@ class Category implements GradebookItem
         }
 
         if (!empty($links)) {
-            /** @var EvalLink $link */
+            /** @var EvalLink|ExerciseLink $link */
             foreach ($links as $link) {
                 $linkres = $link->calc_score($stud_id);
-
-                if (isset($linkres) && $link->get_weight() != 0) {
-                    $linkweight     = $link->get_weight();
-                    $link_res_denom = ($linkres[1] == 0) ? 1 : $linkres[1];
+                if (!empty($linkres) && $link->get_weight() != 0) {
+                    $linkweight = $link->get_weight();
+                    $link_res_denom = $linkres[1] == 0 ? 1 : $linkres[1];
                     $rescount++;
                     $weightsum += $linkweight;
-                    $ressum += (($linkres[0] / $link_res_denom) * $linkweight);
+                    $ressum += ($linkres[0] / $link_res_denom) * $linkweight;
                 } else {
-                    // Ddding if result does not exists
+                    // Adding if result does not exists
                     if ($link->get_weight() != 0) {
                         $linkweight = $link->get_weight();
                         $weightsum += $linkweight;
@@ -1296,14 +1301,23 @@ class Category implements GradebookItem
 
         // 1 student
         if (isset($stud_id)) {
-            // special case: this is the root
+            // Special case: this is the root
             if ($this->id == 0) {
                 return Category::get_root_categories_for_student($stud_id, $course_code, $session_id);
             } else {
-                return Category::load(null,null, $course_code, $this->id, api_is_allowed_to_edit() ? null : 1, $session_id, $order);
+                return Category::load(
+                    null,
+                    null,
+                    $course_code,
+                    $this->id,
+                    api_is_allowed_to_edit() ? null : 1,
+                    $session_id,
+                    $order
+                );
             }
-        } else {// all students
-            // course admin
+        } else {
+            // All students
+            // Course admin
             if (api_is_allowed_to_edit() && !api_is_platform_admin()) {
                 // root
                 if ($this->id == 0) {
@@ -1439,8 +1453,14 @@ class Category implements GradebookItem
                 $sessionId
             );
             if (!empty($subcats)) {
+                /** @var Category $subcat */
                 foreach ($subcats as $subcat) {
-                    $sublinks = $subcat->get_links($stud_id, false, $course_code, $sessionId);
+                    $sublinks = $subcat->get_links(
+                        $stud_id,
+                        false,
+                        $course_code,
+                        $sessionId
+                    );
                     $links = array_merge($links, $sublinks);
                 }
             }
@@ -1567,10 +1587,19 @@ class Category implements GradebookItem
     public static function register_user_certificate($category_id, $user_id)
     {
         // Generating the total score for a course
-        $cats_course = Category::load($category_id, null, null, null, null, api_get_session_id(), false);
-
-        $alleval_course  = $cats_course[0]->get_evaluations($user_id, true);
-        $alllink_course  = $cats_course[0]->get_links($user_id, true);
+        $cats_course = Category::load(
+            $category_id,
+            null,
+            null,
+            null,
+            null,
+            api_get_session_id(),
+            false
+        );
+        /** @var Category $category */
+        $category = $cats_course[0];
+        $alleval_course = $category->get_evaluations($user_id, true);
+        $alllink_course = $category->get_links($user_id, true);
         $evals_links = array_merge($alleval_course, $alllink_course);
 
         //@todo move these in a function
@@ -1589,13 +1618,15 @@ class Category implements GradebookItem
         $main_weight = $cats_course[0]->get_weight();
 
         $item_total_value = 0;
-        $item_value = 0;
-
         for ($count=0; $count < count($evals_links); $count++) {
+            /** @var AbstractLink $item */
             $item = $evals_links[$count];
             $score = $item->calc_score($user_id);
-            $divide = ( ($score[1])==0 ) ? 1 : $score[1];
-            $item_value = $score[0]/$divide*$item->get_weight();
+            $item_value = 0;
+            if (!empty($score)) {
+                $divide = $score[1] == 0 ? 1 : $score[1];
+                $item_value = $score[0] / $divide * $item->get_weight();
+            }
             $item_total_value += $item_value;
         }
 
@@ -1618,6 +1649,7 @@ class Category implements GradebookItem
             $item_total_value >= $certificate_min_score
         ) {
             $my_certificate = get_certificate_by_user_id($cats_course[0]->get_id(), $user_id);
+
             if (empty($my_certificate)) {
                 register_user_info_about_certificate(
                     $category_id,
@@ -1631,6 +1663,7 @@ class Category implements GradebookItem
             if (!empty($my_certificate)) {
                 $certificate_obj = new Certificate($my_certificate['id']);
                 $fileWasGenerated = $certificate_obj->html_file_is_generated();
+
                 if (!empty($fileWasGenerated)) {
                     $url = api_get_path(WEB_PATH) . 'certificates/index.php?id=' . $my_certificate['id'];
                     $certificates = Display::url(

+ 15 - 5
main/gradebook/lib/be/evallink.class.php

@@ -19,18 +19,26 @@ abstract class EvalLink extends AbstractLink
         parent::__construct();
     }
 
-    // Functions implementing AbstractLink
-
+    /**
+     * @return bool
+     */
     public function has_results()
     {
         $eval = $this->get_evaluation();
+
         return $eval->has_results();
     }
 
-    public function calc_score($stud_id = null)
+    /**
+     * @param int $userId
+     *
+     * @return array
+     */
+    public function calc_score($userId = null)
     {
         $eval = $this->get_evaluation();
-        return $eval->calc_score($stud_id);
+
+        return $eval->calc_score($userId);
     }
 
     public function get_link()
@@ -157,7 +165,8 @@ abstract class EvalLink extends AbstractLink
     /**
      * Lazy load function to get the linked evaluation
      */
-    protected function get_evaluation () {
+    protected function get_evaluation ()
+    {
         if (!isset($this->evaluation)) {
             if (isset($this->ref_id)) {
                 $evalarray = Evaluation::load($this->get_ref_id());
@@ -175,6 +184,7 @@ abstract class EvalLink extends AbstractLink
                 $this->set_ref_id($eval->get_id());
             }
         }
+
         return $this->evaluation;
     }
 }

+ 48 - 18
main/gradebook/lib/be/exerciselink.class.php

@@ -40,19 +40,21 @@ class ExerciseLink extends AbstractLink
         }
         $tbl_grade_links = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
 
-        $sql = 'SELECT id, title from '.$this->get_exercise_table().' exe
+        $sql = 'SELECT id, title FROM '.$this->get_exercise_table().' exe
                 WHERE id NOT IN (
-                        SELECT ref_id FROM '.$tbl_grade_links.'
-                              WHERE type        = '.LINK_EXERCISE." AND
-                                    course_code = '".$this->get_course_code()."'
-                        ) AND
-                exe.c_id        = ".$this->course_id;
+                    SELECT ref_id FROM '.$tbl_grade_links.'
+                    WHERE
+                        type = '.LINK_EXERCISE." AND
+                        course_code = '".$this->get_course_code()."'
+                ) AND
+                exe.c_id = ".$this->course_id;
 
         $result = Database::query($sql);
         $cats = array();
         while ($data=Database::fetch_array($result)) {
             $cats[] = array ($data['id'], $data['title']);
         }
+
         return $cats;
     }
 
@@ -64,6 +66,9 @@ class ExerciseLink extends AbstractLink
     {
         $TBL_DOCUMENT = Database :: get_course_table(TABLE_DOCUMENT);
         $TBL_ITEM_PROPERTY = Database :: get_course_table(TABLE_ITEM_PROPERTY);
+        $exerciseTable = $this->get_exercise_table();
+        $lpItemTable = Database :: get_course_table(TABLE_LP_ITEM);
+
         $documentPath = api_get_path(SYS_COURSE_PATH).$this->course_code."/document";
         if (empty($this->course_code)) {
             die('Error in get_not_created_links() : course code not set');
@@ -78,9 +83,14 @@ class ExerciseLink extends AbstractLink
         // @todo
         $uploadPath = null;
 
-        $sql = 'SELECT id,title from '.$this->get_exercise_table().'
+        $sql = 'SELECT id,title FROM '.$exerciseTable.'
 				WHERE c_id = '.$this->course_id.' AND active=1  '.$session_condition;
 
+        $sqlLp = "SELECT e.id, e.title FROM $exerciseTable e INNER JOIN $lpItemTable i
+                  ON (e.c_id = i.c_id AND e.id = i.path)
+				  WHERE e.c_id = $this->course_id AND active = 0 AND item_type = 'quiz'
+				  $session_condition";
+
         $sql2 = "SELECT d.path as path, d.comment as comment, ip.visibility as visibility, d.id
                 FROM $TBL_DOCUMENT d, $TBL_ITEM_PROPERTY ip
                 WHERE
@@ -92,12 +102,17 @@ class ExerciseLink extends AbstractLink
                     d.path  LIKE '".Database :: escape_string($uploadPath.'/%/%')."' AND
                     ip.visibility='1'
                 ";
+
         require_once api_get_path(SYS_CODE_PATH).'exercice/hotpotatoes.lib.php';
+        $exerciseInLP = array();
         if (!$this->is_hp) {
             $result = Database::query($sql);
+            $resultLp = Database::query($sqlLp);
+            $exerciseInLP = Database::store_result($resultLp);
         } else {
             $result2 = Database::query($sql2);
         }
+
         $cats = array();
         if (isset($result)) {
             if (Database::num_rows($result) > 0) {
@@ -106,6 +121,7 @@ class ExerciseLink extends AbstractLink
                 }
             }
         }
+
         if (isset($result2)) {
             if (Database::num_rows($result2) > 0) {
                 while ($row=Database::fetch_array($result2)) {
@@ -123,13 +139,22 @@ class ExerciseLink extends AbstractLink
                             if ($title == '') {
                                 $title = basename($path);
                             }
-                            $cats[] = array ($attribute['id'], $title.'(HP)');
+                            $cats[] = array($attribute['id'], $title.'(HP)');
                         }
                     }
                 }
             }
         }
 
+        if (!empty($exerciseInLP)) {
+            foreach ($exerciseInLP as $exercise) {
+                $cats[] = array(
+                    $exercise['id'],
+                    $exercise['title'].' ('.get_lang('ToolLearnpath').')'
+                );
+            }
+        }
+
         return $cats;
     }
 
@@ -152,7 +177,8 @@ class ExerciseLink extends AbstractLink
 
     /**
      * Get the score of this exercise. Only the first attempts are taken into account.
-     * @param int $stud_id student id (default: all students who have results - then the average is returned)
+     * @param int $stud_id student id (default: all students who have results -
+     * then the average is returned)
      * @return	array (score, max) if student is given
      * 			array (sum of scores, number of scores) otherwise
      * 			or null if no scores available
@@ -221,7 +247,7 @@ class ExerciseLink extends AbstractLink
             if ($student_count == 0) {
                 return null;
             } else {
-                return array ($sum , $student_count);
+                return array($sum, $student_count);
             }
         }
     }
@@ -260,9 +286,11 @@ class ExerciseLink extends AbstractLink
                 if ($title == '') {
                     $title = basename($data['path']);
                 }
+
                 return $title;
             }
         }
+
         return $data['title'];
     }
 
@@ -284,7 +312,7 @@ class ExerciseLink extends AbstractLink
         $sql = 'SELECT count(id) from '.$this->get_exercise_table().'
                 WHERE c_id = '.$this->course_id.' AND id = '.(int)$this->get_ref_id().' ';
         $result = Database::query($sql);
-        $number=Database::fetch_row($result);
+        $number = Database::fetch_row($result);
         return ($number[0] != 0);
     }
 
@@ -334,20 +362,22 @@ class ExerciseLink extends AbstractLink
     private function get_exercise_data()
     {
         $TBL_ITEM_PROPERTY = Database :: get_course_table(TABLE_ITEM_PROPERTY);
-
         if ($this->is_hp == 1) {
             $tbl_exercise = Database :: get_course_table(TABLE_DOCUMENT);
         } else {
             $tbl_exercise = $this->get_exercise_table();
         }
-        if ($tbl_exercise=='') {
+
+        $ref_id = intval($this->get_ref_id());
+
+        if ($tbl_exercise == '') {
             return false;
         } elseif (!isset($this->exercise_data)) {
             if ($this->is_hp == 1) {
-                $ref_id = intval($this->get_ref_id());
-                $sql = "SELECT * FROM $tbl_exercise ex, $TBL_ITEM_PROPERTY ip
+                $sql = "SELECT * FROM $tbl_exercise ex
+                        INNER JOIN $TBL_ITEM_PROPERTY ip
+                        ON (ip.ref = ex.id AND ip.c_id = ex.c_id)
                         WHERE
-                            ip.ref = ex.id AND
                             ip.c_id = $this->course_id AND
                             ex.c_id = $this->course_id AND
                             ip.ref = $ref_id AND
@@ -359,10 +389,10 @@ class ExerciseLink extends AbstractLink
                 $sql = 'SELECT * FROM '.$tbl_exercise.'
                         WHERE
                             c_id = '.$this->course_id.' AND
-                            id = '.(int)$this->get_ref_id().' ';
+                            id = '.$ref_id.' ';
             }
             $result = Database::query($sql);
-            $this->exercise_data=Database::fetch_array($result);
+            $this->exercise_data = Database::fetch_array($result);
         }
 
         return $this->exercise_data;

+ 1 - 1
main/gradebook/lib/be/learnpathlink.class.php

@@ -236,7 +236,7 @@ class LearnpathLink extends AbstractLink
 			$sql = 'SELECT * FROM '.$this->get_learnpath_table().'
                     WHERE c_id = '.$this->course_id.' AND id = '.$this->get_ref_id().' ';
 			$result = Database::query($sql);
-			$this->learnpath_data=Database::fetch_array($result);
+			$this->learnpath_data = Database::fetch_array($result);
 		}
 		return $this->learnpath_data;
 	}

+ 20 - 12
main/gradebook/lib/be/studentpublicationlink.class.php

@@ -158,27 +158,32 @@ class StudentPublicationLink extends AbstractLink
 	public function calc_score($stud_id = null)
 	{
 		$stud_id = intval($stud_id);
-		$tbl_stats = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
-		$sql = 'SELECT * FROM '.$tbl_stats."
+		$table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
+		$sql = 'SELECT * FROM '.$table."
     			WHERE
     				c_id = {$this->course_id} AND
     				id  = '".intval($this->get_ref_id())."' AND
-    				session_id	= ".api_get_session_id()."";
+    				session_id	= ".api_get_session_id()."
+				"
+		;
+
 		$query = Database::query($sql);
 		$assignment = Database::fetch_array($query);
 
-		if (count($assignment)==0) {
-			$v_assigment_id ='0';
+		if (count($assignment) == 0) {
+			$parentId = '0';
 		} else {
-			$v_assigment_id = $assignment['id'];
+			$parentId = $assignment['id'];
 		}
-		$sql = 'SELECT * FROM '.$tbl_stats.'
+
+		$sql = 'SELECT * FROM '.$table.'
     			WHERE
     				c_id = '.$this->course_id.' AND
     				active = 1 AND
-    				parent_id ="'.$v_assigment_id.'" AND
-    				session_id='.api_get_session_id().'';
-
+    				parent_id = "'.$parentId.'" AND
+    				session_id = '.api_get_session_id() .' AND
+    				qualificator_id <> 0
+				';
 		if (!empty($stud_id)) {
 			$sql .= " AND user_id = $stud_id ";
 		}
@@ -202,7 +207,10 @@ class StudentPublicationLink extends AbstractLink
 		// for 1 student
 		if (!empty($stud_id)) {
 			if ($data = Database::fetch_array($scores)) {
-				return array($data['qualification'], $assignment['qualification']);
+				return array(
+					$data['qualification'],
+					$assignment['qualification']
+				);
 			} else {
 				return '';
 			}
@@ -224,7 +232,7 @@ class StudentPublicationLink extends AbstractLink
 			if ($rescount == 0) {
 				return null;
 			} else {
-				return array ($sum , $rescount);
+				return array($sum, $rescount);
 			}
 		}
 	}

+ 27 - 8
main/gradebook/lib/be/surveylink.class.php

@@ -69,8 +69,15 @@ class SurveyLink extends AbstractLink
 				WHERE c_id = '.$course_id.' AND session_id = '.intval($session_id).'';
 		$result = Database::query($sql);
 		while ($data = Database::fetch_array($result)) {
-			$links[] = array($data['survey_id'], api_trunc_str($data['code'].': '.self::html_to_text($data['title']), 80));
-		};
+			$links[] = array(
+				$data['survey_id'],
+				api_trunc_str(
+					$data['code'] . ': ' . self::html_to_text($data['title']),
+					80
+				)
+			);
+		}
+
 		return isset($links) ? $links : null;
 	}
 
@@ -112,7 +119,6 @@ class SurveyLink extends AbstractLink
 		$session_id = api_get_session_id();
 		$tbl_survey = Database::get_course_table(TABLE_SURVEY);
 		$tbl_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
-		$get_individual_score = !is_null($stud_id);
 		$sql = "SELECT
 				COUNT(i.answered)
 				FROM $tbl_survey AS s
@@ -153,7 +159,9 @@ class SurveyLink extends AbstractLink
 				WHERE
 					s.c_id = {$this->course_id} AND
 					i.c_id = {$this->course_id} AND
-					s.survey_id = $ref_id AND i.session_id = $session_id";
+					s.survey_id = $ref_id AND
+					i.session_id = $session_id
+				";
 
 		if ($get_individual_score) {
 			$sql .= ' AND i.user = '.intval($stud_id);
@@ -199,7 +207,10 @@ class SurveyLink extends AbstractLink
 	{
 		$session_id = api_get_session_id();
 		$sql = 'SELECT count(survey_id) FROM '.$this->get_survey_table().'
-        		 WHERE c_id = '.$this->course_id.' AND survey_id = '.intval($this->get_ref_id()).' AND session_id='.intval($session_id).'';
+        		 WHERE
+        		 	c_id = '.$this->course_id.' AND
+        		 	survey_id = '.intval($this->get_ref_id()).' AND
+        		 	session_id='.intval($session_id).'';
 		$result = Database::query($sql);
 		$number = Database::fetch_row($result);
 		return ($number[0] != 0);
@@ -217,7 +228,10 @@ class SurveyLink extends AbstractLink
 			$session_id = api_get_session_id();
 			if ($tbl_name != '') {
 				$sql = 'SELECT survey_id FROM '.$this->get_survey_table().'
-    					WHERE c_id = '.$this->course_id.' AND survey_id = '.intval($this->get_ref_id()).' AND session_id = '.intval($session_id).' ';
+    					WHERE
+    						c_id = '.$this->course_id.' AND
+    						survey_id = '.intval($this->get_ref_id()).' AND
+    						session_id = '.intval($session_id).' ';
 				$result = Database::query($sql);
 				$row = Database::fetch_array($result, 'ASSOC');
 				$survey_id = $row['survey_id'];
@@ -234,7 +248,11 @@ class SurveyLink extends AbstractLink
 		if ($tbl_name == '') {
 			return false;
 		} elseif (!isset($this->survey_data)) {
-			$sql = 'SELECT * FROM '.$tbl_name.' WHERE c_id = '.$this->course_id.' AND survey_id = '.intval($this->get_ref_id()).' AND session_id='.intval($session_id).'';
+			$sql = 'SELECT * FROM '.$tbl_name.'
+					WHERE
+						c_id = '.$this->course_id.' AND
+						survey_id = '.intval($this->get_ref_id()).' AND
+						session_id='.intval($session_id).'';
 			$query = Database::query($sql);
 			$this->survey_data = Database::fetch_array($query);
 		}
@@ -248,6 +266,7 @@ class SurveyLink extends AbstractLink
 
 	private static function html_to_text($string)
 	{
-		return trim(api_html_entity_decode(strip_tags(str_ireplace(array('<p>', '</p>', '<br />', '<br/>', '<br>'), array('', ' ', ' ', ' ', ' '), $string)), ENT_QUOTES));
+		return strip_tags($string);
+		//return trim(api_html_entity_decode(strip_tags(str_ireplace(array('<p>', '</p>', '<br />', '<br/>', '<br>'), array('', ' ', ' ', ' ', ' '), $string)), ENT_QUOTES));
 	}
 }

+ 8 - 6
main/gradebook/lib/fe/displaygradebook.php

@@ -439,12 +439,14 @@ class DisplayGradebook
             for ($count = 0; $count < count($allEvalsLinks); $count++) {
                 $item = $allEvalsLinks[$count];
                 $score = $item->calc_score($user_id);
-                $divide = ( ($score[1]) == 0 ) ? 1 : $score[1];
-                //$sub_cat_percentage = $sum_categories_weight_array[$item->get_category_id()];
-                //$item_value = $score[0] / $divide * $item->get_weight() / $sub_cat_percentage * $sub_cat_percentage / $main_weight * $main_weight;
-                $item_value = $score[0] / $divide * $item->get_weight();
-                //var_dump($score[0], $divide, $item->get_weight(), $sub_cat_percentage, $main_weight, $item_value);
-                $item_value_total += $item_value;
+                if (!empty($score)) {
+                    $divide = $score[1] == 0 ? 1 : $score[1];
+                    //$sub_cat_percentage = $sum_categories_weight_array[$item->get_category_id()];
+                    //$item_value = $score[0] / $divide * $item->get_weight() / $sub_cat_percentage * $sub_cat_percentage / $main_weight * $main_weight;
+                    $item_value = $score[0] / $divide * $item->get_weight();
+                    //var_dump($score[0], $divide, $item->get_weight(), $sub_cat_percentage, $main_weight, $item_value);
+                    $item_value_total += $item_value;
+                }
             }
 
             $item_total = $main_weight;

+ 20 - 25
main/gradebook/lib/fe/flatviewtable.class.php

@@ -42,7 +42,8 @@ class FlatViewTable extends SortableTable
         $addparams = null,
         $mainCourseCategory = null
     ) {
-        parent :: __construct('flatviewlist', null, null, (api_is_western_name_order() xor api_sort_by_first_name()) ? 1 : 0);
+        parent :: __construct('flatviewlist', null, null, api_is_western_name_order() ? 1 : 0);
+
         $this->selectcat = $selectcat;
 
         $this->datagen = new FlatViewDataGenerator(
@@ -541,30 +542,26 @@ class FlatViewTable extends SortableTable
         }
 
         // retrieve sorting type
+
         if ($is_western_name_order) {
             $users_sorting = ($this->column == 0 ? FlatViewDataGenerator :: FVDG_SORT_FIRSTNAME : FlatViewDataGenerator :: FVDG_SORT_LASTNAME);
         } else {
             $users_sorting = ($this->column == 0 ? FlatViewDataGenerator :: FVDG_SORT_LASTNAME : FlatViewDataGenerator :: FVDG_SORT_FIRSTNAME);
         }
+
         if ($this->direction == 'DESC') {
             $users_sorting |= FlatViewDataGenerator :: FVDG_SORT_DESC;
         } else {
             $users_sorting |= FlatViewDataGenerator :: FVDG_SORT_ASC;
         }
-        // step 1: generate columns: evaluations and links
 
+        // step 1: generate columns: evaluations and links
         $header_names = $this->datagen->get_header_names($this->offset, $selectlimit);
 
-        $column = 0;
-
-        if ($is_western_name_order) {
-            $this->set_header($column++, $header_names[1]);
-            $this->set_header($column++, $header_names[0]);
-        } else {
-            $this->set_header($column++, $header_names[0]);
-            $this->set_header($column++, $header_names[1]);
-        }
+        $this->set_header(0, $header_names[0]);
+        $this->set_header(1, $header_names[1]);
 
+        $column = 2;
         while ($column < count($header_names)) {
             $this->set_header($column, $header_names[$column], false);
             $column++;
@@ -580,22 +577,19 @@ class FlatViewTable extends SortableTable
 
         $table_data = array();
         foreach ($data_array as $user_row) {
-            $table_row = array();
-            $count = 0;
-            $user_id = $user_row[$count++];
-            $lastname = $user_row[$count++];
-            $firstname = $user_row[$count++];
+            $user_id = $user_row[0];
+            unset($user_row[0]);
+            $userInfo = api_get_user_info($user_id);
             if ($is_western_name_order) {
-                $table_row[] = $this->build_name_link($user_id, $firstname);
-                $table_row[] = $this->build_name_link($user_id, $lastname);
+                $user_row[1] = $this->build_name_link($user_id, $userInfo['firstname']);
+                $user_row[2] = $this->build_name_link($user_id, $userInfo['lastname']);
             } else {
-                $table_row[] = $this->build_name_link($user_id, $lastname);
-                $table_row[] = $this->build_name_link($user_id, $firstname);
+                $user_row[1] = $this->build_name_link($user_id, $userInfo['lastname']);
+                $user_row[2] = $this->build_name_link($user_id, $userInfo['firstname']);
             }
-            while ($count < count($user_row)) {
-                $table_row[] = $user_row[$count++];
-            }
-            $table_data[] = $table_row;
+            $user_row = array_values($user_row);
+
+            $table_data[] = $user_row;
         }
         return $table_data;
     }
@@ -603,10 +597,11 @@ class FlatViewTable extends SortableTable
     /**
      * @param $user_id
      * @param $name
+     *
      * @return string
      */
     private function build_name_link($user_id, $name)
     {
-        return '<a href="user_stats.php?userid=' . $user_id . '&selectcat=' . $this->selectcat->get_id() . '">' . $name . '</a>';
+        return '<a href="user_stats.php?userid=' . $user_id . '&selectcat=' . $this->selectcat->get_id() . '&'.api_get_cidreq().'">' . $name . '</a>';
     }
 }

+ 4 - 2
main/gradebook/lib/fe/resulttable.class.php

@@ -148,8 +148,10 @@ class ResultTable extends SortableTable
 			$edit_column .= ' <a href="' . api_get_self() . '?delete_mark=' . $item['result_id'] . '&selecteval=' . $this->evaluation->get_id() . '">'.Display::return_icon('delete.png', get_lang('Delete'),'','22').'</a>';
 		}
 		if ($this->evaluation->get_course_code() == null) {
-			$edit_column.= '&nbsp;<a href="' . api_get_self() . '?resultdelete=' . $item['result_id'] . '&selecteval=' . $this->evaluation->get_id() . '" onclick="return confirmationuser();"><img src="../img/delete.gif" border="0" title="' . get_lang('Delete') . '" alt="" /></a>';
-		    $edit_column.= '&nbsp;<a href="user_stats.php?userid=' . $item['id'] . '&selecteval=' . $this->evaluation->get_id() . '"><img src="../img/statistics.gif" width="17px" border="0" title="' . get_lang('Statistics') . '" alt="" /></a>';
+			$edit_column.= '&nbsp;<a href="' . api_get_self() . '?resultdelete=' . $item['result_id'] . '&selecteval=' . $this->evaluation->get_id() . '" onclick="return confirmationuser();">
+			<img src="../img/delete.gif" border="0" title="' . get_lang('Delete') . '" alt="" /></a>';
+		    $edit_column.= '&nbsp;<a href="user_stats.php?userid=' . $item['id'] . '&selecteval=' . $this->evaluation->get_id() . '&'.api_get_cidreq().'">
+		    <img src="../img/statistics.gif" width="17px" border="0" title="' . get_lang('Statistics') . '" alt="" /></a>';
 		}
 		// Evaluation's origin is a link
 		if ($this->evaluation->get_category_id() < 0) {

+ 2 - 2
main/gradebook/lib/fe/usertable.class.php

@@ -92,8 +92,8 @@ class UserTable extends SortableTable
 		foreach ($data_array as $data) {
 			if ($data[2]!="") {//filter by course removed
 				$row = array ();
-				$row[] = $this->build_type_column ($data[0]);
-				$row[] = $this->build_name_link ($data[0]);
+				$row[] = $this->build_type_column($data[0]);
+				$row[] = $this->build_name_link($data[0]);
 				$row[] = $data[2];
 				$row[] = $data[3];
 				$row[] = $data[4];

+ 40 - 17
main/gradebook/lib/flatview_data_generator.class.php

@@ -57,6 +57,7 @@ class FlatViewDataGenerator
 
     /**
      * Get total number of users (rows)
+     * @return int
      */
     public function get_total_users_count()
     {
@@ -65,6 +66,7 @@ class FlatViewDataGenerator
 
     /**
     * Get total number of evaluations/links (columns) (the 2 users columns not included)
+    * @return int
     */
     public function get_total_items_count()
     {
@@ -85,6 +87,7 @@ class FlatViewDataGenerator
         if (isset($this->params['show_official_code']) && $this->params['show_official_code']) {
             $headers[] = get_lang('OfficialCode');
         }
+
         if (isset($this->params['join_firstname_lastname']) && $this->params['join_firstname_lastname']) {
             if (api_is_western_name_order()) {
                 $headers[] = get_lang('FirstnameAndLastname');
@@ -155,18 +158,17 @@ class FlatViewDataGenerator
             $session_id,
             'ORDER BY id'
         );
+
         $evaluationsAdded = array();
         if ($parent_id == 0 && !empty($allcat)) {
             // Means there are any subcategory
+
             foreach ($allcat as $sub_cat) {
                 $sub_cat_weight = round(100 * $sub_cat->get_weight() / $main_weight, 1);
                 $add_weight = " $sub_cat_weight %";
-                /*if (isset($this->params['export_pdf']) && $this->params['export_pdf']) {
-                   $add_weight = null;
-                }*/
                 $headers[] = Display::url(
                         $sub_cat->get_name(),
-                        api_get_self().'?selectcat='.$sub_cat->get_id()
+                        api_get_self().'?selectcat='.$sub_cat->get_id().'&'.api_get_cidreq()
                     ).$add_weight;
             }
         } else {
@@ -188,7 +190,9 @@ class FlatViewDataGenerator
             for ($count = 0; ($count < $items_count) && ($items_start + $count < count($this->evals_links)); $count++) {
                 /** @var AbstractLink $item */
                 $item = $this->evals_links[$count + $items_start];
-                if ($mainCategoryId == $item->get_category_id() && !in_array($item->get_id(), $evaluationsAdded)) {
+                if ($mainCategoryId == $item->get_category_id() &&
+                    !in_array($item->get_id(), $evaluationsAdded)
+                ) {
                     $weight = round(100 * $item->get_weight() / $main_weight, 1);
                     $headers[] = $item->get_name() . ' ' . $weight . ' % ';
                 }
@@ -215,11 +219,13 @@ class FlatViewDataGenerator
                 $max = $score[0];
             }
         }
-        return $max ;
+
+        return $max;
     }
 
     /**
      * Get array containing evaluation items
+     * @return array
      */
     public function get_evaluation_items($items_start = 0, $items_count = null)
     {
@@ -272,9 +278,10 @@ class FlatViewDataGenerator
 
         // sort users array
         if ($users_sorting & self :: FVDG_SORT_LASTNAME) {
-            usort($userTable, array ('FlatViewDataGenerator','sort_by_last_name'));
+            usort($userTable, array('FlatViewDataGenerator','sort_by_last_name'));
+
         } elseif ($users_sorting & self :: FVDG_SORT_FIRSTNAME) {
-            usort($userTable, array ('FlatViewDataGenerator','sort_by_first_name'));
+            usort($userTable, array('FlatViewDataGenerator','sort_by_first_name'));
         }
 
         if ($users_sorting & self :: FVDG_SORT_DESC) {
@@ -352,7 +359,9 @@ class FlatViewDataGenerator
             }
 
             // Last name
-            if (isset($this->params['join_firstname_lastname']) && $this->params['join_firstname_lastname']) {
+            if (isset($this->params['join_firstname_lastname']) &&
+                $this->params['join_firstname_lastname']
+            ) {
                 if ($export_to_pdf) {
                     $row['name'] = api_get_person_name($user[3], $user[2]);
                 } else {
@@ -386,7 +395,12 @@ class FlatViewDataGenerator
 
             $course_code = api_get_course_id();
             $session_id = api_get_session_id();
-            $allcat = $this->category->get_subcategories(null, $course_code, $session_id, 'ORDER BY id');
+            $allcat = $this->category->get_subcategories(
+                null,
+                $course_code,
+                $session_id,
+                'ORDER BY id'
+            );
 
             $evaluationsAdded = array();
 
@@ -397,7 +411,7 @@ class FlatViewDataGenerator
 
                     $real_score = $score;
 
-                    $divide = ( ($score[1])==0 ) ? 1 : $score[1];
+                    $divide = $score[1] == 0 ? 1 : $score[1];
 
                     $sub_cat_percentage = $sum_categories_weight_array[$sub_cat->get_id()];
                     $item_value  = $score[0]/$divide*$main_weight;
@@ -407,10 +421,10 @@ class FlatViewDataGenerator
                     $item_value = $percentage*$item_value;
                     $item_total += $sub_cat->get_weight();
                     /*
-                                        if ($convert_using_the_global_weight) {
-                                            $score[0] = $score[0]/$main_weight*$sub_cat->get_weight();
-                                            $score[1] = $main_weight ;
-                                        }
+                        if ($convert_using_the_global_weight) {
+                            $score[0] = $score[0]/$main_weight*$sub_cat->get_weight();
+                            $score[1] = $main_weight ;
+                        }
                     */
                     if (api_get_setting('gradebook_show_percentage_in_reports') == 'false') {
                         //if (true)
@@ -424,8 +438,7 @@ class FlatViewDataGenerator
                     }
 
                     if (!isset($this->params['only_total_category']) ||
-                        (isset($this->params['only_total_category']) &&
-                            $this->params['only_total_category'] == false)
+                        (isset($this->params['only_total_category']) && $this->params['only_total_category'] == false)
                     ) {
                         if (!$show_all) {
                             $row[] = $temp_score.' ';
@@ -796,11 +809,21 @@ class FlatViewDataGenerator
         return $data;
     }
 
+    /**
+     * @param $item1
+     * @param $item2
+     * @return int
+     */
     public function sort_by_last_name($item1, $item2)
     {
         return api_strcmp($item1[2], $item2[2]);
     }
 
+    /**
+     * @param $item1
+     * @param $item2
+     * @return int
+     */
     public function sort_by_first_name($item1, $item2)
     {
         return api_strcmp($item1[3], $item2[3]);

+ 12 - 3
main/gradebook/lib/gradebook_functions.inc.php

@@ -5,6 +5,7 @@
  * Script
  * @package chamilo.gradebook
  */
+
 /**
  * These are functions used in gradebook
  *
@@ -110,6 +111,7 @@ function remove_resource_from_course_gradebook($link_id)
     $l = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
     $sql = "DELETE FROM $l WHERE id = ".(int)$link_id;
     Database::query($sql);
+
     return true;
 }
 
@@ -127,7 +129,9 @@ function block_students()
 function get_course_name_from_code($code)
 {
     $tbl_main_categories = Database :: get_main_table(TABLE_MAIN_COURSE);
-    $sql = 'SELECT title, code FROM ' . $tbl_main_categories . 'WHERE code = "' . Database::escape_string($code) . '"';
+    $sql = 'SELECT title, code
+            FROM ' . $tbl_main_categories . '
+            WHERE code = "' . Database::escape_string($code) . '"';
     $result = Database::query($sql);
     if ($col = Database::fetch_array($result)) {
         return $col['title'];
@@ -194,6 +198,7 @@ function get_icon_file_name($type)
             $icon = 'link.gif';
             break;
     }
+
     return $icon;
 }
 
@@ -400,7 +405,10 @@ function is_resource_in_course_gradebook($course_code, $resource_type, $resource
     $l = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
     $course_code = Database::escape_string($course_code);
     $sql = "SELECT * FROM $l l
-            WHERE course_code = '$course_code' AND type = ".(int)$resource_type . " AND ref_id = " . (int)$resource_id;
+            WHERE
+                course_code = '$course_code' AND
+                type = ".(int)$resource_type . " AND
+                ref_id = " . (int)$resource_id;
     $res = Database::query($sql);
 
     if (Database::num_rows($res) < 1) {
@@ -649,7 +657,8 @@ function get_list_users_certificates($cat_id = null, $userList = array())
     $table_user = Database::get_main_table(TABLE_MAIN_USER);
     $sql = 'SELECT DISTINCT u.user_id, u.lastname, u.firstname, u.username
     		FROM ' . $table_user . ' u
-    		INNER JOIN ' . $table_certificate . ' gc ON u.user_id=gc.user_id ';
+    		INNER JOIN ' . $table_certificate . ' gc
+    		ON u.user_id=gc.user_id ';
     if (!is_null($cat_id) && $cat_id > 0) {
         $sql.=' WHERE cat_id=' . intval($cat_id);
     }

+ 53 - 21
main/gradebook/lib/gradebook_functions_users.inc.php

@@ -1,5 +1,6 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
  * Various user related functions
  * @author Julio Montoya <gugli100@gmail.com> adding security functions
@@ -23,17 +24,25 @@ function get_users_in_course($course_id)
 	if (!empty($current_session)) {
 		$sql = "SELECT user.user_id, user.username, lastname, firstname, official_code
 			 	FROM $tbl_session_course_user as scru, $tbl_user as user
-			 	WHERE scru.id_user=user.user_id
-			 	AND scru.status=0
-			 	AND scru.course_code='$course_id' AND id_session ='$current_session' $order_clause ";
+			 	WHERE
+			 		scru.id_user=user.user_id AND
+			 		scru.status=0  AND
+			 		scru.course_code='$course_id' AND
+			 		id_session ='$current_session'
+			 	$order_clause
+			 	";
 	} else {
 		$sql = 'SELECT user.user_id, user.username, lastname, firstname, official_code
                 FROM '.$tbl_course_user.' as course_rel_user, '.$tbl_user.' as user
-                WHERE   course_rel_user.user_id=user.user_id AND
-                        course_rel_user.status='.STUDENT.' AND
-                        course_rel_user.course_code = "'.$course_id.'" '.$order_clause;
+                WHERE
+                	course_rel_user.user_id=user.user_id AND
+                    course_rel_user.status='.STUDENT.' AND
+                    course_rel_user.course_code = "'.$course_id.'" '.
+				$order_clause;
 	}
+
 	$result = Database::query($sql);
+
 	return get_user_array_from_sql_result($result);
 }
 
@@ -55,7 +64,7 @@ function get_user_array_from_sql_result($result)
 	return $a_students;
 }
 
-function get_all_users ($evals = array(), $links = array())
+function get_all_users($evals = array(), $links = array())
 {
 	$coursecodes = array();
 	$users = array();
@@ -64,18 +73,26 @@ function get_all_users ($evals = array(), $links = array())
 		$coursecode = $eval->get_course_code();
 		// evaluation in course
 		if (isset($coursecode) && !empty($coursecode)) {
-			if (!array_key_exists($coursecode,$coursecodes)) {
+			if (!array_key_exists($coursecode, $coursecodes)) {
 				$coursecodes[$coursecode] = '1';
 				$users = array_merge($users, get_users_in_course($coursecode));
 			}
-		} else {// course independent evaluation
+		} else {
+			// course independent evaluation
 			$tbl_user = Database :: get_main_table(TABLE_MAIN_USER);
 			$tbl_res = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
 
-			$sql = 'SELECT user.user_id,lastname, firstname, user.official_code
+			$sql = 'SELECT user.user_id, lastname, firstname, user.official_code
                     FROM '.$tbl_res.' as res, '.$tbl_user.' as user
-                    WHERE res.evaluation_id = '.intval($eval->get_id())
-				.' AND res.user_id = user.user_id';
+                    WHERE
+                    	res.evaluation_id = '.intval($eval->get_id()).' AND
+                    	res.user_id = user.user_id
+					';
+			$sql .= ' ORDER BY lastname, firstname';
+			if (api_is_western_name_order()) {
+				$sql .= ' ORDER BY firstname, lastname';
+			}
+
 			$result = Database::query($sql);
 			$users = array_merge($users, get_user_array_from_sql_result($result));
 		}
@@ -89,7 +106,7 @@ function get_all_users ($evals = array(), $links = array())
 			$users = array_merge($users, get_users_in_course($coursecode));
 		}
 	}
-	unset ($coursecodes);
+
 	return $users;
 }
 
@@ -105,9 +122,10 @@ function find_students($mask= '')
 	}
 	$mask = Database::escape_string($mask);
 
-	$tbl_user= Database :: get_main_table(TABLE_MAIN_USER);
-	$tbl_cru= Database :: get_main_table(TABLE_MAIN_COURSE_USER);
-	$sql= 'SELECT DISTINCT user.user_id, user.lastname, user.firstname, user.email, user.official_code ' . ' FROM ' . $tbl_user . ' user';
+	$tbl_user = Database :: get_main_table(TABLE_MAIN_USER);
+	$tbl_cru = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
+	$sql = 'SELECT DISTINCT user.user_id, user.lastname, user.firstname, user.email, user.official_code
+		    FROM ' . $tbl_user . ' user';
 	if (!api_is_platform_admin()) {
 		$sql .= ', ' . $tbl_cru . ' cru';
 	}
@@ -117,12 +135,26 @@ function find_students($mask= '')
 	$sql .= ' OR user.firstname LIKE '."'%" . $mask . "%')";
 
 	if (!api_is_platform_admin()) {
-		$sql .= ' AND user.user_id = cru.user_id AND cru.relation_type<>'.COURSE_RELATION_TYPE_RRHH.' ' . ' AND cru.course_code in' . ' (SELECT course_code' . ' FROM ' . $tbl_cru . ' WHERE user_id = ' . api_get_user_id() . ' AND status = ' . COURSEMANAGER . ')';
+		$sql .= ' AND user.user_id = cru.user_id AND
+				  cru.relation_type <> '.COURSE_RELATION_TYPE_RRHH.' AND
+				  cru.course_code in (
+						SELECT course_code FROM '.$tbl_cru . '
+				  		WHERE
+				  			user_id = ' . api_get_user_id() . ' AND
+				  			status = ' . COURSEMANAGER . '
+				  	)
+				';
 	}
-	$sql .= ' ORDER BY lastname';
-	$result= Database::query($sql);
-	$db_users= Database::store_result($result);
-	return $db_users;
+
+	$sql .= ' ORDER BY lastname, firstname';
+	if (api_is_western_name_order()) {
+		$sql .= ' ORDER BY firstname, lastname';
+	}
+
+	$result = Database::query($sql);
+	$users = Database::store_result($result);
+
+	return $users;
 }
 
 /**

+ 2 - 0
main/gradebook/lib/scoredisplay.class.php

@@ -364,9 +364,11 @@ class ScoreDisplay
                 return $this->display_as_div($score).' (' . $this->display_as_percent($score) . ')'.$custom;
             case SCORE_DIV_SIMPLE_WITH_CUSTOM :         // X - Good!
                 $custom = $this->display_custom($score);
+
                 if (!empty($custom)) {
                     $custom = ' - '.$custom;
                 }
+
                 return $this->display_simple_score($score).$custom;
                 break;
             case SCORE_DIV_SIMPLE_WITH_CUSTOM_LETTERS:

+ 7 - 7
main/gradebook/lib/user_data_generator.class.php

@@ -47,13 +47,13 @@ class UserDataGenerator
 				$evals_filtered_copy = $evals;
 			}
 
-		}//isset($coursecode) && strcmp($coursecode,api_get_course_id())===0
+		}
 		if (count($result) == 0) {
 			$evals_filtered=$evals;
 		} else {
 			$evals_filtered=$evals_filtered_copy;
 		}
-		$this->items = array_merge ($evals_filtered, $links);
+		$this->items = array_merge($evals_filtered, $links);
 
 		$this->coursecodecache = array();
 		$this->categorycache = array();
@@ -143,12 +143,12 @@ class UserDataGenerator
 			$row = array ();
 			$row[] = $item;
 			$row[] = $item->get_name();
-			$row[] = $this->build_course_name ($item);
-			$row[] = $this->build_category_name ($item);
-			$row[] = $this->build_average_column ($item, $ignore_score_color);
-			$row[] = $this->build_result_column ($item, $ignore_score_color);
+			$row[] = $this->build_course_name($item);
+			$row[] = $this->build_category_name($item);
+			$row[] = $this->build_average_column($item, $ignore_score_color);
+			$row[] = $this->build_result_column($item, $ignore_score_color);
 			if ($scoredisplay->is_custom())
-				$row[] = $this->build_mask_column ($item, $ignore_score_color);
+				$row[] = $this->build_mask_column($item, $ignore_score_color);
 			$data[] = $row;
 		}
 		return $data;

+ 12 - 2
main/gradebook/user_info.php

@@ -5,8 +5,11 @@
  * Script
  * @package chamilo.gradebook
  */
+
 $language_file = 'gradebook';
+
 //$cidReset = true;
+
 require_once '../inc/global.inc.php';
 require_once api_get_path(LIBRARY_PATH) . 'fileManage.lib.php';
 require_once api_get_path(LIBRARY_PATH) . 'export.lib.inc.php';
@@ -28,9 +31,16 @@ require_once 'lib/gradebook_functions.inc.php';
 require_once 'lib/fe/userform.class.php';
 block_students();
 
-$form = new UserForm(UserForm :: TYPE_USER_INFO, $user, 'user_info_form', null, api_get_self() . '?userid=' . $user_id . '&selectcat=' . Security::remove_XSS($_GET['selectcat']));
+$form = new UserForm(
+    UserForm :: TYPE_USER_INFO,
+    $user,
+    'user_info_form',
+    null,
+    api_get_self() . '?userid=' . $user_id . '&selectcat=' . Security::remove_XSS($_GET['selectcat']).'&'.api_get_cidreq()
+);
+
 if ($form->validate()) {
-    header('Location: user_stats.php?selectcat=' . Security::remove_XSS($_GET['selectcat']).'&userid=' .$user_id);
+    header('Location: user_stats.php?selectcat=' . Security::remove_XSS($_GET['selectcat']).'&userid=' .$user_id.'&'.api_get_cidreq();
     exit;
 }
 

+ 4 - 4
main/gradebook/user_stats.php

@@ -32,9 +32,9 @@ $interbreadcrumb[]= array (
 ));
 
 $category = Category :: load($_GET['selectcat']);
-$my_user_id=Security::remove_XSS($_GET['userid']);
-$allevals= $category[0]->get_evaluations($my_user_id, true);
-$alllinks= $category[0]->get_links($my_user_id, true);
+$my_user_id = Security::remove_XSS($_GET['userid']);
+$allevals = $category[0]->get_evaluations($my_user_id, true);
+$alllinks = $category[0]->get_links($my_user_id, true);
 
 if ($_GET['selectcat'] != null) {
     $addparams= array (
@@ -48,7 +48,7 @@ if ($_GET['selectcat'] != null) {
     );
 }
 
-$user_table= new UserTable($my_user_id, $allevals, $alllinks, $addparams);
+$user_table = new UserTable($my_user_id, $allevals, $alllinks, $addparams);
 
 if (isset ($_GET['exportpdf'])) {
     $datagen       = new UserDataGenerator($my_user_id, $allevals, $alllinks);

+ 3 - 3
main/group/example.csv

@@ -1,5 +1,5 @@
-"category";"group";"description";"announcements_state";"calendar_state";"chat_state";"doc_state";"forum_state";"work_state";"wiki_state";"max_student";"self_reg_allowed";"self_unreg_allowed";"groups_per_user";
+"category";"group";"description";"announcements_state";"calendar_state";"chat_state";"doc_state";"forum_state";"work_state";"wiki_state";"max_student";"self_reg_allowed";"self_unreg_allowed";"groups_per_user";"students";"tutors"
 "Category 1";"";"This is a category";"2";"2";"2";"2";"2";"2";"2";"0";"0";"0";"0";
-"";"Group 1";"This is a group with no category";"2";"2";"2";"2";"2";"2";"2";"0";"0";"0"
-"Category 1";"Group 2";"This is a group in a category 1";"2";"2";"2";"2";"2";"2";"2";"0";"0";"0"
+"";"Group 1";"This is a group with no category";"2";"2";"2";"2";"2";"2";"2";"0";"0";"0";"";"username1,username2";"username3,username4"
+"Category 1";"Group 2";"This is a group in a category 1";"2";"2";"2";"2";"2";"2";"2";"0";"0";"0";"";"username1,username2";"username3,username4"
 

+ 2 - 5
main/group/group.php

@@ -167,18 +167,15 @@ if (api_is_allowed_to_edit(false, true)) {
     echo  '<a href="import.php?'.api_get_cidreq().'&action=import">'.
         Display::return_icon('import_csv.png', get_lang('Import'), '', ICON_SIZE_MEDIUM).'</a>';
 
-    echo  '<a href="group_overview.php?'.api_get_cidreq().'&action=export&type=csv">'.
+    echo  '<a href="group_overview.php?'.api_get_cidreq().'&action=export_all&type=csv">'.
         Display::return_icon('export_csv.png', get_lang('ExportAsCSV'), '', ICON_SIZE_MEDIUM).'</a>';
 
-    echo  '<a href="group_overview.php?'.api_get_cidreq().'&action=export&type=xls">'.
+    echo  '<a href="group_overview.php?'.api_get_cidreq().'&action=export_all&type=xls">'.
         Display::return_icon('export_excel.png', get_lang('ExportAsXLS'), '', ICON_SIZE_MEDIUM).'</a>';
 
     echo  '<a href="group_overview.php?'.api_get_cidreq().'&action=export_pdf">'.
         Display::return_icon('pdf.png', get_lang('ExportToPDF'), '', ICON_SIZE_MEDIUM).'</a>';
 
-    echo  '<a href="group_overview.php?'.api_get_cidreq().'&action=export_all&type=xls">'.
-        Display::return_icon('export_excel.png', get_lang('ExportSettingsAsXLS'), '', ICON_SIZE_MEDIUM).'</a>';
-
     echo '<a href="group_overview.php?'.api_get_cidreq().'">'.
         Display::return_icon('group_summary.png', get_lang('GroupOverview'), '', ICON_SIZE_MEDIUM).'</a>';
 

+ 4 - 23
main/group/group_overview.php

@@ -1,5 +1,6 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
  *	Main page for the group module.
  *	This script displays the general group settings,
@@ -12,9 +13,6 @@
  *	@author Bart Mollet, code cleaning, use of Display-library, list of courseAdmin-tools, use of GroupManager
  *	@package chamilo.group
  */
-/**
- * INIT SECTION
- */
 
 // Name of the language file that needs to be included
 $language_file = array('group', 'admin');
@@ -39,7 +37,7 @@ $keyword = isset($_GET['keyword']) ? $_GET['keyword'] : null;
 if (isset($_GET['action'])) {
     switch ($_GET['action']) {
         case 'export_all':
-            $data = GroupManager::exportCategoriesAndGroupsToArray();
+            $data = GroupManager::exportCategoriesAndGroupsToArray(null, true);
             Export::export_table_csv($data);
             exit;
             break;
@@ -54,26 +52,9 @@ if (isset($_GET['action'])) {
             break;
         case 'export':
             $groupId = isset($_GET['id']) ? intval($_GET['id']) : null;
-            $groups = GroupManager::get_group_list();
 
-            $data = array();
-            foreach ($groups as $index => $group) {
-                if (!empty($groupId)) {
-                    if ($group['id'] != $groupId) {
-                        continue;
-                    }
-                }
-                $users = GroupManager::get_users($group['id']);
-                foreach ($users as $index => $user) {
-                    $row = array();
-                    $user = api_get_user_info($user);
-                    $row[] = $group['name'];
-                    $row[] = $user['official_code'];
-                    $row[] = $user['lastName'];
-                    $row[] = $user['firstName'];
-                    $data[] = $row;
-                }
-            }
+            $data = GroupManager::exportCategoriesAndGroupsToArray($groupId, true);
+
             switch ($_GET['type']) {
                 case 'csv':
                     Export::export_table_csv($data);

+ 3 - 1
main/group/import.php

@@ -35,7 +35,9 @@ $form->addElement('label', null, Display::url(get_lang('ExampleCSVFile'), api_ge
 $form->addElement('button', 'submit', get_lang('Import'));
 
 if ($form->validate()) {
-    if (isset($_FILES['file']['tmp_name']) && !empty($_FILES['file']['tmp_name'])) {
+    if (isset($_FILES['file']['tmp_name']) &&
+        !empty($_FILES['file']['tmp_name'])
+    ) {
         $groupData = Import::csv_reader($_FILES['file']['tmp_name']);
         $deleteNotInArray = $form->getSubmitValue('delete_not_in_file') == 1 ? true : false;
 

+ 68 - 0
main/inc/ajax/admin.ajax.php

@@ -35,6 +35,74 @@ switch ($action) {
     case 'version':
         echo version_check();
         break;
+
+    case 'save_block_extra':
+        $content = isset($_POST['content']) ? Security::remove_XSS($_POST['content']) : null;
+        $blockName = isset($_POST['block']) ? Security::remove_XSS($_POST['block']) : null;
+
+        if (empty($blockName)) {
+            die;
+        }
+
+        if (api_is_multiple_url_enabled()) {
+            $accessUrlId = api_get_current_access_url_id();
+
+            if ($accessUrlId == -1) {
+                die;
+            }
+
+            $urlInfo = api_get_access_url($accessUrlId);
+            $url = api_remove_trailing_slash(preg_replace('/https?:\/\//i', '', $urlInfo['url']));
+            $cleanUrl = str_replace('/', '-', $url);
+
+            $newUrlDir = api_get_path(SYS_PATH) . "home/$cleanUrl/admin/";
+        } else {
+            $newUrlDir = api_get_path(SYS_PATH) . "home/admin/";
+        }
+
+        if (!is_dir($newUrlDir)) {
+            @mkdir($newUrlDir, api_get_permissions_for_new_directories(), true);
+        }
+
+        $fullFilePath = "{$newUrlDir}{$blockName}_extra.html";
+
+        if (file_exists($fullFilePath)) {
+            @unlink($fullFilePath);
+        }
+
+        @touch($fullFilePath);
+
+        @file_put_contents($fullFilePath, $content);
+
+        break;
+
+    case 'get_extra_content':
+        $blockName = isset($_POST['block']) ? Security::remove_XSS($_POST['block']) : null;
+
+        if (empty($blockName)) {
+            die;
+        }
+
+        if (api_is_multiple_url_enabled()) {
+            $accessUrlId = api_get_current_access_url_id();
+
+            if ($accessUrlId == -1) {
+                die;
+            }
+
+            $urlInfo = api_get_access_url($accessUrlId);
+            $url = api_remove_trailing_slash(preg_replace('/https?:\/\//i', '', $urlInfo['url']));
+            $cleanUrl = str_replace('/', '-', $url);
+
+            $newUrlDir = api_get_path(SYS_PATH) . "home/$cleanUrl/admin/";
+        } else {
+            $newUrlDir = api_get_path(SYS_PATH) . "home/admin/";
+        }
+
+        if (Security::check_abs_path("{$newUrlDir}{$blockName}_extra.html", $newUrlDir)) {
+            echo @file_get_contents("{$newUrlDir}{$blockName}_extra.html");
+        }
+        break;
 }
 
 

+ 6 - 1
main/inc/ajax/agenda.ajax.php

@@ -36,6 +36,7 @@ switch ($action) {
             break;
         }
         $add_as_announcement = isset($_REQUEST['add_as_annonuncement']) ? $_REQUEST['add_as_annonuncement'] : null;
+        $comment = isset($_REQUEST['comment']) ? $_REQUEST['comment'] : null;
         echo $agenda->add_event(
             $_REQUEST['start'],
             $_REQUEST['end'],
@@ -43,7 +44,11 @@ switch ($action) {
             $_REQUEST['title'],
             $_REQUEST['content'],
             $_REQUEST['users_to_send'],
-            $add_as_announcement
+            $add_as_announcement,
+            null, //$parentEventId = null,
+            array(), //$attachmentArray = array(),
+            null, //$attachmentComment = null,
+            $comment
         );
         break;
     case 'edit_event':

+ 29 - 18
main/inc/introductionSection.inc.php

@@ -1,5 +1,6 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
  * The INTRODUCTION MICRO MODULE is used to insert and edit
  * an introduction section on a Chamilo module or on the course homepage.
@@ -18,7 +19,7 @@
  *
  * usage :
  *
- * $moduleId = XX // specifying the module Id
+ * $moduleId = 'XX'; // specifying the module tool (string value)
  * include(introductionSection.inc.php);
  *
  * This script is also used since Chamilo 1.9 to show course progress (from the
@@ -91,19 +92,27 @@ $form->addElement('style_submit_button', 'intro_cmdUpdate', get_lang('SaveIntroT
 $course_id = api_get_course_int_id();
 
 if ($intro_editAllowed) {
-    $moduleId = intval($moduleId);
-
     /* Replace command */
     if ($intro_cmdUpdate) {
         if ($form->validate()) {
             $form_values = $form->exportValues();
             $intro_content = Security::remove_XSS(stripslashes(api_html_entity_decode($form_values['intro_content'])), COURSEMANAGERLOWSECURITY);
             if (!empty($intro_content)) {
-                $sql = "REPLACE $TBL_INTRODUCTION SET c_id = $course_id, id='$moduleId',intro_text='".Database::escape_string($intro_content)."', session_id='".intval($session_id)."'";
+                $sql = "REPLACE $TBL_INTRODUCTION
+                        SET
+                            c_id = $course_id, id='".Database::escape_string($moduleId)."',
+                            intro_text='".Database::escape_string($intro_content)."',
+                            session_id='".intval($session_id)."'
+                        ";
                 Database::query($sql);
-                $introduction_section .= Display::return_message(get_lang('IntroductionTextUpdated'),'confirmation', false);
+                $introduction_section .= Display::return_message(
+                    get_lang('IntroductionTextUpdated'),
+                    'confirmation',
+                    false
+                );
             } else {
-                $intro_cmdDel = true;	// got to the delete command
+                // got to the delete command
+                $intro_cmdDel = true;
             }
         } else {
             $intro_cmdEdit = true;
@@ -112,12 +121,16 @@ if ($intro_editAllowed) {
 
     /* Delete Command */
     if ($intro_cmdDel) {
-        Database::query("DELETE FROM $TBL_INTRODUCTION WHERE c_id = $course_id AND id='".$moduleId."' AND session_id='".intval($session_id)."'");
+        $sql = "DELETE FROM $TBL_INTRODUCTION
+                WHERE
+                    c_id = $course_id AND
+                    id='".Database::escape_string($moduleId)."' AND
+                    session_id='".intval($session_id)."'";
+        Database::query($sql);
         $introduction_section .= Display::return_message(get_lang('IntroductionTextDeleted'), 'confirmation');
     }
 }
 
-
 /* INTRODUCTION MICRO MODULE - DISPLAY SECTION */
 
 /* Retrieves the module introduction text, if exist */
@@ -126,6 +139,7 @@ if ($intro_editAllowed) {
 $intro_content = null;
 $sql = "SELECT intro_text FROM $TBL_INTRODUCTION
         WHERE c_id = $course_id AND id='".Database::escape_string($moduleId)."' AND session_id = 0";
+
 $intro_dbQuery = Database::query($sql);
 if (Database::num_rows($intro_dbQuery) > 0) {
     $intro_dbResult = Database::fetch_array($intro_dbQuery);
@@ -243,7 +257,7 @@ if ($tool == TOOL_COURSE_HOMEPAGE && !isset($_GET['intro_cmdEdit'])) {
                                     <div class="row-fluid score-thematic">
                                         <div class="span8">';
         $thematic_description_html .=
-                                            '<div class="span6 name-student">
+            '<div class="span6 name-student">
                                                 <h2>' . $userInfo['firstName'] . '</h2>
                                                 <h3>' . $userInfo['lastName'] . '</h3>
                                             </div>
@@ -256,7 +270,7 @@ if ($tool == TOOL_COURSE_HOMEPAGE && !isset($_GET['intro_cmdEdit'])) {
                                             </div>
                                         </div>';
         $thematic_description_html .=
-                                        '<div class="span4">
+            '<div class="span4">
                                             <a id="thematic-show" class="btn btn-small btn-primary accordion-toggle btn-hide-thematic" href="#pross" data-toggle="collapse" data-parent="#progress-bar-course">
                                             ' . get_lang('SeeDetail') . '
                                             </a>
@@ -268,7 +282,7 @@ if ($tool == TOOL_COURSE_HOMEPAGE && !isset($_GET['intro_cmdEdit'])) {
                                 </div>
                             </div>';
         $thematic_description_html .=
-                            '<div class="accordion-body collapse in" id="pross" style="height: auto !important;">
+            '<div class="accordion-body collapse in" id="pross" style="height: auto !important;">
                                 <div class="accordion-inner">
                                     <div class="row-fluid">
                                         <div class="span4">
@@ -291,10 +305,10 @@ if ($tool == TOOL_COURSE_HOMEPAGE && !isset($_GET['intro_cmdEdit'])) {
                                             </div>
                                         </div>';
         $thematic_description_html .=
-                                        '<div class="span8">
+            '<div class="span8">
                                             <div class="row-fluid">';
         $thematic_description_html .=
-                                                '<div class="span6 items-progress'.$class1.'">
+            '<div class="span6 items-progress'.$class1.'">
                                                     <div class="topics">' . $subTitle1 . '</div>
                                                     <p class="title_topics">' . $thematic_info['title'] . '</p>
                                                     <p class="date">' . $thematic_advance_info['start_date'] . '</p>
@@ -308,7 +322,7 @@ if ($tool == TOOL_COURSE_HOMEPAGE && !isset($_GET['intro_cmdEdit'])) {
             $thematic_advance_info2['start_date'] = api_format_date($thematic_advance_info2['start_date'], DATE_TIME_FORMAT_LONG);
 
             $thematic_description_html .=
-                                                '<div class="span6 items-progress">
+                '<div class="span6 items-progress">
                                                     <div class="topics">'.$subTitle2.'</div>
                                                     <p class="title_topics">'.$thematic_info['title'].'</p>
                                                     <p class="date">'.$thematic_advance_info2['start_date'].'</p>
@@ -317,7 +331,7 @@ if ($tool == TOOL_COURSE_HOMEPAGE && !isset($_GET['intro_cmdEdit'])) {
                                                 </div>';
         }
         $thematic_description_html.=
-                                                '</div>
+            '</div>
                                             </div>
                                         </div>
                                     </div>
@@ -337,9 +351,6 @@ $introduction_section .=  '</div>';
 $introduction_section .=  '<div class="home-course-intro span12"><div class="page-course">';
 
 if ($intro_dispDefault) {
-
-    $intro_content = $intro_content;
-
     if (!empty($intro_content)) {
         $introduction_section.='<div class="page-course-intro">';
         $introduction_section .=  $intro_content;

+ 80 - 39
main/inc/lib/certificate.lib.php

@@ -3,14 +3,19 @@
 
 /**
  * Certificate Class
- * The certificates class is used to generate certificates from inside the
- * gradebook tool.
+ * Generate certificates based in the gradebook tool.
  * @package chamilo.library.certificates
  */
 class Certificate extends Model
 {
     public $table;
-    public $columns = array('id','cat_id','score_certificate','created_at','path_certificate');
+    public $columns = array(
+        'id',
+        'cat_id',
+        'score_certificate',
+        'created_at',
+        'path_certificate'
+    );
     /**
      * Certification data
      */
@@ -21,8 +26,8 @@ class Certificate extends Model
      */
     public $certification_user_path = null;
     public $certification_web_user_path = null;
-    public $html_file     = null;
-    public $qr_file     = null;
+    public $html_file = null;
+    public $qr_file = null;
     public $user_id;
 
     /* If true every time we enter to the certificate URL
@@ -34,16 +39,18 @@ class Certificate extends Model
 
     /**
      * Constructor
-     * @param	int	ID of the certificate. If no ID given, take user_id and try to generate one
+     * @param int $certificate_id ID of the certificate.
+     *
+     * If no ID given, take user_id and try to generate one
      */
     public function __construct($certificate_id = null)
     {
-        $this->table             =  Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
+        $this->table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
         $this->certificate_data = null;
 
         if (isset($certificate_id)) {
             $this->certificate_data = $this->get($certificate_id);
-            $this->user_id          = $this->certificate_data['user_id'];
+            $this->user_id = $this->certificate_data['user_id'];
         } else {
             //Try with the current user
             $this->user_id = api_get_user_id();
@@ -51,10 +58,10 @@ class Certificate extends Model
 
         if ($this->user_id) {
 
-            //Need to be called before any operation
+            // Need to be called before any operation
             $this->check_certificate_path();
 
-            //To force certification generation
+            // To force certification generation
             if ($this->force_certificate_generation) {
                 $this->generate();
             }
@@ -102,9 +109,12 @@ class Certificate extends Model
      * Deletes the current certificate object. This is generally triggered by
      * the teacher from the gradebook tool to re-generate the certificate because
      * the original version wa flawed.
+     * @param bool $force_delete
+     * @return bool
      */
     public function delete($force_delete = false)
     {
+        $delete_db = false;
         if (!empty($this->certificate_data)) {
             if (!is_null($this->html_file) || $this->html_file != '' || strlen($this->html_file)) {
                 //Deleting HTML file
@@ -121,12 +131,15 @@ class Certificate extends Model
                     @unlink($this->qr_file);
                 }
                 if ($delete_db || $force_delete) {
+
                     return parent::delete($this->certificate_data['id']);
                 }
             } else {
+
                 return parent::delete($this->certificate_data['id']);
             }
         }
+
         return false;
     }
 
@@ -146,43 +159,58 @@ class Certificate extends Model
         $params['hide_print_button'] = isset($params['hide_print_button']) ? true : false;
 
         $my_category = Category :: load($this->certificate_data['cat_id']);
-
-        if (isset($my_category[0]) && $my_category[0]->is_certificate_available($this->user_id)) {
-
-            $user         = api_get_user_info($this->user_id);
+        if (isset($my_category[0]) &&
+            $my_category[0]->is_certificate_available($this->user_id)
+        ) {
+            $user = api_get_user_info($this->user_id);
             $scoredisplay = ScoreDisplay :: instance();
-            $scorecourse  = $my_category[0]->calc_score($this->user_id);
-
-            $scorecourse_display = (isset($scorecourse) ? $scoredisplay->display_score($scorecourse,SCORE_AVERAGE) : get_lang('NoResultsAvailable'));
+            $scorecourse = $my_category[0]->calc_score($this->user_id);
+            $scorecourse_display = isset($scorecourse) ? $scoredisplay->display_score($scorecourse,SCORE_AVERAGE) : get_lang('NoResultsAvailable');
 
-            //Prepare all necessary variables:
-            $organization_name     = api_get_setting('Institution');
+            // Prepare all necessary variables:
+            $organization_name = api_get_setting('Institution');
             //$portal_name         = api_get_setting('siteName');
-            $stud_fn             = $user['firstname'];
-            $stud_ln             = $user['lastname'];
+            $stud_fn = $user['firstname'];
+            $stud_ln = $user['lastname'];
 
             //@todo this code is not needed
-            $certif_text         = sprintf(get_lang('CertificateWCertifiesStudentXFinishedCourseYWithGradeZ'), $organization_name, $stud_fn.' '.$stud_ln, $my_category[0]->get_name(), $scorecourse_display);
-            $certif_text         = str_replace("\\n","\n", $certif_text);
+            $certif_text = sprintf(
+                get_lang('CertificateWCertifiesStudentXFinishedCourseYWithGradeZ'),
+                $organization_name, $stud_fn.' '.$stud_ln, $my_category[0]->get_name(),
+                $scorecourse_display
+            );
+            $certif_text = str_replace("\\n","\n", $certif_text);
 
             //If the gradebook is related to skills we added the skills to the user
 
             $skill = new Skill();
-            $skill->add_skill_to_user($this->user_id, $this->certificate_data['cat_id']);
+            $skill->add_skill_to_user(
+                $this->user_id,
+                $this->certificate_data['cat_id']
+            );
 
             if (is_dir($this->certification_user_path)) {
                 if (!empty($this->certificate_data)) {
-                    $new_content_html = get_user_certificate_content($this->user_id, $my_category[0]->get_course_code(), false, $params['hide_print_button']);
+                    $new_content_html = get_user_certificate_content(
+                        $this->user_id,
+                        $my_category[0]->get_course_code(),
+                        false,
+                        $params['hide_print_button']
+                    );
 
                     if ($my_category[0]->get_id() == strval(intval($this->certificate_data['cat_id']))) {
                         $name = $this->certificate_data['path_certificate'];
                         $my_path_certificate = $this->certification_user_path.basename($name);
-                        if (file_exists($my_path_certificate) && !empty($name) && !is_dir($my_path_certificate) && $this->force_certificate_generation == false) {
+                        if (file_exists($my_path_certificate) &&
+                            !empty($name) &&
+                            !is_dir($my_path_certificate) &&
+                            $this->force_certificate_generation == false
+                        ) {
                             //Seems that the file was already generated
                             return true;
                         } else {
-                            //Creating new name
-                            $name    = md5($this->user_id.$this->certificate_data['cat_id']).'.html';
+                            // Creating new name
+                            $name = md5($this->user_id.$this->certificate_data['cat_id']).'.html';
                             $my_path_certificate = $this->certification_user_path.$name;
                             $path_certificate    ='/'.$name;
 
@@ -190,13 +218,21 @@ class Certificate extends Model
                             $file_info = pathinfo($path_certificate);
                             $qr_code_filename = $this->certification_user_path.$file_info['filename'].'_qr.png';
 
-                            $my_new_content_html = str_replace('((certificate_barcode))', Display::img($this->certification_web_user_path.$file_info['filename'].'_qr.png', 'QR'), $new_content_html['content']);
+                            $my_new_content_html = str_replace(
+                                '((certificate_barcode))',
+                                Display::img($this->certification_web_user_path.$file_info['filename'].'_qr.png', 'QR'),
+                                $new_content_html['content']
+                            );
                             $my_new_content_html = mb_convert_encoding($my_new_content_html,'UTF-8', api_get_system_encoding());
 
                             $result = @file_put_contents($my_path_certificate, $my_new_content_html);
                             if ($result) {
                                 //Updating the path
-                                self::update_user_info_about_certificate($this->certificate_data['cat_id'], $this->user_id, $path_certificate);
+                                self::update_user_info_about_certificate(
+                                    $this->certificate_data['cat_id'],
+                                    $this->user_id,
+                                    $path_certificate
+                                );
                                 $this->certificate_data['path_certificate'] = $path_certificate;
 
                                 if ($this->html_file_is_generated()) {
@@ -206,24 +242,29 @@ class Certificate extends Model
                                     }
                                 }
                             }
+
                             return $result;
                         }
                     }
                 }
             }
         }
+
         return false;
     }
 
     /**
     * update user info about certificate
-    * @param int The category id
-    * @param int The user id
-    * @param string the path name of the certificate
+    * @param int $cat_id category id
+    * @param int $user_id user id
+    * @param string $path_certificate the path name of the certificate
     * @return void()
     */
-    public function update_user_info_about_certificate ($cat_id,$user_id,$path_certificate)
-    {
+    public function update_user_info_about_certificate(
+        $cat_id,
+        $user_id,
+        $path_certificate
+    ) {
         $table_certificate = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
         if (!UserManager::is_user_certified($cat_id,$user_id)) {
             $sql='UPDATE '.$table_certificate.' SET path_certificate="'.Database::escape_string($path_certificate).'"
@@ -233,7 +274,6 @@ class Certificate extends Model
     }
 
     /**
-     *
      * Check if the file was generated
      *
      * @return boolean
@@ -254,8 +294,8 @@ class Certificate extends Model
 
     /**
      * Generates a QR code for the certificate. The QR code embeds the text given
-     * @param    string    Text to be added in the QR code
-     * @param    string    file path of the image
+     * @param    string    $text Text to be added in the QR code
+     * @param    string    $path file path of the image
      * */
     public function generate_qr($text, $path)
     {
@@ -271,7 +311,8 @@ class Certificate extends Model
     /**
      * Transforms certificate tags into text values. This function is very static
      * (it doesn't allow for much flexibility in terms of what tags are printed).
-     * @param array Contains two array entris: first are the headers, second is an array of contents
+     * @param array $array Contains two array entris: first are the headers,
+     * second is an array of contents
      * @return string The translated string
      */
     public function parse_certificate_variables($array)

+ 34 - 16
main/inc/lib/course.lib.php

@@ -3585,6 +3585,12 @@ class CourseManager
         return $html;
     }
 
+    /**
+     * @param string $main_content
+     * @param string $sub_content
+     * @param string $sub_sub_content
+     * @return string
+     */
     public static function course_item_parent($main_content, $sub_content, $sub_sub_content = null)
     {
         return '<div class="well">'.$main_content.$sub_content.$sub_sub_content.'</div>';
@@ -3597,7 +3603,7 @@ class CourseManager
      * in the sense that any user clicking them is registered as a student
      * @param int       User id
      * @param bool      Whether to show the document quick-loader or not
-     * @return void
+     * @return string
      */
     public static function display_special_courses($user_id, $load_dirs = false)
     {
@@ -3702,7 +3708,7 @@ class CourseManager
      * @uses display_courses_in_category() to display the courses themselves
      * @param int        user id
      * @param bool      Whether to show the document quick-loader or not
-     * @return void
+     * @return string
      */
     public static function display_courses($user_id, $load_dirs = false)
     {
@@ -3740,7 +3746,7 @@ class CourseManager
      *  class userportal-course-item.
      *  @param int      User category id
      * @param bool      Whether to show the document quick-loader or not
-     *  @return void
+     *  @return string
      */
     public static function display_courses_in_category($user_category_id, $load_dirs = false)
     {
@@ -3748,7 +3754,7 @@ class CourseManager
         // Table definitions
         $TABLECOURS = Database :: get_main_table(TABLE_MAIN_COURSE);
         $TABLECOURSUSER = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
-        $TABLE_ACCESS_URL_REL_COURSE    = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
+        $TABLE_ACCESS_URL_REL_COURSE = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
         $current_url_id = api_get_current_access_url_id();
 
         // Get course list auto-register
@@ -3862,18 +3868,23 @@ class CourseManager
 
             $course_title_url = '';
             if ($course_info['visibility'] != COURSE_VISIBILITY_CLOSED || $course['status'] == COURSEMANAGER) {
-                $course_title_url = api_get_path(WEB_COURSE_PATH).$course_info['path'].'/?id_session=0';
+                $course_title_url = api_get_path(WEB_COURSE_PATH).$course_info['path'].'/index.php?id_session=0';
                 $course_title = Display::url($course_info['title'], $course_title_url);
             } else {
-                $course_title = $course_info['title']." ".Display::tag('span',get_lang('CourseClosed'), array('class'=>'item_closed'));
+                $course_title = $course_info['title']." ".Display::tag('span', get_lang('CourseClosed'), array('class'=>'item_closed'));
             }
 
             // Start displaying the course block itself
             if (api_get_setting('display_coursecode_in_courselist') == 'true') {
                 $course_title .= ' ('.$course_info['visual_code'].') ';
             }
+
             if (api_get_setting('display_teacher_in_courselist') == 'true') {
-                $teachers = CourseManager::get_teacher_list_from_course_code_to_string($course['code'], self::USER_SEPARATOR, true);
+                $teachers = CourseManager::get_teacher_list_from_course_code_to_string(
+                    $course['code'],
+                    self::USER_SEPARATOR,
+                    true
+                );
             }
 
             $params['link'] = $course_title_url;
@@ -3885,11 +3896,11 @@ class CourseManager
                 $params['notifications'] = $show_notification;
             }
 
-            $is_subcontent = true;
+            $isSubcontent = true;
             if (empty($user_category_id)) {
-                $is_subcontent = false;
+                $isSubcontent = false;
             }
-            $html .= self::course_item_html($params, $is_subcontent);
+            $html .= self::course_item_html($params, $isSubcontent);
         }
 
         return $html;
@@ -3914,18 +3925,25 @@ class CourseManager
     }
 
     /**
-     * Get the course id based on the original id and field name in the extra fields. Returns 0 if course was not found
+     * Get the course id based on the original id and field name in the extra fields.
+     * Returns 0 if course was not found
      *
-     * @param string Original course code
-     * @param string Original field name
+     * @param string $original_course_id_value Original course code
+     * @param string $original_course_id_name Original field name
      * @return int Course id
      */
     public static function get_course_id_from_original_id($original_course_id_value, $original_course_id_name)
     {
         $t_cfv = Database::get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES);
         $table_field = Database::get_main_table(TABLE_MAIN_COURSE_FIELD);
-        $sql_course = "SELECT course_code FROM $table_field cf INNER JOIN $t_cfv cfv ON cfv.field_id=cf.id WHERE field_variable='$original_course_id_name' AND field_value='$original_course_id_value'";
-        $res = Database::query($sql_course);
+        $original_course_id_name = Database::escape_string($original_course_id_name);
+        $original_course_id_name = Database::escape_string($original_course_id_name);
+        $sql = "SELECT course_code FROM $table_field cf
+                INNER JOIN $t_cfv cfv ON cfv.field_id=cf.id
+                WHERE
+                    field_variable='$original_course_id_name' AND
+                    field_value='$original_course_id_value'";
+        $res = Database::query($sql);
         $row = Database::fetch_object($res);
         if ($row != false) {
             return $row->course_code;
@@ -4589,7 +4607,7 @@ class CourseManager
      * @param int $url_id
      *
      */
-    public function remove_course_ranking($course_id, $session_id, $url_id = null)
+    public static function remove_course_ranking($course_id, $session_id, $url_id = null)
     {
         $table_course_ranking = Database::get_main_table(TABLE_STATISTIC_TRACK_COURSE_RANKING);
         $table_user_course_vote = Database::get_main_table(TABLE_MAIN_USER_REL_COURSE_VOTE);

+ 3 - 3
main/inc/lib/course_category.lib.php

@@ -101,7 +101,7 @@ function addNode($code, $name, $canHaveCourses, $parent_id)
     $tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
     $code = trim(Database::escape_string($code));
     $name = trim(Database::escape_string($name));
-    $parent_id = intval($parent_id);
+    $parent_id = trim(Database::escape_string($parent_id));
     $canHaveCourses = Database::escape_string($canHaveCourses);
     $code = generate_course_code($code);
 
@@ -109,7 +109,6 @@ function addNode($code, $name, $canHaveCourses, $parent_id)
     if (Database::num_rows($result)) {
         return false;
     }
-
     $result = Database::query("SELECT MAX(tree_pos) AS maxTreePos FROM $tbl_category");
     $row = Database::fetch_array($result);
     $tree_pos = $row['maxTreePos'] + 1;
@@ -142,7 +141,8 @@ function updateCategoryChildren($category)
     }
 
     $children_count = compterFils($category, 0) - 1;
-    Database::query("UPDATE $tbl_category SET children_count='$children_count' WHERE code='$category'");
+    $sql = "UPDATE $tbl_category SET children_count='$children_count' WHERE code='$category'";
+    Database::query($sql);
 }
 
 /**

+ 1 - 18
main/inc/lib/dashboard.lib.php

@@ -512,24 +512,7 @@ class DashboardManager
 	 */
 	public static function get_links_for_styles_from_dashboard_plugins() {
 
-		$possible_paths = self::get_posible_dashboard_plugins_path();
-		$enabled_blocks = self::get_enabled_dashboard_blocks();
-		$links = '';
-		foreach ($enabled_blocks as $block) {
-			$path = $block['path'];
-			$dashboard_plugin_path = api_get_path(SYS_PLUGIN_PATH).'dashboard/'.$path.'/css/';
-			if (is_dir($dashboard_plugin_path)) {
-				$handle = @opendir($dashboard_plugin_path);
-				while (false !== ($file = readdir($handle))) {
-					if ($file <> '.' AND $file <> '..') {
-						$src = api_get_path(WEB_PLUGIN_PATH).'dashboard/'.$path.'/css/'.$file;
-						$links .= '<link rel="stylesheet" href="'.$src.'" type="text/css" />'.PHP_EOL;
-					}
-				}
-				@closedir($handle);
-			}
-		}
-		return $links;
+		return '<link rel="stylesheet" href="'.api_get_path(WEB_PLUGIN_PATH).'dashboard/css/default.css" type="text/css" />'.PHP_EOL;
 	}
 
 }

+ 5 - 3
main/inc/lib/database.lib.php

@@ -465,16 +465,18 @@ class Database
      * @param resource  $connection (optional)   The database server connection, for detailed description see the method query().
      * @param bool $addFix
      * @return string   he escaped string
-     * @author Yannick Warnier <yannick.warnier@dokeos.com>
+     * @author Yannick Warnier <yannick.warnier@beeznest.com>
      * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
      */
     public static function escape_string($string, $connection = null, $addFix = true)
     {
         // Fixes security problem when there's no "" or '' between a variable.
         // See #7440 for more info
+        /*
         if ($addFix) {
             //$string = "__@$string@__";
         }
+        */
         return get_magic_quotes_gpc()
             ? (self::use_default_connection($connection)
                 ? mysql_real_escape_string(stripslashes($string))
@@ -514,7 +516,7 @@ class Database
      * @param   string      Optional class name to instanciate
      * @param   array       Optional array of parameters
      * @return  object      Object of class StdClass or the required class, containing the query result row
-     * @author  Yannick Warnier <yannick.warnier@dokeos.com>
+     * @author  Yannick Warnier <yannick.warnier@beeznest.com>
      */
     public static function fetch_object($result, $class = null, $params = null) {
         return !empty($class) ? (is_array($params) ? mysql_fetch_object($result, $class, $params) : mysql_fetch_object($result, $class)) : mysql_fetch_object($result);
@@ -663,7 +665,7 @@ class Database
      * Gets the number of rows from the last query result - help achieving database independence
      * @param resource      The result
      * @return integer      The number of rows contained in this result
-     * @author Yannick Warnier <yannick.warnier@dokeos.com>
+     * @author Yannick Warnier <yannick.warnier@beeznest.com>
      **/
     public static function num_rows($result) {
         return is_resource($result) ? mysql_num_rows($result) : false;

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

@@ -27,7 +27,7 @@ class Diagnoser
 
         $sections = array('chamilo', 'php', 'mysql', 'webserver');
 
-        if (!in_array($_GET['section'], $sections)) {
+        if (!in_array(trim($_GET['section']), $sections)) {
             $current_section = 'chamilo';
         } else {
             $current_section = $_GET['section'];

+ 15 - 4
main/inc/lib/display.lib.php

@@ -142,7 +142,13 @@ class Display
         echo self::return_introduction_section($tool, $editor_config);
     }
 
-    public static function return_introduction_section($tool, $editor_config = null) {
+    /**
+     * @param string $tool
+     * @param array $editor_config
+     * @return null
+     */
+    public static function return_introduction_section($tool, $editor_config = null)
+    {
         $is_allowed_to_edit = api_is_allowed_to_edit();
         $moduleId = $tool;
         if (api_get_setting('enable_tool_introduction') == 'true' || $tool == TOOL_COURSE_HOMEPAGE) {
@@ -826,7 +832,8 @@ class Display
     public static function url($name, $url, $extra_attributes = array())
     {
         if (!empty($url)) {
-            $extra_attributes['href']= $url;
+            $url = htmlspecialchars($url, ENT_QUOTES, 'UTF-8');
+            $extra_attributes['href'] = $url;
         }
         return self::tag('a', $name, $extra_attributes);
     }
@@ -1789,16 +1796,20 @@ class Display
      * @param array $items
      * @return null|string
      */
-    public static function actions($items)
+    public static function actions($items, $class = 'new_actions')
     {
         $html = null;
         if (!empty($items)) {
-            $html = '<div class="new_actions"><ul class="nav nav-pills">';
+            $html = '<div class="'.$class.'"><ul class="nav nav-pills">';
             foreach ($items as $value) {
                 $class = null;
                 if (isset($value['active']) && $value['active']) {
                     $class = 'class ="active"';
                 }
+
+                if (basename($_SERVER['REQUEST_URI']) == basename($value['url']) ) {
+                    $class = 'class ="active"';
+                }
                 $html .= "<li $class >";
                 $html .= self::url($value['content'], $value['url']);
                 $html .= '</li>';

+ 25 - 6
main/inc/lib/document.lib.php

@@ -3223,7 +3223,7 @@ class DocumentManager
                 if (CourseManager::is_user_subscribed_in_course($user_id, $course_info['code'])) {
                     $user_in_course = true;
                 }
-                //Check if course is open then we can consider that the student is regitered to the course
+                // Check if course is open then we can consider that the student is registered to the course
                 if (isset($course_info) && in_array($course_info['visibility'], array(2, 3))) {
                     $user_in_course = true;
                 }
@@ -3261,6 +3261,13 @@ class DocumentManager
 
         $folderCondition = " AND docs.path LIKE '/%' ";
 
+        if (!api_is_allowed_to_edit()) {
+            $protectedFolders = self::getProtectedFolderFromStudent();
+            foreach ($protectedFolders as $folder) {
+                $folderCondition .= " AND docs.path NOT LIKE '$folder' ";
+            }
+        }
+
         if ($folderId !== false) {
             $parentData = self::get_document_data_by_id($folderId, $course_info['code']);
             if (!empty($parentData)) {
@@ -3443,7 +3450,6 @@ class DocumentManager
                         });
                     }
     		    }
-
             }
     		</script>";
         }
@@ -3702,10 +3708,10 @@ class DocumentManager
                             $overwrite_url
                         );
                     }
-
                 }
             }
         }
+
         return $return;
     }
 
@@ -4178,9 +4184,9 @@ class DocumentManager
     /**
      * @return array
      */
-    static function get_system_folders()
+    public static function get_system_folders()
     {
-        $system_folders = array(
+        return array(
             '/certificates',
             '/HotPotatoes_files',
             '/chat_files',
@@ -4191,7 +4197,20 @@ class DocumentManager
             '/shared_folder',
             '/learning_path'
         );
-        return $system_folders;
+    }
+
+    /**
+     * @return array
+     */
+    public static function getProtectedFolderFromStudent()
+    {
+        return array(
+            '/certificates',
+            '/HotPotatoes_files',
+            '/chat_files',
+            '/shared_folder',
+            '/learning_path'
+        );
     }
 
     /**

+ 54 - 19
main/inc/lib/events.lib.inc.php

@@ -910,40 +910,67 @@ function get_attempt_count_not_finished($user_id, $exerciseId, $lp_id, $lp_item_
  */
 function delete_student_lp_events($user_id, $lp_id, $course, $session_id)
 {
-    $lp_view_table         = Database::get_course_table(TABLE_LP_VIEW);
-    $lp_item_view_table    = Database::get_course_table(TABLE_LP_ITEM_VIEW);
-    $course_id 			   = $course['real_id'];
+    $lp_view_table = Database::get_course_table(TABLE_LP_VIEW);
+    $lp_item_view_table = Database::get_course_table(TABLE_LP_ITEM_VIEW);
+    $lpInteraction = Database::get_course_table(TABLE_LP_IV_INTERACTION);
+    $lpObjective = Database::get_course_table(TABLE_LP_IV_OBJECTIVE);
+
+    $course_id = $course['real_id'];
 
     if (empty($course_id)) {
         $course_id = api_get_course_int_id();
     }
 
-    $track_e_exercises     = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
-    $track_attempts        = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
-    $recording_table       = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING);
-
-    $user_id               = intval($user_id);
-    $lp_id                 = intval($lp_id);
-    $session_id            = intval($session_id);
+    $track_e_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
+    $track_attempts = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
+    $recording_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING);
+    $user_id = intval($user_id);
+    $lp_id = intval($lp_id);
+    $session_id = intval($session_id);
 
     //Make sure we have the exact lp_view_id
     $sql = "SELECT id FROM $lp_view_table
-            WHERE c_id = $course_id AND user_id = $user_id AND lp_id = $lp_id AND session_id = $session_id ";
-    $result    = Database::query($sql);
+            WHERE
+                c_id = $course_id AND
+                user_id = $user_id AND
+                lp_id = $lp_id AND
+                session_id = $session_id ";
+    $result = Database::query($sql);
 
     if (Database::num_rows($result)) {
-        $view          = Database::fetch_array($result, 'ASSOC');
-        $lp_view_id    = $view['id'];
-        $sql = "DELETE FROM $lp_item_view_table WHERE c_id = $course_id AND lp_view_id = $lp_view_id ";
+        $view = Database::fetch_array($result, 'ASSOC');
+        $lp_view_id = $view['id'];
+        $sql = "DELETE FROM $lp_item_view_table
+                WHERE c_id = $course_id AND lp_view_id = $lp_view_id ";
+        Database::query($sql);
+
+        $sql = "DELETE FROM $lpInteraction
+                WHERE c_id = $course_id AND lp_iv_id = $lp_view_id ";
+        Database::query($sql);
+
+        $sql = "DELETE FROM $lpObjective
+                WHERE c_id = $course_id AND lp_iv_id = $lp_view_id ";
         Database::query($sql);
     }
 
-    $sql = "DELETE FROM $lp_view_table WHERE c_id = $course_id AND user_id = $user_id AND lp_id= $lp_id AND session_id = $session_id ";
+    $sql = "DELETE FROM $lp_view_table
+            WHERE
+                c_id = $course_id AND
+                user_id = $user_id AND
+                lp_id= $lp_id AND
+                session_id = $session_id
+            ";
     Database::query($sql);
 
     $sql = "SELECT exe_id FROM $track_e_exercises
-            WHERE exe_user_id = $user_id AND session_id = $session_id  AND exe_cours_id = '{$course['code']}' AND orig_lp_id = $lp_id";
-    $result    = Database::query($sql);
+            WHERE
+                exe_user_id = $user_id AND
+                session_id = $session_id AND
+                exe_cours_id = '{$course['code']}' AND
+                orig_lp_id = $lp_id
+            ";
+
+    $result = Database::query($sql);
     $exe_list = array();
     while ($row = Database::fetch_array($result, 'ASSOC')) {
         $exe_list[] = $row['exe_id'];
@@ -959,7 +986,15 @@ function delete_student_lp_events($user_id, $lp_id, $course, $session_id)
         $sql = "DELETE FROM $recording_table WHERE exe_id IN (".implode(',',$exe_list).")";
         Database::query($sql);
     }
-    event_system(LOG_LP_ATTEMPT_DELETE, LOG_LP_ID, $lp_id, null, null, $course['code'], $session_id);
+    event_system(
+        LOG_LP_ATTEMPT_DELETE,
+        LOG_LP_ID,
+        $lp_id,
+        null,
+        null,
+        $course['code'],
+        $session_id
+    );
 }
 
 /**

+ 22 - 0
main/inc/lib/fckeditor/editor/plugins/Abbr/lang/nl.js

@@ -0,0 +1,22 @@
+/*
+ * FCKeditor - The text editor for internet
+ * Copyright (C) 2003-2005 Frederico Caldeira Knabben
+ * 
+ * Licensed under the terms of the GNU Lesser General Public License:
+ *    http://www.opensource.org/licenses/lgpl-license.php
+ * 
+ * For further information visit:
+ *    http://www.fckeditor.net/
+ * 
+ * File Name: en.js
+ *  Abbr English language file.
+ *  Changes for Chamilo corrections
+ * 
+ */
+FCKLang.Abbr	      		= 'Corrections' ;
+FCKLang.AbbrBtn      		= 'Insert/Remove corrections' ;
+FCKLang.AbbrDlgTitle 		= 'Insert/Remove corrections' ;
+FCKLang.AbbrDlgName  		= 'Please insert a comment:' ;
+FCKLang.AbbrDlgTxt   		= 'Correction gets visible while mouseover with cursor [<abbr title="This word is a mispelling">This is the correction appearance</abbr>]';
+FCKLang.AbbrDlgRemove		= 'Remove correction';
+FCKLang.AbbrDlgSelectFirst	= 'You have to select text first!';

+ 2 - 2
main/inc/lib/fckeditor/editor/plugins/ajaxfilemanager/ajax_get_file_listing.php

@@ -19,13 +19,13 @@ if (!isset($manager)) {
     $pagination    = new pagination(false);
     $search_folder = null;
     if (isset($_GET['search_folder'])) {
-        $search_folder = str_replace("'", "", $_GET['search_folder']); //security fix for Chamilo by cfasanando
+        $search_folder = str_replace("'", "", Security::remove_XSS($_GET['search_folder']));
     }
 
     if (!empty($_GET['search'])) {
         include_once(CLASS_SEARCH);
 
-        $search = new Search($search_folder); //security fix for Chamilo by cfasanando
+        $search = new Search($search_folder);
         $search->addSearchKeyword('recursive', @$_GET['search_recursively']);
         $search->addSearchKeyword('mtime_from', @$_GET['search_mtime_from']);
         $search->addSearchKeyword('mtime_to', @$_GET['search_mtime_to']);

+ 3 - 3
main/inc/lib/fckeditor/fcktemplates.xml.php

@@ -177,8 +177,8 @@ function load_platform_templates() {
     $certificateTemplateContent = file_get_contents(api_get_path(SYS_PATH) . 'main/gradebook/certificate_template/template.html');
     $certificateTemplateHTML = str_replace($search, $replace, $certificateTemplateContent);
 
-    echo '<Template title="TemplateCertificateTitle" image="' . "$certificateTemplateThumb" . '">'
-    . '<Description>TemplateCertificateDescription</Description>'
+    echo '<Template title="'.get_lang('TemplateCertificateTitle').'" image="' . "$certificateTemplateThumb" . '">'
+    . '<Description>'. get_lang('TemplateCertificateComment') . '</Description>'
     . '<Html>'
     . '<![CDATA['
     . $certificateTemplateHTML
@@ -356,4 +356,4 @@ function load_student_templates() {
         </Html>
     </Template>
     <?php
-}
+}

+ 74 - 72
main/inc/lib/fileUpload.lib.php

@@ -1518,100 +1518,102 @@ function create_unexisting_directory(
     }
 
     if (!is_dir($base_work_dir.$systemFolderName)) {
-        mkdir(
+        $result = mkdir(
             $base_work_dir.$systemFolderName,
             api_get_permissions_for_new_directories(),
             true
         );
 
-        // Check if pathname already exists inside document table
-        $tbl_document = Database::get_course_table(TABLE_DOCUMENT);
-        $sql = "SELECT id, path FROM $tbl_document
-		        WHERE
-		            c_id = $course_id AND
-		            (
-		                path = '".$systemFolderName."'
-                    )
-        ";
+        if ($result) {
 
-        $rs = Database::query($sql);
-        if (Database::num_rows($rs) == 0) {
+            // Check if pathname already exists inside document table
+            $tbl_document = Database::get_course_table(TABLE_DOCUMENT);
+            $sql = "SELECT id, path FROM $tbl_document
+                    WHERE
+                        c_id = $course_id AND
+                        (
+                            path = '" . $systemFolderName . "'
+                        )
+            ";
 
-            $document_id = add_document(
-                $_course,
-                $systemFolderName,
-                'folder',
-                0,
-                $title,
-                null,
-                0,
-                true,
-                $to_group_id
-            );
+            $rs = Database::query($sql);
+            if (Database::num_rows($rs) == 0) {
 
-            if ($document_id) {
-                // Update document item_property
-                if (!empty($visibility)) {
+                $document_id = add_document(
+                    $_course,
+                    $systemFolderName,
+                    'folder',
+                    0,
+                    $title,
+                    null,
+                    0,
+                    true,
+                    $to_group_id
+                );
 
-                    $visibilities = array(
-                        0 => 'invisible',
-                        1 => 'visible',
-                        2 => 'delete'
-                    );
-                    api_item_property_update(
-                        $_course,
-                        TOOL_DOCUMENT,
-                        $document_id,
-                        $visibilities[$visibility],
-                        $user_id,
-                        $to_group_id,
-                        $to_user_id,
-                        null,
-                        null,
-                        $session_id
-                    );
-                } else {
-                    api_item_property_update(
-                        $_course,
-                        TOOL_DOCUMENT,
+                if ($document_id) {
+                    // Update document item_property
+                    if (!empty($visibility)) {
+
+                        $visibilities = array(
+                            0 => 'invisible',
+                            1 => 'visible',
+                            2 => 'delete'
+                        );
+                        api_item_property_update(
+                            $_course,
+                            TOOL_DOCUMENT,
+                            $document_id,
+                            $visibilities[$visibility],
+                            $user_id,
+                            $to_group_id,
+                            $to_user_id,
+                            null,
+                            null,
+                            $session_id
+                        );
+                    } else {
+                        api_item_property_update(
+                            $_course,
+                            TOOL_DOCUMENT,
+                            $document_id,
+                            'FolderCreated',
+                            $user_id,
+                            $to_group_id,
+                            $to_user_id,
+                            null,
+                            null,
+                            $session_id
+                        );
+                    }
+
+                    $documentData = DocumentManager::get_document_data_by_id(
                         $document_id,
-                        'FolderCreated',
-                        $user_id,
-                        $to_group_id,
-                        $to_user_id,
-                        null,
-                        null,
+                        $_course['code'],
+                        false,
                         $session_id
                     );
+
+                    return $documentData;
                 }
+            } else {
+                $document = Database::fetch_array($rs);
                 $documentData = DocumentManager::get_document_data_by_id(
-                    $document_id,
+                    $document['id'],
                     $_course['code'],
                     false,
                     $session_id
                 );
-                return $documentData;
-            } else {
-                return false;
-            }
-        } else {
-            $document = Database::fetch_array($rs);
-            $documentData = DocumentManager::get_document_data_by_id(
-                $document['id'],
-                $_course['code'],
-                false,
-                $session_id
-            );
 
-            /* This means the folder NOT exist in the filesystem
-             (now this was created) but there is a record in the Database*/
+                /* This means the folder NOT exist in the filesystem
+                 (now this was created) but there is a record in the Database*/
 
-            return $documentData;
+                return $documentData;
+            }
         }
-    } else {
-
-        return false;
     }
+
+    return false;
 }
 
 /**

+ 8 - 1
main/inc/lib/formvalidator/FormValidator.class.php

@@ -556,12 +556,19 @@ EOT;
      * @return string $return_value HTML code of the form
      *
      * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, august 2006
+     * @author Julio Montoya
      */
     public function return_form()
     {
         $error = false;
         $addDateLibraries = false;
-        $dateElementTypes = array('date_range_picker', 'date_time_picker', 'date_picker', 'datepicker', 'datetimepicker');
+        $dateElementTypes = array(
+            'date_range_picker',
+            'date_time_picker',
+            'date_picker',
+            'datepicker',
+            'datetimepicker'
+        );
         /** @var HTML_QuickForm_element $element */
         foreach ($this->_elements as $element) {
             if (in_array($element->getType(), $dateElementTypes)) {

+ 124 - 51
main/inc/lib/groupmanager.lib.php

@@ -84,34 +84,31 @@ class GroupManager
      */
     public static function get_group_list($category = null, $course_code = null)
     {
-        $my_user_id = api_get_user_id();
         $course_info = api_get_course_info($course_code);
+        $session_id = api_get_session_id();
 
         $course_id = $course_info['real_id'];
         $table_group_user = Database :: get_course_table(TABLE_GROUP_USER);
         $table_group = Database :: get_course_table(TABLE_GROUP);
 
-        //condition for the session
-        $session_id = api_get_session_id();
-
         $sql = "SELECT g.id,
-                        g.name,
-                        g.description,
-                        g.category_id,
-                        g.max_student maximum_number_of_members,
-                        g.secret_directory,
-                        g.self_registration_allowed,
-                        g.self_unregistration_allowed,
-                        g.session_id,
-                        ug.user_id is_member
-                    FROM $table_group g
-                    LEFT JOIN $table_group_user ug
-                    ON (
-                        ug.group_id = g.id AND
-                        ug.user_id = '".api_get_user_id()."' AND
-                        ug.c_id = $course_id AND
-                        g.c_id = $course_id
-                    )";
+                    g.name,
+                    g.description,
+                    g.category_id,
+                    g.max_student maximum_number_of_members,
+                    g.secret_directory,
+                    g.self_registration_allowed,
+                    g.self_unregistration_allowed,
+                    g.session_id,
+                    ug.user_id is_member
+                FROM $table_group g
+                LEFT JOIN $table_group_user ug
+                ON (
+                    ug.group_id = g.id AND
+                    ug.user_id = '".api_get_user_id()."' AND
+                    ug.c_id = $course_id AND
+                    g.c_id = $course_id
+                )";
 
         $sql .= " WHERE 1=1 ";
 
@@ -377,7 +374,7 @@ class GroupManager
     }
 
     /**
-     * deletes groups and their data.
+     * Deletes groups and their data.
      * @author Christophe Gesche <christophe.gesche@claroline.net>
      * @author Hugues Peeters <hugues.peeters@claroline.net>
      * @author Bart Mollet
@@ -389,11 +386,11 @@ class GroupManager
     public static function delete_groups($group_ids, $course_code = null)
     {
         $course_info = api_get_course_info($course_code);
-        $course_id     = $course_info['real_id'];
+        $course_id = $course_info['real_id'];
 
         // Database table definitions
-        $group_table             = Database :: get_course_table(TABLE_GROUP);
-        $forum_table             = Database :: get_course_table(TABLE_FORUM);
+        $group_table = Database:: get_course_table(TABLE_GROUP);
+        $forum_table = Database:: get_course_table(TABLE_FORUM);
 
         $group_ids = is_array($group_ids) ? $group_ids : array ($group_ids);
         $group_ids = array_map('intval',$group_ids);
@@ -413,6 +410,8 @@ class GroupManager
 
         // Unsubscribe all users
         self :: unsubscribe_all_users($group_ids);
+        self ::unsubscribe_all_tutors($group_ids);
+
         $sql = "SELECT id, secret_directory, session_id FROM $group_table
                 WHERE c_id = $course_id AND id IN (".implode(' , ', $group_ids).")";
         $db_result = Database::query($sql);
@@ -1084,6 +1083,8 @@ class GroupManager
         $sql = "SELECT user_id FROM $tutor_user_table
                 WHERE c_id = $course_id AND group_id = $group_id";
         $res = Database::query($sql);
+
+        $users = array();
         while ($obj = Database::fetch_object($res)) {
             $users[] = api_get_user_info($obj->user_id);
         }
@@ -1524,10 +1525,10 @@ class GroupManager
     }
 
     /**
-     * Subscribe user(s) to a specified group in current course
+     * Subscribe user(s) to a specified group in current course (as a student)
      * @param mixed $user_ids Can be an array with user-id's or a single user-id
      * @param int $group_id
-     * @return bool TRUE if successfull
+     * @return bool TRUE if successful
      */
     public static function subscribe_users($user_ids, $group_id)
     {
@@ -1567,9 +1568,11 @@ class GroupManager
         foreach ($user_ids as $user_id) {
             $user_id = intval($user_id);
             $group_id = intval($group_id);
-            $sql = "INSERT INTO ".$table_group_tutor." (c_id, user_id, group_id)
-                    VALUES ('$course_id', '".$user_id."', '".$group_id."')";
-            $result &= Database::query($sql);
+            if (self::can_user_subscribe($user_id, $group_id)) {
+                $sql = "INSERT INTO " . $table_group_tutor . " (c_id, user_id, group_id)
+                    VALUES ('$course_id', '" . $user_id . "', '" . $group_id . "')";
+                $result &= Database::query($sql);
+            }
         }
         return $result;
     }
@@ -2266,7 +2269,6 @@ class GroupManager
     }
 
     /**
-     *
      * @param array $groupData
      * @param bool $deleteNotInArray
      * @return array
@@ -2404,6 +2406,27 @@ class GroupManager
                     $data['group_id'] = $groupId;
                     $result['updated']['group'][] = $data;
                 }
+
+                $students = isset($data['students']) ? explode(',', $data['students']) : null;
+                if (!empty($students)) {
+                    $studentUserIdList = array();
+                    foreach ($students as $student) {
+                        $userInfo = api_get_user_info_from_username($student);
+                        $studentUserIdList[] = $userInfo['user_id'];
+                    }
+                    self::subscribe_users($studentUserIdList, $groupId);
+                }
+
+                $tutors = isset($data['tutors']) ? explode(',', $data['tutors']) : null;
+                if (!empty($tutors)) {
+                    $tutorIdList = array();
+                    foreach ($tutors as $tutor) {
+                        $userInfo = api_get_user_info_from_username($tutor);
+                        $tutorIdList[] = $userInfo['user_id'];
+                    }
+                    self::subscribe_tutors($tutorIdList, $groupId);
+                }
+
                 $elementsFound['groups'][] = $groupId;
             }
         }
@@ -2434,9 +2457,11 @@ class GroupManager
     /**
      * Export all categories/group from a course to an array.
      * This function works only in a context of a course.
+     * @param int $groupId
+     * @param bool $loadUsers
      * @return array
      */
-    public static function exportCategoriesAndGroupsToArray()
+    public static function exportCategoriesAndGroupsToArray($groupId = null, $loadUsers = false)
     {
         $data = array();
         $data[] = array(
@@ -2456,25 +2481,35 @@ class GroupManager
             'groups_per_user'
         );
 
-        $categories = GroupManager::get_categories();
+        $count = 1;
 
-        foreach ($categories as $categoryInfo) {
-            $data[] = array(
-                $categoryInfo['title'],
-                null,
-                $categoryInfo['description'],
-                $categoryInfo['announcements_state'],
-                $categoryInfo['calendar_state'],
-                $categoryInfo['chat_state'],
-                $categoryInfo['doc_state'],
-                $categoryInfo['forum_state'],
-                $categoryInfo['work_state'],
-                $categoryInfo['wiki_state'],
-                $categoryInfo['max_student'],
-                $categoryInfo['self_reg_allowed'],
-                $categoryInfo['self_unreg_allowed'],
-                $categoryInfo['groups_per_user']
-            );
+        if ($loadUsers) {
+            $data[0][] = 'students';
+            $data[0][] = 'tutors';
+        }
+
+        if ($loadUsers == false) {
+            $categories = GroupManager::get_categories();
+
+            foreach ($categories as $categoryInfo) {
+                $data[$count] = array(
+                    $categoryInfo['title'],
+                    null,
+                    $categoryInfo['description'],
+                    $categoryInfo['announcements_state'],
+                    $categoryInfo['calendar_state'],
+                    $categoryInfo['chat_state'],
+                    $categoryInfo['doc_state'],
+                    $categoryInfo['forum_state'],
+                    $categoryInfo['work_state'],
+                    $categoryInfo['wiki_state'],
+                    $categoryInfo['max_student'],
+                    $categoryInfo['self_reg_allowed'],
+                    $categoryInfo['self_unreg_allowed'],
+                    $categoryInfo['groups_per_user']
+                );
+                $count++;
+            }
         }
 
         $groups = GroupManager::get_group_list();
@@ -2487,7 +2522,31 @@ class GroupManager
                 $categoryTitle = $categoryInfo['title'];
             }
 
-            $data[] = array(
+            $users = GroupManager::getStudents($groupInfo['id']);
+            $userList = array();
+            foreach ($users as $user) {
+                $user = api_get_user_info($user['user_id']);
+                $userList[] = $user['username'];
+            }
+
+            $tutors = GroupManager::getTutors($groupInfo['id']);
+            $tutorList = array();
+            foreach ($tutors as $user) {
+                $user = api_get_user_info($user['user_id']);
+                $tutorList[] = $user['username'];
+            }
+
+            $userListToString = null;
+            if (!empty($userList)) {
+                $userListToString = implode(',', $userList);
+            }
+
+            $tutorListToString = null;
+            if (!empty($tutorList)) {
+                $tutorListToString = implode(',', $tutorList);
+            }
+
+            $data[$count] = array(
                 $categoryTitle,
                 $groupSettings['name'],
                 $groupSettings['description'],
@@ -2501,8 +2560,22 @@ class GroupManager
                 $groupSettings['maximum_number_of_students'],
                 $groupSettings['self_registration_allowed'],
                 $groupSettings['self_unregistration_allowed'],
+                null
             );
+
+            if ($loadUsers) {
+                $data[$count][] = $userListToString;
+                $data[$count][] = $tutorListToString;
+            }
+
+            if (!empty($groupId)) {
+                if ($groupId == $groupInfo['id']) {
+                    break;
+                }
+            }
+            $count++;
         }
+
         return $data;
     }
 

+ 13 - 3
main/inc/lib/internationalization.lib.php

@@ -1011,7 +1011,15 @@ function api_get_months_long($language = null) {
  * @author Carlos Vargas <carlos.vargas@dokeos.com> - initial implementation.
  * @author Ivan Tcholakov
  */
-function api_get_person_name($first_name, $last_name, $title = null, $format = null, $language = null, $encoding = null, $username = null) {
+function api_get_person_name(
+    $first_name,
+    $last_name,
+    $title = null,
+    $format = null,
+    $language = null,
+    $encoding = null,
+    $username = null
+) {
     static $valid = array();
     if (empty($format)) {
         $format = PERSON_NAME_COMMON_CONVENTION;
@@ -1025,6 +1033,7 @@ function api_get_person_name($first_name, $last_name, $title = null, $format = n
     if (empty($encoding)) {
         $encoding = _api_mb_internal_encoding();
     }
+
     if (!isset($valid[$format][$language])) {
         if (is_int($format)) {
             switch ($format) {
@@ -1078,7 +1087,7 @@ function api_get_person_name($first_name, $last_name, $title = null, $format = n
 /**
  * Checks whether a given format represents person name in Western order (for which first name is first).
  * @param int/string $format (optional)	The person name format. It may be a pattern-string (for example '%t. %l, %f') or some of the constants PERSON_NAME_COMMON_CONVENTION (default), PERSON_NAME_WESTERN_ORDER, PERSON_NAME_EASTERN_ORDER, PERSON_NAME_LIBRARY_ORDER.
- * @param string $language (optional)	The language indentificator. If it is omited, the current interface language is assumed. This parameter has meaning with the format PERSON_NAME_COMMON_CONVENTION only.
+ * @param string $language (optional)	The language identificator. If it is omited, the current interface language is assumed. This parameter has meaning with the format PERSON_NAME_COMMON_CONVENTION only.
  * @return bool							The result TRUE means that the order is first_name last_name, FALSE means last_name first_name.
  * Note: You may use this function for determing the order of the fields or columns "First name" and "Last name" in forms, tables and reports.
  * @author Ivan Tcholakov
@@ -2499,7 +2508,8 @@ function api_strcasecmp($string1, $string2, $language = null, $encoding = null)
  * @link http://php.net/manual/en/function.strcmp.php
  * @link http://php.net/manual/en/collator.compare.php
  */
-function api_strcmp($string1, $string2, $language = null, $encoding = null) {
+function api_strcmp($string1, $string2, $language = null, $encoding = null)
+{
     if (INTL_INSTALLED) {
         $collator = _api_get_collator($language);
         if (is_object($collator)) {

+ 0 - 8
main/inc/lib/internationalization_database/name_order_conventions.php

@@ -84,15 +84,7 @@ return array(
 	'simpl_chinese' =>    array('format' => 'title last_name first_name',  'sort_by' => 'last_name' ), // Eastern order
 	'slovak' =>           array('format' => 'title first_name last_name',  'sort_by' => 'first_name'),
 	'slovenian' =>        array('format' => 'title first_name last_name',  'sort_by' => 'first_name'),
-
-	//'spanish' =>          array(  'format' => 'title first_name last_name',  'sort_by' => 'last_name'),
-	//'spanish' =>          array(  'format' => 'title last_name first_name',  'sort_by' => 'last_name'),
-	// Some experimental settings for Spanish language:
-	//'spanish' =>          array(  'format' => 'title first_name LAST_NAME',  'sort_by' => 'first_name'), // Western order, last name is uppercase when a full name is assembled
-	//'spanish' =>          array(  'format' => 'title first_name LAST_NAME',  'sort_by' => 'last_name'), // Western order, last name is uppercase when a full name is assembled
 	'spanish' =>          array('format' => 'title last_name, first_name',  'sort_by' => 'last_name'), // Library order
-	//'spanish' =>          array(  'format' => 'title LAST_NAME, first_name',  'sort_by' => 'last_name'), // Library order, last name is uppercase when a full name is assembled
-
 	'swahili' =>          array('format' => 'title first_name last_name',  'sort_by' => 'first_name'),
 	'swedish' =>          array('format' => 'title first_name last_name',  'sort_by' => 'first_name'),
 	'tagalog' =>          array('format' => 'title first_name last_name',  'sort_by' => 'first_name'),

+ 21 - 9
main/inc/lib/internationalization_internal.lib.php

@@ -196,18 +196,16 @@ function &_api_get_day_month_names($language = null) {
     return $date_parts[$language];
 }
 
-
-/**
- * Appendix to "Name order conventions"
- */
-
 /**
  * Returns returns person name convention for a given language.
  * @param string $language	The input language.
- * @param string $type		The type of the requested convention. It may be 'format' for name order convention or 'sort_by' for name sorting convention.
- * @return mixed			Depending of the requested type, the returned result may be string or boolean; null is returned on error;
+ * @param string $type		The type of the requested convention.
+ * It may be 'format' for name order convention or 'sort_by' for name sorting convention.
+ * @return mixed Depending of the requested type,
+ * the returned result may be string or boolean; null is returned on error;
  */
-function _api_get_person_name_convention($language, $type) {
+function _api_get_person_name_convention($language, $type)
+{
     static $conventions;
     $language = api_purify_language_id($language);
     if (!isset($conventions)) {
@@ -215,8 +213,22 @@ function _api_get_person_name_convention($language, $type) {
         if (file_exists($file)) {
             $conventions = include ($file);
         } else {
-            $conventions = array('english' => array('format' => 'title first_name last_name', 'sort_by' => 'first_name'));
+            $conventions = array(
+                'english' => array(
+                    'format' => 'title first_name last_name',
+                    'sort_by' => 'first_name'
+                )
+            );
         }
+        // Overwrite classic conventions
+        $customConventions = api_get_configuration_value('name_order_conventions');
+
+        if (!empty($customConventions)) {
+            foreach ($customConventions as $key => $data) {
+                $conventions[$key] = $data;
+            }
+        }
+
         $search1 = array('FIRST_NAME', 'LAST_NAME', 'TITLE');
         $replacement1 = array('%F', '%L', '%T');
         $search2 = array('first_name', 'last_name', 'title');

BIN
main/inc/lib/javascript/emojine/png/1F1F5-1F1F1.png


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