Julio Montoya 11 years ago
parent
commit
2e45b2e6c0
100 changed files with 1567 additions and 2183 deletions
  1. 1 0
      .gitignore
  2. 3 0
      .htaccess
  3. 9 8
      composer.json
  4. 433 116
      composer.lock
  5. 19 16
      config/configuration.dist.php
  6. 1 1
      console.php
  7. 6 3
      documentation/dependencies.html
  8. 97 84
      documentation/installation_guide.html
  9. 35 44
      documentation/installation_guide_es_ES.html
  10. 2 0
      global.inc.php
  11. 3 0
      htaccess-dist
  12. 2 0
      inc/global.inc.php
  13. 2 2
      main/admin/archive_cleanup.php
  14. 7 7
      main/admin/calendar.php
  15. 3 7
      main/admin/calendar_view.php
  16. 2 2
      main/admin/configure_homepage.php
  17. 2 5
      main/admin/configure_inscription.php
  18. 2 1
      main/admin/course_create_content.php
  19. 5 3
      main/admin/course_list.php
  20. 4 1
      main/admin/index.php
  21. 4 5
      main/admin/ldap_synchro.php
  22. 28 34
      main/admin/settings.lib.php
  23. 2 2
      main/admin/settings.php
  24. 10 7
      main/admin/statistics/index.php
  25. 2 1
      main/admin/system_announcements.php
  26. 3 4
      main/admin/user_add.php
  27. 23 20
      main/admin/user_fields_add.php
  28. 12 6
      main/admin/user_list.php
  29. 19 2
      main/announcements/announcements.php
  30. 27 36
      main/announcements/resources/js/main.js
  31. 15 15
      main/auth/cas/lib/CAS.php
  32. 2 2
      main/auth/inscription.php
  33. 1 1
      main/auth/profile.php
  34. 3 3
      main/auth/shibboleth/app/shibboleth.class.php
  35. 2 2
      main/blog/blog.php
  36. 1 1
      main/blog/calendar.php
  37. 119 124
      main/calendar/agenda.inc.php
  38. 0 1105
      main/calendar/agenda.lib.php
  39. 2 2
      main/calendar/agenda.php
  40. 1 2
      main/calendar/agenda_js.php
  41. 1 2
      main/calendar/allagendas.php
  42. 1 1
      main/calendar/calendar.php
  43. 1 2
      main/calendar/ical_export.php
  44. 2 1
      main/calendar/myagenda.php
  45. 1 1
      main/conference/api.php
  46. 1 1
      main/conference/get_translation.lib.php
  47. 2 1
      main/course_home/course_home.php
  48. 3 4
      main/course_info/delete_course.php
  49. 1 2
      main/course_info/download.php
  50. 8 7
      main/course_info/infocours.php
  51. 8 10
      main/coursecopy/classes/CourseArchiver.class.php
  52. 2 2
      main/coursecopy/classes/CourseRecycler.class.php
  53. 2 2
      main/coursecopy/classes/CourseRestorer.class.php
  54. 1 1
      main/coursecopy/classes/DummyCourseCreator.class.php
  55. 8 10
      main/coursecopy/classes/Resource.class.php
  56. 4 1
      main/coursecopy/import_backup.php
  57. 3 5
      main/create_course/add_course.php
  58. 6 3
      main/css/base.css
  59. 3 3
      main/document/create_document.php
  60. 2 2
      main/document/document.php
  61. 1 1
      main/document/document_lite.php
  62. 3 1
      main/document/document_slideshow.inc.php
  63. 2 2
      main/document/save_pixlr.php
  64. 4 4
      main/dropbox/dropbox_config.inc.php
  65. 1 1
      main/dropbox/dropbox_functions.inc.php
  66. 1 1
      main/dropbox/dropbox_submit.php
  67. 18 16
      main/exercice/admin.php
  68. 4 4
      main/exercice/adminhp.php
  69. 6 4
      main/exercice/answer_admin.inc.php
  70. 3 2
      main/exercice/exercice.php
  71. 53 38
      main/exercice/exercise.class.php
  72. 3 1
      main/exercice/exercise_history.php
  73. 6 4
      main/exercice/exercise_reminder.php
  74. 8 5
      main/exercice/exercise_report.php
  75. 10 2
      main/exercice/exercise_result.class.php
  76. 2 2
      main/exercice/exercise_result.php
  77. 9 9
      main/exercice/exercise_show.php
  78. 117 67
      main/exercice/exercise_submit.php
  79. 6 6
      main/exercice/exercise_submit_modal.php
  80. 1 1
      main/exercice/hotpotatoes.php
  81. 1 1
      main/exercice/hotpotatoes_exercise_report.php
  82. 1 1
      main/exercice/hotspot_admin.inc.php
  83. 2 2
      main/exercice/live_stats.php
  84. 5 2
      main/exercice/overview.php
  85. 8 5
      main/exercice/question_admin.inc.php
  86. 2 2
      main/exercice/showinframes.php
  87. 3 3
      main/exercice/stats.php
  88. 2 2
      main/exercice/testcategory.class.php
  89. 2 3
      main/exercice/upload_exercise.php
  90. 5 5
      main/forum/editpost.php
  91. 2 2
      main/forum/newthread.php
  92. 0 1
      main/gradebook/lib/be/abstractlink.class.php
  93. 1 1
      main/gradebook/lib/fe/exportgradebook.php
  94. 60 3
      main/inc/Entity/Repository/UserRepository.php
  95. 26 1
      main/inc/Entity/Role.php
  96. 172 29
      main/inc/Entity/User.php
  97. 3 7
      main/inc/ajax/agenda.ajax.php
  98. 20 22
      main/inc/ajax/chat.ajax.php
  99. 20 7
      main/inc/ajax/exercise.ajax.php
  100. 0 178
      main/inc/entity/access_url.class.php

+ 1 - 0
.gitignore

@@ -9,6 +9,7 @@ config/portfolio.conf.php
 config/profile.conf.php
 
 temp/*
+!temp/twig/PLACEHOLDER
 data/*
 !data/upload/users
 logs/*

+ 3 - 0
.htaccess

@@ -15,6 +15,9 @@
     RewriteRule ^courses/(.*)/index.php$ web/courses/$1? [R,L]
     RewriteRule ^courses/(.*)/$ web/courses/$1? [R,L]
 
+    # PHP Main files are redirected to the "web/main" zone
+    RewriteRule ^main/(.*)\.php web/main/$1.php [R,L]
+
     # Courses documents
     # courses/MATHS/document/folder1/picture.jpg --> web/data/courses/MATHS/document/folder1/picture.jpg
     RewriteRule ^courses/(.*)/document/(.*)$ web/data/courses/$1/document/$2 [R,L]

+ 9 - 8
composer.json

@@ -1,7 +1,7 @@
 {
     "name": "chamilo/chamilo-lms",
     "type": "project",
-    "homepage": "www.chamilo.org",
+    "homepage": "http://www.chamilo.org",
     "license": "GPL-3.0",
     "support": {
         "forum": "http://www.chamilo.org/forum",
@@ -35,10 +35,6 @@
         {
             "type": "vcs",
             "url": "https://github.com/jmontoyaa/silex-pagerfanta-provider"
-        },
-        {
-            "type": "vcs",
-            "url": "https://github.com/ThePixelDeveloper/ConsoleServiceProvider"
         }
     ],
     "require": {
@@ -54,6 +50,10 @@
         "symfony/translation": "~2.3",
         "symfony/dependency-injection": "~2.3",
         "monolog/monolog" : ">=1.0.0",
+        "symfony/config": "~2.3",
+        "symfony/yaml": "~2.3",
+        "symfony/locale": "~2.3",
+        "symfony/monolog-bridge": "~2.3",
         "twig/twig": ">=1.8,<2.0-dev",
         "dflydev/doctrine-orm-service-provider": "1.0.*@dev",
         "doctrine/migrations": "dev-master",
@@ -62,7 +62,7 @@
         "swiftmailer/swiftmailer": ">=4.1.2,<4.2-dev",
         "pagerfanta/pagerfanta": "dev-master",
         "franmomu/silex-pagerfanta-provider": "2.3.*@dev",
-        "igorw/config-service-provider": "1.0.*@dev",
+        "igorw/config-service-provider": "1.2.*@dev",
         "mpdf/mpdf": "v5.6.1",
         "ezyang/htmlpurifier": "v4.5.0",
         "realityking/pchart": "dev-master",
@@ -79,12 +79,13 @@
     },
     "require-dev": {
         "symfony/browser-kit": "2.3.*@dev",
-        "symfony/web-profiler-bundle": "~2.2",
+        "symfony/web-profiler-bundle": "~2.3",
         "silex/web-profiler": "1.0.x-dev",
         "natxet/CssMin": "dev-master",
         "leafo/lessphp": "dev-master",
         "mheap/silex-assetic": "1.0.*@dev",
-        "filp/whoops": "dev-master"
+        "filp/whoops": "dev-master",
+        "sensio/framework-extra-bundle": "2.3.*@dev"
     },
     "scripts": {
         "post-install-cmd": "ChamiloLMS\\Composer\\Tasks::postInstall",

+ 433 - 116
composer.lock

@@ -3,7 +3,7 @@
         "This file locks the dependencies of your project to a known state",
         "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
     ],
-    "hash": "58d73dfb3014105475e16c5f520fe4cd",
+    "hash": "94cb7c5f7d4efa532d6bd2b1a4ba0cd6",
     "packages": [
         {
             "name": "bt51/gaufrette-serviceprovider",
@@ -58,18 +58,18 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/chamilo/chash.git",
-                "reference": "bd251168e9e7ea01c7da0cef67708c0bdec550bf"
+                "reference": "0720bc4ab428494465ac6bab6532cb167704183f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/chamilo/chash/zipball/bd251168e9e7ea01c7da0cef67708c0bdec550bf",
-                "reference": "bd251168e9e7ea01c7da0cef67708c0bdec550bf",
+                "url": "https://api.github.com/repos/chamilo/chash/zipball/0720bc4ab428494465ac6bab6532cb167704183f",
+                "reference": "0720bc4ab428494465ac6bab6532cb167704183f",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.2",
-                "symfony/console": "2.3.*@dev",
-                "symfony/yaml": "2.1.*"
+                "symfony/console": ">=2.3,<3.0",
+                "symfony/yaml": ">=2.3,<3.0"
             },
             "type": "library",
             "autoload": {
@@ -78,7 +78,8 @@
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
-            "time": "2013-06-10 13:35:04"
+            "homepage": "http://www.chamilo.org",
+            "time": "2013-06-14 09:54:38"
         },
         {
             "name": "dflydev/doctrine-orm-service-provider",
@@ -198,9 +199,9 @@
                     "email": "kontakt@beberlei.de"
                 },
                 {
-                    "name": "Johannes M. Schmitt",
+                    "name": "Johannes Schmitt",
                     "email": "schmittjoh@gmail.com",
-                    "homepage": "https://github.com/schmittjoh",
+                    "homepage": "http://jmsyst.com",
                     "role": "Developer of wrapped JMSSerializerBundle"
                 }
             ],
@@ -626,32 +627,34 @@
         },
         {
             "name": "igorw/config-service-provider",
-            "version": "v1.0.0",
+            "version": "dev-master",
             "source": {
                 "type": "git",
-                "url": "https://github.com/igorw/ConfigServiceProvider",
-                "reference": "v1.0.0"
+                "url": "https://github.com/igorw/ConfigServiceProvider.git",
+                "reference": "v1.2.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://github.com/igorw/ConfigServiceProvider/archive/v1.0.0.zip",
-                "reference": "v1.0.0",
+                "url": "https://api.github.com/repos/igorw/ConfigServiceProvider/zipball/v1.2.1",
+                "reference": "v1.2.1",
                 "shasum": ""
             },
             "require": {
-                "silex/silex": "1.0.*@dev"
+                "silex/silex": ">=1.0,<2.0"
             },
             "require-dev": {
-                "symfony/yaml": "2.1.*@dev"
+                "jamesmoss/toml": ">=0.1,<1.0",
+                "symfony/yaml": ">=2.1,<3.0"
             },
             "suggest": {
-                "symfony/yaml": "2.1.*"
+                "jamesmoss/toml": "~0.1",
+                "symfony/yaml": "~2.1"
             },
             "type": "library",
             "extra": {
-                "branch-alias": [
-
-                ]
+                "branch-alias": {
+                    "dev-master": "1.2-dev"
+                }
             },
             "autoload": {
                 "psr-0": {
@@ -673,11 +676,11 @@
                     "homepage": "https://github.com/igorw/ConfigServiceProvider/contributors"
                 }
             ],
-            "description": "A JSON/Yaml-based config ServiceProvider for Silex.",
+            "description": "A config ServiceProvider for Silex with support for php, json and yaml.",
             "keywords": [
                 "silex"
             ],
-            "time": "2012-07-13 17:12:34"
+            "time": "2013-05-31 14:23:34"
         },
         {
             "name": "imagine/imagine",
@@ -762,7 +765,8 @@
                 {
                     "name": "Johnny Broadway",
                     "email": "johnny@johnnybroadway.com",
-                    "homepage": "http://www.johnnybroadway.com/"
+                    "homepage": "http://www.johnnybroadway.com/",
+                    "role": "Main Developer"
                 }
             ],
             "description": "PHP port of URLify.js from the Django project. Transliterates non-ascii characters for use in URLs.",
@@ -827,18 +831,18 @@
             "version": "dev-master",
             "source": {
                 "type": "git",
-                "url": "https://github.com/ThePixelDeveloper/ConsoleServiceProvider.git",
-                "reference": "ba7d78060a1f6689082b35b5b4f5a4891b48a36c"
+                "url": "https://github.com/KnpLabs/ConsoleServiceProvider.git",
+                "reference": "1f1a3315409814d01702a47a8823549c6996de41"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/ThePixelDeveloper/ConsoleServiceProvider/zipball/ba7d78060a1f6689082b35b5b4f5a4891b48a36c",
-                "reference": "ba7d78060a1f6689082b35b5b4f5a4891b48a36c",
+                "url": "https://api.github.com/repos/KnpLabs/ConsoleServiceProvider/zipball/1f1a3315409814d01702a47a8823549c6996de41",
+                "reference": "1f1a3315409814d01702a47a8823549c6996de41",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.2",
-                "symfony/console": "~2.1"
+                "symfony/console": ">=2.1,<3.0"
             },
             "type": "library",
             "autoload": {
@@ -846,6 +850,7 @@
                     "Knp\\": ""
                 }
             },
+            "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "MIT"
             ],
@@ -861,10 +866,7 @@
                 "console",
                 "silex"
             ],
-            "support": {
-                "source": "https://github.com/ThePixelDeveloper/ConsoleServiceProvider/tree/master"
-            },
-            "time": "2013-02-10 13:15:07"
+            "time": "2013-06-13 12:43:39"
         },
         {
             "name": "knplabs/gaufrette",
@@ -989,7 +991,7 @@
                     "email": "stof@notk.org"
                 },
                 {
-                    "name": "Knplabs",
+                    "name": "KnpLabs",
                     "homepage": "http://knplabs.com"
                 },
                 {
@@ -1213,12 +1215,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/whiteoctober/Pagerfanta.git",
-                "reference": "55544f3af5b409d4ee9d618934f4d92ef874672c"
+                "reference": "1a3cb8addb92df6396e59a2c44c3b7f216b4218a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/whiteoctober/Pagerfanta/zipball/55544f3af5b409d4ee9d618934f4d92ef874672c",
-                "reference": "55544f3af5b409d4ee9d618934f4d92ef874672c",
+                "url": "https://api.github.com/repos/whiteoctober/Pagerfanta/zipball/1a3cb8addb92df6396e59a2c44c3b7f216b4218a",
+                "reference": "1a3cb8addb92df6396e59a2c44c3b7f216b4218a",
                 "shasum": ""
             },
             "require": {
@@ -1267,7 +1269,7 @@
                 "paginator",
                 "paging"
             ],
-            "time": "2013-05-16 12:46:53"
+            "time": "2013-06-13 22:25:28"
         },
         {
             "name": "pimple/pimple",
@@ -1518,19 +1520,67 @@
             ],
             "time": "2012-06-17 13:55:34"
         },
+        {
+            "name": "symfony/config",
+            "version": "v2.3.1",
+            "target-dir": "Symfony/Component/Config",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/Config.git",
+                "reference": "v2.3.1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/Config/zipball/v2.3.1",
+                "reference": "v2.3.1",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3",
+                "symfony/filesystem": ">=2.3,<3.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.3-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Symfony\\Component\\Config\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "http://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Config Component",
+            "homepage": "http://symfony.com",
+            "time": "2013-06-03 00:18:25"
+        },
         {
             "name": "symfony/console",
-            "version": "v2.3.0",
+            "version": "v2.3.1",
             "target-dir": "Symfony/Component/Console",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/Console.git",
-                "reference": "v2.3.0"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Console/zipball/v2.3.0",
-                "reference": "v2.3.0",
+                "url": "https://api.github.com/repos/symfony/Console/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
@@ -1569,21 +1619,21 @@
             ],
             "description": "Symfony Console Component",
             "homepage": "http://symfony.com",
-            "time": "2013-05-30 05:11:26"
+            "time": "2013-06-11 07:15:14"
         },
         {
             "name": "symfony/debug",
-            "version": "v2.3.0",
+            "version": "v2.3.1",
             "target-dir": "Symfony/Component/Debug",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/Debug.git",
-                "reference": "v2.3.0"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Debug/zipball/v2.3.0",
-                "reference": "v2.3.0",
+                "url": "https://api.github.com/repos/symfony/Debug/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
@@ -1629,17 +1679,17 @@
         },
         {
             "name": "symfony/dependency-injection",
-            "version": "v2.3.0",
+            "version": "v2.3.1",
             "target-dir": "Symfony/Component/DependencyInjection",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/DependencyInjection.git",
-                "reference": "v2.3.0-RC1"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/v2.3.0-RC1",
-                "reference": "v2.3.0-RC1",
+                "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
@@ -1681,7 +1731,7 @@
             ],
             "description": "Symfony DependencyInjection Component",
             "homepage": "http://symfony.com",
-            "time": "2013-05-13 14:36:40"
+            "time": "2013-06-05 09:51:05"
         },
         {
             "name": "symfony/doctrine-bridge",
@@ -1805,17 +1855,17 @@
         },
         {
             "name": "symfony/filesystem",
-            "version": "v2.3.0",
+            "version": "v2.3.1",
             "target-dir": "Symfony/Component/Filesystem",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/Filesystem.git",
-                "reference": "v2.3.0-RC1"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Filesystem/zipball/v2.3.0-RC1",
-                "reference": "v2.3.0-RC1",
+                "url": "https://api.github.com/repos/symfony/Filesystem/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
@@ -1848,21 +1898,21 @@
             ],
             "description": "Symfony Filesystem Component",
             "homepage": "http://symfony.com",
-            "time": "2013-05-06 20:03:44"
+            "time": "2013-06-04 15:02:05"
         },
         {
             "name": "symfony/form",
-            "version": "v2.3.0",
+            "version": "v2.3.1",
             "target-dir": "Symfony/Component/Form",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/Form.git",
-                "reference": "v2.3.0"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Form/zipball/v2.3.0",
-                "reference": "v2.3.0",
+                "url": "https://api.github.com/repos/symfony/Form/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
@@ -1911,17 +1961,17 @@
         },
         {
             "name": "symfony/http-foundation",
-            "version": "v2.3.0",
+            "version": "v2.3.1",
             "target-dir": "Symfony/Component/HttpFoundation",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/HttpFoundation.git",
-                "reference": "v2.3.0-RC1"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/v2.3.0-RC1",
-                "reference": "v2.3.0-RC1",
+                "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
@@ -2079,17 +2129,17 @@
         },
         {
             "name": "symfony/intl",
-            "version": "v2.3.0",
+            "version": "v2.3.1",
             "target-dir": "Symfony/Component/Intl",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/Intl.git",
-                "reference": "v2.3.0"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Intl/zipball/v2.3.0",
-                "reference": "v2.3.0",
+                "url": "https://api.github.com/repos/symfony/Intl/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
@@ -2154,19 +2204,116 @@
             ],
             "time": "2013-05-18 11:21:22"
         },
+        {
+            "name": "symfony/locale",
+            "version": "v2.3.1",
+            "target-dir": "Symfony/Component/Locale",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/Locale.git",
+                "reference": "v2.3.1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/Locale/zipball/v2.3.1",
+                "reference": "v2.3.1",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3",
+                "symfony/intl": ">=2.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.3-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Symfony\\Component\\Locale\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "http://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Locale Component",
+            "homepage": "http://symfony.com",
+            "time": "2013-04-11 09:29:25"
+        },
+        {
+            "name": "symfony/monolog-bridge",
+            "version": "v2.3.1",
+            "target-dir": "Symfony/Bridge/Monolog",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/MonologBridge.git",
+                "reference": "v2.3.1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/MonologBridge/zipball/v2.3.1",
+                "reference": "v2.3.1",
+                "shasum": ""
+            },
+            "require": {
+                "monolog/monolog": ">=1.3,<2.0",
+                "php": ">=5.3.3",
+                "symfony/http-kernel": ">=2.2,<3.0"
+            },
+            "type": "symfony-bridge",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.3-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Symfony\\Bridge\\Monolog\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "http://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Monolog Bridge",
+            "homepage": "http://symfony.com",
+            "time": "2013-05-24 13:05:33"
+        },
         {
             "name": "symfony/options-resolver",
-            "version": "v2.3.0",
+            "version": "v2.3.1",
             "target-dir": "Symfony/Component/OptionsResolver",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/OptionsResolver.git",
-                "reference": "v2.3.0-RC1"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/OptionsResolver/zipball/v2.3.0-RC1",
-                "reference": "v2.3.0-RC1",
+                "url": "https://api.github.com/repos/symfony/OptionsResolver/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
@@ -2213,12 +2360,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/PropertyAccess.git",
-                "reference": "v2.3.0-RC1"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/PropertyAccess/zipball/v2.3.0-RC1",
-                "reference": "v2.3.0-RC1",
+                "url": "https://api.github.com/repos/symfony/PropertyAccess/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
@@ -2324,17 +2471,17 @@
         },
         {
             "name": "symfony/security",
-            "version": "v2.3.0",
+            "version": "v2.3.1",
             "target-dir": "Symfony/Component/Security",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/Security.git",
-                "reference": "v2.3.0"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Security/zipball/v2.3.0",
-                "reference": "v2.3.0",
+                "url": "https://api.github.com/repos/symfony/Security/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
@@ -2388,7 +2535,7 @@
             ],
             "description": "Symfony Security Component",
             "homepage": "http://symfony.com",
-            "time": "2013-05-27 14:49:21"
+            "time": "2013-06-02 22:50:02"
         },
         {
             "name": "symfony/translation",
@@ -2447,17 +2594,17 @@
         },
         {
             "name": "symfony/twig-bridge",
-            "version": "v2.3.0",
+            "version": "v2.3.1",
             "target-dir": "Symfony/Bridge/Twig",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/TwigBridge.git",
-                "reference": "v2.3.0-RC1"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/TwigBridge/zipball/v2.3.0-RC1",
-                "reference": "v2.3.0-RC1",
+                "url": "https://api.github.com/repos/symfony/TwigBridge/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
@@ -2513,17 +2660,17 @@
         },
         {
             "name": "symfony/validator",
-            "version": "v2.3.0",
+            "version": "v2.3.1",
             "target-dir": "Symfony/Component/Validator",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/Validator.git",
-                "reference": "v2.3.0"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Validator/zipball/v2.3.0",
-                "reference": "v2.3.0",
+                "url": "https://api.github.com/repos/symfony/Validator/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
@@ -2570,30 +2717,35 @@
             ],
             "description": "Symfony Validator Component",
             "homepage": "http://symfony.com",
-            "time": "2013-06-02 12:05:51"
+            "time": "2013-06-10 16:23:25"
         },
         {
             "name": "symfony/yaml",
-            "version": "v2.1.11",
+            "version": "v2.3.1",
             "target-dir": "Symfony/Component/Yaml",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/Yaml.git",
-                "reference": "v2.1.11"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.1.11",
-                "reference": "v2.1.11",
+                "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.3"
             },
             "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.3-dev"
+                }
+            },
             "autoload": {
                 "psr-0": {
-                    "Symfony\\Component\\Yaml": ""
+                    "Symfony\\Component\\Yaml\\": ""
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -2612,7 +2764,7 @@
             ],
             "description": "Symfony Yaml Component",
             "homepage": "http://symfony.com",
-            "time": "2013-05-10 00:09:46"
+            "time": "2013-05-10 18:12:13"
         },
         {
             "name": "twig/twig",
@@ -2932,6 +3084,53 @@
             ],
             "time": "2013-03-15 18:47:32"
         },
+        {
+            "name": "sensio/framework-extra-bundle",
+            "version": "dev-master",
+            "target-dir": "Sensio/Bundle/FrameworkExtraBundle",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sensiolabs/SensioFrameworkExtraBundle.git",
+                "reference": "v2.3.1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/zipball/v2.3.1",
+                "reference": "v2.3.1",
+                "shasum": ""
+            },
+            "require": {
+                "doctrine/common": ">=2.2,<3.0",
+                "symfony/framework-bundle": ">=2.2,<3.0"
+            },
+            "type": "symfony-bundle",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.3.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Sensio\\Bundle\\FrameworkExtraBundle": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                }
+            ],
+            "description": "This bundle provides a way to configure your controllers with annotations",
+            "keywords": [
+                "annotations",
+                "controllers"
+            ],
+            "time": "2013-06-02 16:13:20"
+        },
         {
             "name": "silex/web-profiler",
             "version": "dev-master",
@@ -2984,12 +3183,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/BrowserKit.git",
-                "reference": "v2.3.0-RC1"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/BrowserKit/zipball/v2.3.0-RC1",
-                "reference": "v2.3.0-RC1",
+                "url": "https://api.github.com/repos/symfony/BrowserKit/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
@@ -3034,17 +3233,17 @@
         },
         {
             "name": "symfony/dom-crawler",
-            "version": "v2.3.0",
+            "version": "v2.3.1",
             "target-dir": "Symfony/Component/DomCrawler",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/DomCrawler.git",
-                "reference": "v2.3.0"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/v2.3.0",
-                "reference": "v2.3.0",
+                "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
@@ -3083,7 +3282,7 @@
             ],
             "description": "Symfony DomCrawler Component",
             "homepage": "http://symfony.com",
-            "time": "2013-05-19 19:00:48"
+            "time": "2013-06-11 07:15:14"
         },
         {
             "name": "symfony/finder",
@@ -3132,19 +3331,89 @@
             "homepage": "http://symfony.com",
             "time": "2013-05-27 20:26:32"
         },
+        {
+            "name": "symfony/framework-bundle",
+            "version": "v2.3.1",
+            "target-dir": "Symfony/Bundle/FrameworkBundle",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/FrameworkBundle.git",
+                "reference": "v2.3.1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/FrameworkBundle/zipball/v2.3.1",
+                "reference": "v2.3.1",
+                "shasum": ""
+            },
+            "require": {
+                "doctrine/common": ">=2.2,<3.0",
+                "php": ">=5.3.3",
+                "symfony/config": ">=2.2,<3.0",
+                "symfony/dependency-injection": ">=2.2,<3.0",
+                "symfony/event-dispatcher": ">=2.1,<3.0",
+                "symfony/filesystem": ">=2.3,<3.0",
+                "symfony/http-kernel": ">=2.3,<3.0",
+                "symfony/routing": ">=2.2,<3.0",
+                "symfony/stopwatch": ">=2.3,<3.0",
+                "symfony/templating": ">=2.1,<3.0",
+                "symfony/translation": ">=2.3,<3.0"
+            },
+            "require-dev": {
+                "symfony/class-loader": ">=2.1,<3.0",
+                "symfony/finder": ">=2.0,<3.0",
+                "symfony/form": ">=2.3,<3.0",
+                "symfony/security": ">=2.3,<3.0",
+                "symfony/validator": ">=2.1,<3.0"
+            },
+            "suggest": {
+                "symfony/console": "",
+                "symfony/finder": "",
+                "symfony/form": "",
+                "symfony/validator": ""
+            },
+            "type": "symfony-bundle",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.3-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Symfony\\Bundle\\FrameworkBundle\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "http://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony FrameworkBundle",
+            "homepage": "http://symfony.com",
+            "time": "2013-06-07 22:05:01"
+        },
         {
             "name": "symfony/process",
-            "version": "v2.3.0",
+            "version": "v2.3.1",
             "target-dir": "Symfony/Component/Process",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/Process.git",
-                "reference": "v2.3.0-RC1"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Process/zipball/v2.3.0-RC1",
-                "reference": "v2.3.0-RC1",
+                "url": "https://api.github.com/repos/symfony/Process/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
@@ -3181,17 +3450,17 @@
         },
         {
             "name": "symfony/stopwatch",
-            "version": "v2.3.0",
+            "version": "v2.3.1",
             "target-dir": "Symfony/Component/Stopwatch",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/Stopwatch.git",
-                "reference": "v2.3.0-RC1"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/v2.3.0-RC1",
-                "reference": "v2.3.0-RC1",
+                "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
@@ -3226,19 +3495,66 @@
             "homepage": "http://symfony.com",
             "time": "2013-04-17 07:17:10"
         },
+        {
+            "name": "symfony/templating",
+            "version": "v2.3.1",
+            "target-dir": "Symfony/Component/Templating",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/Templating.git",
+                "reference": "v2.3.1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/Templating/zipball/v2.3.1",
+                "reference": "v2.3.1",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.3-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Symfony\\Component\\Templating\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "http://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Templating Component",
+            "homepage": "http://symfony.com",
+            "time": "2013-04-17 05:31:37"
+        },
         {
             "name": "symfony/web-profiler-bundle",
-            "version": "v2.3.0",
+            "version": "v2.3.1",
             "target-dir": "Symfony/Bundle/WebProfilerBundle",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/WebProfilerBundle.git",
-                "reference": "v2.3.0"
+                "reference": "v2.3.1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/WebProfilerBundle/zipball/v2.3.0",
-                "reference": "v2.3.0",
+                "url": "https://api.github.com/repos/symfony/WebProfilerBundle/zipball/v2.3.1",
+                "reference": "v2.3.1",
                 "shasum": ""
             },
             "require": {
@@ -3312,7 +3628,8 @@
         "natxet/cssmin": 20,
         "leafo/lessphp": 20,
         "mheap/silex-assetic": 20,
-        "filp/whoops": 20
+        "filp/whoops": 20,
+        "sensio/framework-extra-bundle": 20
     },
     "platform": {
         "php": ">=5.3.2"

+ 19 - 16
config/configuration.dist.php

@@ -25,15 +25,15 @@
 /**
  * Database settings
  */
-// Host
+// Host.
 $_configuration['db_host']     = '{DATABASE_HOST}';
-// Username
+// Username.
 $_configuration['db_user']     = '{DATABASE_USER}';
-// Password
+// Password.
 $_configuration['db_password'] = '{DATABASE_PASSWORD}';
-// Driver
+// Driver.
 $_configuration['db_driver']   = '{DATABASE_DRIVER}';
-// Database name
+// Database name.
 $_configuration['main_database'] = '{DATABASE_MAIN}';
 
 /** Directory settings */
@@ -114,33 +114,33 @@ $_configuration[1]['hosting_limit_disk_space'] = 0;
 $_configuration['cdn_enable'] = false;
 // The following setting will be ignored if the previous one is set to false
 $_configuration['cdn'] = array(
-  //You can define several CDNs and split them by extensions
-  //Replace the following by your full CDN URL, which should point to
-  // your Chamilo's root directory. DO NOT INCLUDE a final slash! (won't work)
-  'http://cdn.chamilo.org' => array('.css','.js','.jpg','.jpeg','.png','.gif','.avi','.flv'),
-  // copy the line above and modify following your needs
+    //You can define several CDNs and split them by extensions
+    //Replace the following by your full CDN URL, which should point to
+    // your Chamilo's root directory. DO NOT INCLUDE a final slash! (won't work)
+    'http://cdn.chamilo.org' => array('.css','.js','.jpg','.jpeg','.png','.gif','.avi','.flv'),
+    // copy the line above and modify following your needs
 );
 
 /**
  * Session settings
  */
-// You may have to restart your web server if you change this
+// You may have to restart your web server if you change this.
 $_configuration['session_stored_in_db'] = false;
 // Session lifetime
 $_configuration['session_lifetime'] = SESSION_LIFETIME;
 
 /** Security */
-// Security word for password recovery
+// Security word for password recovery.
 $_configuration['security_key'] = '{SECURITY_KEY}';
-// Hash function method
+// Hash function method.
 $_configuration['password_encryption'] = '{ENCRYPT_PASSWORD}';
-//Deny the elimination of users
+//Deny the elimination of users.
 $_configuration['deny_delete_users'] = false;
-//Prevent all admins from using the "login_as" feature
+//Prevent all admins from using the "login_as" feature.
 $_configuration['login_as_forbidden_globally'] = false;
 
 /** Multiple URL */
-// Activation for multi-url access
+// Activation for multi-url access.
 //$_configuration['multiple_access_urls'] = true;
 
 /** Chamilo version settings */
@@ -150,5 +150,8 @@ $_configuration['software_name']     = 'Chamilo';
 $_configuration['software_url']	     = 'http://www.chamilo.org/';
 
 /** Chamilo dev settings */
+// Generate twig templates in every request, prompts SQL errors.
 $_configuration['debug']             = false;
+$_configuration['platform_charset']  = 'utf-8';
+// Show a useful toolbar with memory used, loaded time, request, session, logs information.
 $_configuration['show_profiler']     = false;

+ 1 - 1
console.php

@@ -76,8 +76,8 @@ $cli->addCommands(
         //new ChamiloLMS\Command\Database\InstallExtendCommand(),
         new ChamiloLMS\Command\Database\StatusCommand(),
         new ChamiloLMS\Command\Database\SetupCommand(),
-
         new ChamiloLMS\Command\Template\AsseticDumpCommand(),
+        new ChamiloLMS\Command\Translation\ExportLanguagesCommand(),
 
         // Chash commands.
         new Chash\Command\Database\RunSQLCommand(),

+ 6 - 3
documentation/dependencies.html

@@ -57,18 +57,21 @@ required information to install it.</p>
 <a name="dependencies"></a>
 <h2>Dependencies - client-side</h2>
 <ul>
-  <li>Any modern browser (IE6 *excluded*). Safari is known to have small issues with the WYSIWYG editor.</li>
+  <li>Any modern browser (IE6 *excluded*). Safari is known to have minor issues with the WYSIWYG editor.</li>
   <li>Optional: Flash plugin (only required for a few features)</li>
 </ul>
 <h2>Dependencies - server-side</h2>
 <ul>
   <li> Apache 2+</li>
-  <li> PHP 5.3 or 5.4 with MySQL bindings and php-gd extension to allow Chamilo to resize pictures. The 
-  new components we have included from the Symfony framework highly depend on namespaces, a feature that appeared in PHP 5.3.0+</li>
+  <li> PHP 5.3 or 5.4 with MySQL bindings (mysqlnd is recommended) and php-gd extension to allow Chamilo to resize pictures. The 
+  new components we have included from the Symfony framework highly depend on namespaces, a feature that appeared in PHP 5.3.0</li>
   <li> MySQL 5.1+ or any version of MariaDB database server</li>
   <li>php5-intl</li>
+  <li>php5-imagick</li>
   <li>php5-curl (only required for a feature in the links tool)</li>
   <li>php5-mcrypt (only required for a feature in the survey tool)</li>
+  <li>php5-ldap (only required for connection to a LDAP server)</li>
+  <li>php5-xapian (only required for full-text indexing and search)</li>
 </ul><br />
 <a name="included_dependencies"></a>
 <h2>Included Dependencies</h2>

+ 97 - 84
documentation/installation_guide.html

@@ -67,18 +67,18 @@
 <h2><a name="1._Pre-requisites"></a>1. Pre-requisites</h2>
 
 Chamilo
-can be installed on Windows, Linux, Mac OS X and UNIX servers
-indifferently. However, we recommend the use of Linux server for
+can be installed on Windows, GNU/Linux, Mac OS X and UNIX servers
+indifferently. However, we recommend the use of GNU/Linux for
 optimal flexibility, remote control and scalability. <br />
 
 <br />
 
-Chamilo is mainly a LMS running <span style="font-weight: bold;">Apache (1.3, 2.0 or 2.2)</span>, <span style="font-weight: bold;">MySQL 5.1 (or MariaDB)</span> and <span style="font-weight: bold;">PHP 5.3 (or 5.4)</span> (the so called <span style="font-weight: bold;">AMP</span> trilogy). <br />
+Chamilo is mainly a LMS running from <span style="font-weight: bold;">Apache (1.3, 2.0 or 2.2)</span>, with a <span style="font-weight: bold;">MySQL 5.1 (or MariaDB)</span> database backend and <span style="font-weight: bold;">PHP 5.3 (or 5.4)</span> (the so called <span style="font-weight: bold;">AMP</span> trilogy). <br />
 
 
 <br />
 
-All these pieces of software are free software and freely available. <br />
+All these pieces of software are Free Software and as such freely available. <br />
 
 <br />
 
@@ -88,9 +88,9 @@ To run Chamilo <span style="font-weight: bold;">LMS</span> on your server, you n
   <li>To install <span style="font-weight: bold;">WAMP</span> (AMP on Windows), we recommend the <a href="http://www.apachefriends.org/en/xampp.html">XAMPP</a> .exe installer<a href="http://www.apachefriends.org/en/xampp.html"></a></li>
 
   <li>To install <span style="font-weight: bold;">LAMP</span>
-(AMP on Linux), use the Package manager of your favourite distribution (Synaptic, RPMFinder etc.).
-For instance, on a Ubuntu server,&nbsp;use Shell or Synaptic following the
-    <a href="http://ubuntuguide.org/wiki/Ubuntu:Feisty#Apache_HTTP_Server">Ubuntuguide on Apache</a> and the following sections</li>
+(AMP on Linux), use the Package manager of your favourite distribution (Synaptic, RPMFinder, APT, YUM, etc.).
+For instance, on an Ubuntu server,&nbsp;use apt-get from the Shell or Synaptic from the GUI following the
+    <a href="https://help.ubuntu.com/lts/serverguide/httpd.html">Ubuntu Server Guide about Apache</a> and the following sections</li>
 
   <li>To install <span style="font-weight: bold;">MAMP</span> (AMP on Mac OS X), refer to the <a href="http://www.mamp.info/en/index.php">MAMP</a> dedicated website<a href="http://www.mamp.info/en/index.php"></a></li>
   <li>Make sure you check the <a href="dependencies.html" title="Dependencies">Dependencies page</a> if you need to know the requirements in more precise way.
@@ -105,13 +105,12 @@ For instance, on a Ubuntu server,&nbsp;use Shell or Synaptic following the
 You will need a login and password allowing to manage and create 
 a database. Usually, the default configuration on local computers is to allow you to connect as root with an empty password. It is highly recommended to change the password and define a user with access to only a specific database. Please refer to the MySQL or MariaDB documentation in order to do this.<br />
 <span class="muted">Note that this has been greatly simplified since version 1.9, as it 
-previously required to choose between multiple databases and a deprecated
-single-database mode.</span><br />
+previously required to choose between multiple databases and a deprecated single-database mode.</span><br />
 
 <hr style="width: 100%; height: 2px;" />
 <h2><a name="2._Installation_of_Chamilo_LMS"></a><span style="font-weight: bold;">2. Installation of Chamilo LMS</span></h2>
-<h3>Configuring your web server to allow overrides</h3>
-If you are using Apache, and due to new friendly URL features added in 1.10, you will be required to <b>AllowOverride All</b> (and possibly install the ModRewrite extension for Apache). This means that, inside your Apache configuration (or your VirtualHost configuration), you will need to have a block similar to this (the directory given is the same as in the <i>DocumentRoot</i> directive):
+<h3>Configuring your web server to allow .htaccess overrides</h3>
+Starting from 1.10, Chamilo LMS allows friendly URLs if using Apache. As it is based on .htaccess and rewrites, you will be required to <b>AllowOverride All</b> (and possibly enable the ModRewrite extension for Apache). This means that, inside your Apache configuration (or your VirtualHost configuration), you will need to have a block similar to this (the directory given is the same as in the <i>DocumentRoot</i> directive):
 <pre>
   &lt;Directory /var/www/chamilo&gt;
     Options Indexes FollowSymLinks MultiViews
@@ -121,79 +120,76 @@ If you are using Apache, and due to new friendly URL features added in 1.10, you
   &lt;/Directory&gt;
 </pre>
 <p>
-In particular, the "AllowOverride All" clause is the one that matters. This will allow PHP to send the user from one page to another freely, thus allowing for more user-friendly URLs.<br />
-Once you've made sure "AllowOverride" says "All", you can safely save the file, get out of it and reload the web server (<i>sudo service apache2 reload</i> under Debian/Ubuntu, or click right on the WAMP/XAMP/EasyPHP icon and "reload web server" under Windows).</p>
+In particular, the "AllowOverride All" clause is the one that matters. This will allow PHP to send the user from one page to another freely, thus allowing for friendlier URLs.<br />
+Once you've made sure "AllowOverride" says "All", you can safely save the file, get out of it and reload the web server (<i>sudo service apache2 reload</i> under Debian/Ubuntu, orright-click on the WAMP/XAMP/EasyPHP icon and "reload web server" under Windows).</p>
 <p>
-Please note that, if you are using Chamilo in a subdirectory (for example, you load it in your browser as http://localhost/chamilo/ or http://yoursite.com/chamilo/, you will also need to alter the .htaccess file in the root directory of Chamilo, <b>before</b> you proceed with the installation.<br />
-On the RewriteBase line, where it normally says "/", change it to whatever subdirectory you are using. In the same case as above, your RewriteBase will have to say "chamilo/" (without the quotes).
+Please note that, if you are using Chamilo LMS in a subdirectory (for example, you load it in your browser as http://localhost/chamilo/ or http://yoursite.com/chamilo/, you will also need to alter the .htaccess file in the root directory of Chamilo, <b>before</b> you proceed with the installation.<br />
+On the RewriteBase line, where it normally says "/", change it to whatever subdirectory name you are using. In the default case described above, your RewriteBase will have to say "chamilo/" (without the quotes).
 </p>
 <h3>Downloading and installing Chamilo</h3>
 <ol>
-  <li><a href="http://www.chamilo.org/download">Download Chamilo LMS</a></li>
+  <li><a href="http://www.chamilo.org/en/download">Download Chamilo LMS</a></li>
   <li>Unzip it</li>
   <li>Copy the Chamilo directory in your Apache web directory. This can be
     <span style="font-weight: bold;">C:\xampp\htdocs\</span> on a Windows server or <span style="font-weight: bold;">/var/www/html/</span> (or /var/www/chamilo/) on a Linux server</li>
   <li>Open your web browser (Internet Explorer, Firefox...) and type
-    <span style="font-weight: bold;">http://localhost/chamilo/</span> if you install locally or
-    <span style="font-weight: bold;">http://www.domain.com/chamilo/</span> if you install remotely. <span class="muted">We recommend defining a specific Virtual Host for this installation if you have the skills to do so</span>
+    <span style="font-weight: bold;">http://localhost/chamilo/</span> if installing locally or
+    <span style="font-weight: bold;">http://www.domain.com/chamilo/</span> if installing remotely. <span class="muted">We recommend defining a specific Virtual Host for this installation if you have the skills to do so</span>
     </li>
 
-  <li>Follow the web installation process. You can accept all default
-values. Consider changing the admin password to remember it.&nbsp;</li>
+  <li>Process through the web installation process. You can safely accept all default values. Consider changing the admin password to remember it.</li>
 </ol>
 <br />
-The following directories need to be readable, writeable and executable by your web server. 
-<span class="muted">This usually requires no specific action on Windows servers, but will require a "chmod" under Linux and Mac. See instructions below.</span><br />Replace [chamilo] with the directory where your Chamilo installation is located):
+Only the following directories need to be readable, writeable and executable by your web server. 
+<span class="muted">This usually requires no specific action on Windows servers, but will require a "chmod" under Linux/UNIX and Mac. See instructions below.</span>
+<br />Replace [chamilo] with the directory where your Chamilo installation is located:
 <ul>
-  <li>[chamilo]/main/inc/conf/</li>
-  <li>[chamilo]/main/upload/users/</li>
-  <li>[chamilo]/main/default_course_document/images/</li>
-  <li>[chamilo]/archive/</li>
-  <li>[chamilo]/courses/</li>
-  <li>[chamilo]/home/</li>
+  <li>[chamilo]/config</li>
+  <li>[chamilo]/data</li>
+  <li>[chamilo]/logs</li>
+  <li>[chamilo]/temp</li>
+  <li>[chamilo]/main/default_course_document/images</li>
 </ul>
-Optionally, you can do the same to the following directories if you want to
-enable CSS styles package upload and sub-language definition:
+Optionally, you can do the same to the following directories if you want to enable CSS styles package upload and sub-language definition:
 <ul>
   <li>[chamilo]/main/css/</li>
   <li>[chamilo]/main/lang/</li>
 </ul>
 Since Chamilo 1.8.8, you can also enable full-text indexing features which 
 require the php5-xapian PHP's extension module to be installed. If you do use 
-it, you will need to allow your system to write into the sarchdb directory:
+it, you will need to allow your system to write into the searchdb directory:
 <ul>
-  <li>[chamilo]/searchdb</li>
+  <li>[chamilo]/data/searchdb</li>
 </ul> 
 If you find a tests/ directory at the root of your package, please delete it. 
-This is a development directory that has not been checked for security issues, 
+This is a development directory (automated tests) that has not been checked for security issues, 
 an it should *never* be accessible to final users on a production server. 
 
 <p>On Linux, Mac OS X and BSD operating systems you can use the <em>chmod
-0775</em> command for this (although we recommend you seek advice from an
+0775</em> command to this end (although we recommend you seek advice from an
 experienced system administrator to avoid security issues).
-On Windows, you may need to check the properties of the folders (by
-right-clicking on them).</p>
+On Windows, you may need to check the permissions of the folders (right-clicking on them).</p>
 
 <p>The following directory needs to be readable and writeable for the web browser
 <em>only</em> during the installation process:</p>
 <ul>
-  <li>chamilo/main/inc/conf/ (if present)</li>
+  <li>[chamilo]/config (if present)</li>
 </ul>
 
 <p>On Linux, Mac OS X and BSD operating systems you can use the <em>chmod
 666</em> command for this (although we recommend you seek advice from an
 experienced system administrator).
-In Windows, you may need to check the properties of the files and
-folders (by right-clicking on them).</p>
+In Windows, you may need to check the permissions of the files and
+folders (right-clicking on them).</p>
 
 <p>
 <b>NOTES:</b><br />
 
-Do not modify the home_*.html files directly. Instead,
+Do not edit the home_*.html files directly. Instead,
 choose "Configure the homepage" in the Chamilo administration section.</p>
 
 <p><span style="font-weight: bold;">Windows</span> : with all-in-one packages 
-like XAMPP, you can install Chamilo easily. In this case (and unless you use it
+like XAMPP, you can easily install Chamilo. In this case (and unless you use it
 in production), the login and password for MySQL will probably remain empty.</p>
 
 <p></p>
@@ -205,40 +201,39 @@ in production), the login and password for MySQL will probably remain empty.</p>
 
   <li><strong>Protect your configuration directory: </strong>
 make sure no one (but you) can overwrite it. You can find the config directory in 
-<em>(chamilo folder)</em>/main/inc/conf.
-Make it read-only (windows/xwindows: right-click the file to edit the
-properties. linux/bsd/macosx: use the chmod 0555 command). The config
+<em>[chamilo]</em>/config
+Make it read-only (Windows: right-click the file to edit its
+permissions. Linux/UNIX/MacOsX: use the ""chmod 0555" command). The config
 file is created by your web server (Apache + PHP, usually) so you may 
-need to be root user to change its permissions.</li>
+need to be a privileged user to change its permissions afterwards.</li>
 
   <li><strong>Protect your installation folder: </strong>
-if the <em>(chamilo folder)</em>/main/install
+if the <em>[chamilo]</em>/main/install
 folder is still accessible, someone could install over your existing
 version (you could lose your data that way). Move the folder somewhere
-out of the web directories so it is not accessible, change its name, 
-delete it completely or edit its properties so no one can read or 
+out of the web directories so it is no longer accessible, rename it, 
+delete it completely or edit its permissions so no one can read or 
 execute it.</li>
 
   <li><strong>For better security: </strong>
 making the files world-writeable will help you install, and it solves many
-issues for people without much admin experience. However, it's more
-secure to make a distinct user owner of all the chamilo files and folders, 
+issues for people without much sysadmin experience. Be aware though that it is more
+secure to create a distinct user owning all the Chamilo files and folders, 
 and only give read access to the web server to all files, and write access 
 only to the directories previously mentioned. This way, these files need 
 only be readable and writeable by the Apache process owner, not by the 
-entire world. It would also be adviseable to make all writeable directory
+entire world. It would also be adviseable to make all writeable directories
 refuse the interpretation of PHP files (except for the root of the courses
-directories). Don't hesitate to hire an experienced administrator to do that,
-it might be a bit more expensive now, but you'll be happy not to have to loose
-all of your data to a hacker who attacked your site.</li>
+directories). Don't hesitate to hire an experienced administrator to do that, you'd be happy not to lose
+all of your data in case a hacker ever attacks your site.</li>
 
   <li><strong>Configure your Chamilo installation: </strong>
 in the administration section of Chamilo, you can use the Chamilo Configuration Settings to adjust the behavior of your installation.</li>
 
   <li><strong>Configure Chamilo mail: </strong>
-most of Chamilo uses the mail settings from the php.ini file. However,
-if you use a distinct e-mail server, you might need to adjust the
-e-mail setting in <em>(chamilo folder)</em>/main/inc/conf/mail.conf.php.</li>
+Chamilo uses the mail settings from your PHP configuration file (php.ini) by default. However,
+if you want to use a distinct e-mail server, you might need to adjust the
+e-mail setting in <em>[chamilo]</em>/config/mail.conf.php.</li>
 
   <li>Check our new <a href="./security.html">security guide</a> for more</li>
 </ul>
@@ -246,31 +241,48 @@ e-mail setting in <em>(chamilo folder)</em>/main/inc/conf/mail.conf.php.</li>
 <br />
 
 
-<h3>PHP configuration</h3>
-
+<h3>PHP requirements and configuration</h3>
 
-To get the best out of Chamilo, you need to finetune your PHP settings. Consider : <br />
+Chamilo LMS requires the following PHP extensions:
+<ul>
+	<li><a href="http://www.php.net/manual/en/pcre.installation.php" target="_blank">PCRE</a> (enabled by default since PHP 4.2)</li>
+	<li><a hrer="http://www.php.net/manual/en/session.installation.php" target="_blank">session</a> (enabled by default since the creation of PHP)</li>
+	<li><a href="http://www.php.net/manual/en/json.installation.php" target="_blank">json</a> (enabled by default since PHP 5.2)</li>
+	<li><a href="http://www.php.net/manual/en/image.installation.php" target="_blank">gd</a> (not enabled by default)</li>
+	<li><a href="http://www.php.net/manual/en/mysql.installation.php" target="_blank">mysql</a> or <a href="http://www.php.net/manual/en/mysqlnd.install.php" target="_blank">mysqlnd</a> (neither of these is enabled by default, but we recommend mysqlnd for higher efficiency, mysql also being deprecated starting from PHP 5.5)</li>
+	<li><a href="http://www.php.net/manual/en/mbstring.installation.php" target="_blank">mbstring</a> (not enabled by default)</li>
+	<li><a href="http://www.php.net/manual/en/zlib.installation.php" target="_blank">zlib</a> (NOT enabled by default)</li>
+</ul>
 
+And optionally (for more features) the following PHP modules:
 <ul>
+	<li><a href="http://www.php.net/manual/en/curl.installation.php" target="_blank">curl</a> (required for links checking in the links tool)</li>
+	<li><a href="http://www.php.net/manual/en/iconv.installation.php" target="_blank">iconv</a> (enabled by default, it is used as a second option to mbstring, required above, but Symfony components depend on mbstring only, so this recommendation might be removed in the future)</li>
+	<li><a href="http://www.php.net/manual/en/ldap.installation.php" target="_blank">ldap</a> (required only if you use LDAP authentication)</li>
+	<li><a href="http://xapian.org/download" target="_blank">xapian</a> (required only to use the text indexing feature - see further down this installation guide for install instructions)</li>
+	<li><a href="http://www.php.net/manual/en/imagick.installation.php" target="_blank">imagick</a> (generates better images thumbnails when using the text indexing feature requiring the Xapian extension)</li>
+</ul>
 
-  <li>Editing php.ini file (on windows can be located at 
+To get the best out of Chamilo, you need to finetune your PHP settings. Consider : <br />
+<ul>
+  <li>Editing php.ini file (on Windows can be located at 
   <span style="font-weight: bold;">C:\xampp\php\php.ini</span>, 
-  on Ubuntu Linux : 
+  on Ubuntu : 
   <span style="font-weight: bold;">/etc/php5/apache2/php.ini</span></li>
-  <li>search the word "_max" and increase the two values to optimise the server</li>
+  <li>search the word "_max" and increase the two values (post_max_size and upload_max_filesize) to optimise the server</li>
   <li>we recommend the following values : </li>
 </ul>
 
-<div class="code">
-      max_execution_time = 300; Maximum execution time of each script, in seconds<br />
-      max_input_time = 600; Maximum amount of time each script may spend parsing request data<br />
-      memory_limit = 256M; Maximum amount of memory a script may consume (128MB)<br />
-      post_max_size = 100M<br />
-      upload_max_filesize = 100M<br />
-</div>
+<ul>
+  <li>max_execution_time = 300; Maximum execution time of each script, in seconds</li>
+  <li>max_input_time = 600; Maximum amount of time each script may spend parsing request data</li>
+  <li>memory_limit = 256M; Maximum amount of memory a script may consume (128MB)</li>
+  <li>post_max_size = 100M</li>
+  <li>upload_max_filesize = 100M</li>
+  <li>session.cookie_httponly = On</li>
+</ul>
 
-<p>Some users could meet problems if their PHP settings don't match
-these ones:</p>
+<p>Some users could meet problems if their PHP settings don't match the following:</p>
 
 <ul>
   <li>short_open_tag       = Off</li>
@@ -278,16 +290,17 @@ these ones:</p>
   <li>magic_quotes_gpc     = Off</li>
   <li>magic_quotes_runtime = Off</li>
 </ul>
+On any recent Debian/Ubuntu, just copying those lines into a new .ini file installed in /etc/php5/conf.d/ (e.g. /etc/php5/conf.d/chamilo.ini) and reloading Apache's config (i.e. "sudo service apache2 reload") would do the trick. Any later php.ini modification in this documentation could/should subsequently as well be applied in this file instead.
 
 <p>
-Past Chamilo versions required register_globals to be set to On. This is
-no longer necessary, this can (and should) be set to Off. 
+Past Chamilo releases required register_globals to be set to On. This is
+no longer necessary, and should preferably be set to Off. 
 <span class="muted">It is considered a bad choice in terms of security to set register_globals to On.</a></p>
 
-<p><strong>Note:</strong> if you are using PHP 5.3 or higher, you need to set 
+<p><strong>Note:</strong> if using PHP 5.3 or higher, you also need to set 
 your <em>date.timezone</em> setting to whatever your server's timezone is.
 For example, if your server is in the 'America/New_York' timezone, set this 
-in your php.ini:</p>
+in your PHP .ini file:</p>
 
 <div class="code">
 date.timezone = 'America/New_York'
@@ -295,8 +308,8 @@ date.timezone = 'America/New_York'
 
 <p><strong>Note:</strong> PHP 5.3.9 introduces a new setting "max_input_vars", which limits the number of elements you can send in one single form. If you are dealing with numerous users, make sure you set this setting higher than its default value of 1000.</p>
 
-<p><strong>BSD users:</strong> these php libraries have to be included during
- php installation:</p>
+<p><strong>BSD users:</strong> according to the requirements, the following PHP libraries have to be included during
+ PHP installation:</p>
 
 <ul>
   <li>php5-mysql The mysql shared extension for php</li>
@@ -310,6 +323,7 @@ date.timezone = 'America/New_York'
 <ul>
     <li>php5-ctype</li>
     <li>php5-gd</li>
+    <li>php5-imagick</li>
     <li>php5-iconv</li>
     <li>php5-json</li>
     <li>php5-mbstring</li>
@@ -349,7 +363,7 @@ As this is only a minor version change from previous 1.9.* versions of Chamilo,
   <li> check that you haven't left any customised stylesheet or image <span class="muted">(if you have, make sure you keep a copy on the side*)</span></li>
   <li> download the Chamilo 1.9 install package from the <a href="http://www.chamilo.org/download">Chamilo download page</a></li>
   <li> unzip the new files of Chamilo 1.9 over the files of the older version (or unzip the files in one folder and then copy the files from there to the older version's directory)</li>
-  <li> edit the main/inc/conf/configuration.php file: at the en of the file, locate the previous version number (e.g. '1.9.2') and change it to this new version (e.g. '1.9.4')</li>
+  <li> edit the main/inc/conf/configuration.php file: at the end of the file, locate the previous version number (e.g. '1.9.2') and change it to this new version (e.g. '1.9.4')</li>
   <li> you're done! No other upgrade procedure is required</li>
 </ul>
 
@@ -457,12 +471,11 @@ choose "Configure the homepage" in the Chamilo administration section.</p>
 
 The following directories need to be readable, writeable and executable for the web server:
 <ul>
-  <li>chamilo/main/inc/conf/</li>
-  <li>chamilo/main/upload/users/</li>
+  <li>chamilo/config</li>
+  <li>chamilo/data</li>
+  <li>chamilo/logs</li>
+  <li>chamilo/temp</li>
   <li>chamilo/main/default_course_document/</li>
-  <li>chamilo/archive/</li>
-  <li>chamilo/courses/</li>
-  <li>chamilo/home/</li>
 </ul>
 
 On Linux, Mac OS X and BSD operating systems you can quick-fix this using the

+ 35 - 44
documentation/installation_guide_es_ES.html

@@ -20,15 +20,15 @@
             <ul class="nav">
                 <li><a href="index.html">Home</a></li>
                 <li ><a href="readme.html">About</a></li>
-                <li ><a href="license.html">License</a></li>            
-                <li><a href="credits.html">Credits</a></li>            
-                <li><a href="dependencies.html">Dependencies</a></li>            
+                <li ><a href="license.html">License</a></li>
+                <li><a href="credits.html">Credits</a></li>
+                <li><a href="dependencies.html">Dependencies</a></li>
                 <li><a href="changelog.html">Changelog</a></li>
-            </ul>        
+            </ul>
             </div><!--/.nav-collapse -->
         </div>
     </div>
-</div>    
+</div>
 
 
 <div class="container">
@@ -36,25 +36,18 @@
     <li>
         <a href="index.html">Documentación</a>
         <span class="divider">/</span>
-    </li>    
+    </li>
     <li>Guía de Instalación</li>
-</ul>   
+</ul>
 <h1>Chamilo 1.9 - Guía de Instalación</h1>
 
 <p>Gracias por descargar Chamilo, la suite de aprendizaje de código abierto profesional.</p>
-<ul>  
+<ul>
   <li>Prueba Chamilo en <a href="http://campus.chamilo.org">nuesto Campus libre</a></li>
 </ul>
-
-
 <p>Esta guía explica como instalar Chamilo LIBRE. Por favor, léala completamente antes de proceder con la instalación.</p>
-
-
-
 <h2><b>Contenidos</b></h2>
-
 <ol>
-
   <li><a href="#1._Pre-requisites">Prerrequisitos</a></li>
   <li><a href="#2._Installation_of_Chamilo_LMS">Instalación de Chamilo LMS</a></li>
   <li><a href="#3._Upgrade_from_a_previous_version_of">Actualizar desde una versión previa de Chamilo o Dok€os</a></li>
@@ -127,12 +120,10 @@ Los siguientes directorios necesitan tener permisos de lectura, escritura y ejec
 <p>
 Remplace [chamilo] por el directorio en el cual está ubicado su Chamilo:
 <ul>
-  <li>[chamilo]/main/inc/conf/</li>
-  <li>[chamilo]/main/upload/users/</li>
-  <li>[chamilo]/main/default_course_document/images/</li>
-  <li>[chamilo]/archive/</li>
-  <li>[chamilo]/courses/</li>
-  <li>[chamilo]/home/</li>
+  <li>[chamilo]/config/</li>
+  <li>[chamilo]/data/</li>
+  <li>[chamilo]/temp/</li>
+  <li>[chamilo]/logs/</li>
 </ul>
 Opcionalmente, puede hacer lo mismo a los directorios siguientes si desea
 activar la subida de paquetes de estilos CSS y la definición de sub-idiomas:
@@ -145,7 +136,7 @@ activar la subida de paquetes de estilos CSS y la definición de sub-idiomas:
 <p>
 Desde Chamilo 1.8.8, también puede habilitar funciones de indexación de texto completo que requieren la instalación de la extensión del módulo PHP php5-xapian. Si usted hace uso de él, usted tendrá que permitir que el sistema pueda escribir en el directorio searchdb:
 <ul>
-<li>[chamilo]/searchdb</li>
+<li>[chamilo]/data/searchdb</li>
 </ul>
 </p>
 <p>
@@ -190,7 +181,7 @@ seleccione "Configurar la página de inicio" en la sección de administración d
   <li><strong>Proteger su directorio de instalación: </strong>si el (directorio de Chamilo) directorio /main/install sigue accesible, alguien podría instalar de nuevo sobre la versión existente (usted puede perder sus datos de esta manera). Por ello es muy importante que mueva el directorio a algún lugar fuera de los directorios web para que no se encuentre accesible, cambie su nombre, bórrelo completamente o edite sus propiedades para que nadie pueda leerlo o ejecutarlo.</li>
 
   <li><strong>Para mayor seguridad: </strong> hacer que todos los archivos posean permisos de escritura facilita la instalación y resuelve muchas dudas a las personas con poca experiencia en administración. Sin embargo, es más seguro hacer que el propietario de los archivos y carpetas de Chamilo sea un usuario distinto y conceder sólo al servidor web permisos de lectura sobre todos los ficheros, y permisos de escritura a los directorios previamente mencionados. De esta manera, estos archivos sólo necesitan ser accesibles y escribibles por el propietario el proceso Apache, no por el mundo entero. También sería recomendable hacer que todos los directorios con permisos de escritura rechazaran la interpretación de los archivos PHP ( a excepción de la raíz de los directorios de cursos). No dude en contratar a un administrador con experiencia para hacer eso, puede que sea un poco más caro ahora, pero estará feliz de no tener que perder todos sus datos por el ataque de un hacker a su sitio.</li>
-  
+
   <li><strong>Configurar su instalación de Chamilo: </strong>
 en la sección de administración de Chamilo, usted puede usar las Opciones de Configuración de Chamilo para ajustar el comportamiento de su instalación.</li>
 
@@ -213,11 +204,11 @@ Para obtener lo mejor de Chamilo, necesita ajustar la configuración de PHP. Con
 </ul>
 </p>
 <div class="code">
-			  max_execution_time = 300 ;Tiempo máximo de ejecucion para cada script, en segundos<br />
-			  max_input_time = 600 ;Tiempo máximo que cada script que puede emplear para analizar los datos solicitados<br />
-			  memory_limit = 256M ;Maxima cantidad de memoria que un script puede consumir (128MB)<br />
-			  post_max_size = 100M<br />
-			  upload_max_filesize = 100M
+    max_execution_time = 300 ;Tiempo máximo de ejecucion para cada script, en segundos<br />
+    max_input_time = 600 ;Tiempo máximo que cada script que puede emplear para analizar los datos solicitados<br />
+    memory_limit = 256M ;Maxima cantidad de memoria que un script puede consumir (128MB)<br />
+    post_max_size = 100M<br />
+    upload_max_filesize = 100M
 </div>
 
 <p>
@@ -259,7 +250,7 @@ date.timezone = 'America/Lima'
 <li>php-ctype</li>
 <li>php-gd</li>
 <li>php-iconv</li>
-<li>php-json</li> 
+<li>php-json</li>
 <li>php-mbstring</li>
 <li>php-intl</li>
 <li>php-curl</li>
@@ -369,7 +360,7 @@ directorio actual de la versión antigua</li>
 </p>
 <p>
 <em> NOTA: </em> La actualización desde 1.6.x a 1.9.x implica una revisión de
-los gráficos y estilos personalizados. La nueva versión usa un completo nuevo conjunto 
+los gráficos y estilos personalizados. La nueva versión usa un completo nuevo conjunto
 de iconos y estilos, lo cual significa que aquellos provenientes de la versión 1.6 no pueden ser
 simplemente reusados. La buena noticia es que la versión 1.9.x le permite crear
 su propio estilo en un directorio css separado, el cual se puede reusar en
@@ -603,9 +594,9 @@ Usted puede habilitar la escritura de ecuaciones matemáticas dentro del editor
 	(existe un FCKConfig.ToolbarSets por herramienta). Por ejemplo:
 	        <div class="code">FCKConfig.ToolbarSets["Test"] = [<br />
 	['Bold','Italic','Underline','StrikeThrough','Subscript','Superscript','Link','Unlink','ImageManager','MP3','OrderedList','UnorderedList','Table','mimetex']<br />
-	
+
 	] ;</div>
-	
+
 	        Usted puede agregarlo a todas las herramientas, o sólo a alguna de ellas (por ej., documentos y ejercicios)<br />
 	        <br />
 			</li>
@@ -617,34 +608,34 @@ Usted puede habilitar la escritura de ecuaciones matemáticas dentro del editor
     <li>6. Realice estos cambios:
 
 	<i>Agregar el directorio cgi-bin correspondiente a su configuración de Apache puede ser realizada de esta manera, en Apache 2:</i>
-	
+
 	<div class="code">
 			  ScriptAlias /cgi-bin/ /var/www/cgi-bin/<br />
-	
+
 	  &lt;Directory "/var/www/cgi-bin"&gt;<br />
-	
+
 	        &nbsp;&nbsp;AllowOverride None<br />
-	
+
 	        &nbsp;&nbsp;Options ExecCGI -MultiViews +SymLinksIfOwnerMatch<br />
-	
+
 	        &nbsp;&nbsp;Order allow,deny<br />
-	
+
 	        &nbsp;&nbsp;Allow from all<br />
-	
+
 	  &lt;/Directory&gt;<br />
-	
+
 		</div>
-	
-	
+
+
 	<i>Agregar un enlace simbólico bajo Windows, puede ser realizado mediante la creación de un
 	acceso directo al archivo mimetex.exe desde el directorio cgi-bin, o bajo
 	Linux usando el siguiente comando:</i>
-	
+
 	<div class="code">ln -s /var/www/chamilo/main/inc/lib/mimetex/mimetex.cgi /var/www/cgi-bin/mimetex.cgi</div>
 	<p>Si no quiere modificar su Apache, alternativamente a  este punto 6: copie mimetex.exe (para Windows) o mimetex.cgi (para Linux) en su cgi-bin/ </p>
 	<p>&nbsp;</p>
 	</li>
-	
+
 	<li>7. Asegurarse que el archivo mimetex.cgi (o mimetex.exe) ha sido subido al servidor usando el formato BINARY. Es posible que el servidor de un error 500 cuando se intenta entrar a cgi-bin/mimetex.cgi a pesar de que los permisos están correctos.
 	   Probar volviendo a subir el archivo usando FTP (ASCII format) o si no usando el "administrador de archivos" o CPanel. Si el error persiste contactar con el administrador del servidor para habilitar el acceso público del archivo cgi-bin/mimetex.cgi.
 	</li>

+ 2 - 0
global.inc.php

@@ -0,0 +1,2 @@
+<?php
+/*  File needed because all files include the "require_once '../inc/global.inc.php'" */

+ 3 - 0
htaccess-dist

@@ -15,6 +15,9 @@
     RewriteRule ^courses/(.*)/index.php$ web/courses/$1? [R,L]
     RewriteRule ^courses/(.*)/$ web/courses/$1? [R,L]
 
+    # PHP Main files are redirected to the "web/main" zone
+    RewriteRule ^main/(.*)\.php web/main/$1.php [R,L]
+
     # Courses documents
     # courses/MATHS/document/folder1/picture.jpg --> web/data/courses/MATHS/document/folder1/picture.jpg
     RewriteRule ^courses/(.*)/document/(.*)$ web/data/courses/$1/document/$2 [R,L]

+ 2 - 0
inc/global.inc.php

@@ -0,0 +1,2 @@
+<?php
+/*  File needed because all files include the "require_once '../inc/global.inc.php'" */

+ 2 - 2
main/admin/archive_cleanup.php

@@ -29,7 +29,7 @@ $message = null;
 if ($form->validate()) {
 	$archive_path = api_get_path(SYS_ARCHIVE_PATH);
 	$htaccess 	  = @file_get_contents($archive_path.'.htaccess');
-	$result 	  = rmdirr($archive_path, true);
+	$result 	  = api_rmdirr($archive_path, true);
 
 	if (!empty($htaccess)) {
 		@file_put_contents($archive_path.'/.htaccess', $htaccess);
@@ -63,4 +63,4 @@ if (!empty($message)) {
     echo $message;
 }
 $form->display();
-Display::display_footer();
+Display::display_footer();

+ 7 - 7
main/admin/calendar.php

@@ -100,7 +100,7 @@ if (!empty($_GET['sort']) and ($allow_individual_calendar_status=="show"))
 $htmlHeadXtra[] = to_javascript();
 
 // this loads the javascript that is needed for the date popup selection
-$htmlHeadXtra[] = "<script src=\"calendar_tbl_change.js\" type=\"text/javascript\" language=\"javascript\"></script>";
+$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/calendar/calendar_tbl_change.js" type="text/javascript" ></script>';
 
 // setting the name of the tool
 $nameTools = get_lang('GlobalAgenda'); // language variable in trad4all.inc.php
@@ -124,7 +124,7 @@ $TABLEAGENDA 			= Database::get_main_table(TABLE_MAIN_SYSTEM_CALENDAR);
 $tbl_user       		= Database::get_main_table(TABLE_MAIN_USER);
 $tbl_courseUser 		= Database::get_main_table(TABLE_MAIN_COURSE_USER);
 
-/* 
+/*
   			ACCESS RIGHTS
 */
 // permission stuff - also used by loading from global in agenda.inc.php
@@ -185,12 +185,12 @@ echo '<div class="sort" style="float:right">';
 echo '</div>';
 if (api_is_allowed_to_edit(false,true)) {
 	switch ($_GET['action']) {
-		case "add":            
-            if ($_POST['submit_event']) {		        
+		case "add":
+            if ($_POST['submit_event']) {
 			    $event_start    = (int) $_POST['fyear'].'-'.(int) $_POST['fmonth'].'-'.(int) $_POST['fday'].' '.(int) $_POST['fhour'].':'.(int) $_POST['fminute'].':00';
                 $event_stop     = (int) $_POST['end_fyear'].'-'.(int) $_POST['end_fmonth'].'-'.(int) $_POST['end_fday'].' '.(int) $_POST['end_fhour'].':'.(int) $_POST['end_fminute'].':00';
-                
-				$id = agenda_add_item($_POST['title'],$_POST['content'],$event_start,$event_stop);           
+
+				$id = agenda_add_item($_POST['title'],$_POST['content'],$event_start,$event_stop);
 				display_agenda_items();
 			} else {
 				show_add_form();
@@ -200,7 +200,7 @@ if (api_is_allowed_to_edit(false,true)) {
 		case "edit":
 			if( ! (api_is_course_coach() && !api_is_element_in_the_session(TOOL_AGENDA, intval($_REQUEST['id']) ) ) )
 			{ // a coach can only delete an element belonging to his session
-				if ($_POST['submit_event']) {		
+				if ($_POST['submit_event']) {
 			        $my_id_attach = (int)$_REQUEST['id_attach'];
 					$my_file_comment = Database::escape_string($_REQUEST['file_comment']);
 					store_edited_agenda_item($my_id_attach,$my_file_comment);

+ 3 - 7
main/admin/calendar_view.php

@@ -90,8 +90,10 @@ table.calendar .monthyear a:hover
 	background-color: #ffff00;
 }
 </style>
+
+<script src=<?php echo api_get_path(WEB_LIBRARY_PATH).'javascript/calendar/calendar_tbl_change.js'; ?>" type="text/javascript" ></script>
+
 <script type="text/javascript">
-<!--
     /* added 2004-06-10 by Michael Keck
      *       we need this for Backwards-Compatibility and resolving problems
      *       with non DOM browsers, which may have problems with css 2 (like NC 4)
@@ -120,11 +122,6 @@ table.calendar .monthyear a:hover
             }
         } // end if... else if...
     } // end if
-//-->
-</script>
-<script type="text/javascript" src="calendar_tbl_change.js"></script>
-<script type="text/javascript">
-<!--
 var month_names = new Array(
 <?php
 foreach($MonthsLong as $index => $month)
@@ -141,7 +138,6 @@ foreach($DaysShort as $index => $day)
 }
 ?>
 "");
-//-->
 </script>
 </head>
 <body onLoad="initCalendar();">

+ 2 - 2
main/admin/configure_homepage.php

@@ -87,7 +87,7 @@ if (api_is_multiple_url_enabled()) {
     if ($access_url_id != -1) {
         $url_info = api_get_access_url($access_url_id);
         $url = api_remove_trailing_slash(preg_replace('/https?:\/\//i', '', $url_info['url']));
-        $clean_url = replace_dangerous_char($url);
+        $clean_url = api_replace_dangerous_char($url);
         $clean_url = str_replace('/', '-', $clean_url);
         $clean_url .= '/';
 
@@ -318,7 +318,7 @@ if (!empty($action)) {
                         '/'
                     ) || !strstr($filename, '.html')
                     ) {
-                        $filename = replace_dangerous_char($link_name, 'strict').'.html';
+                        $filename = api_replace_dangerous_char($link_name, 'strict').'.html';
                     }
                     // "home_" prefix for links are renamed to "user_" prefix (to avoid name clash with existing home page files)
                     if (!empty($filename)) {

+ 2 - 5
main/admin/configure_inscription.php

@@ -70,12 +70,9 @@ if (api_is_multiple_url_enabled()) {
     if ($access_url_id != -1) {
         $url_info = api_get_access_url($access_url_id);
         $url = api_remove_trailing_slash(preg_replace('/https?:\/\//i', '', $url_info['url']));
-
-        $clean_url = replace_dangerous_char($url);
+        $clean_url = api_replace_dangerous_char($url);
         $clean_url = str_replace('/', '-', $clean_url);
         $clean_url .= '/';
-
-
         $homep = api_get_path(SYS_PATH).'home/'; //homep for Home Path
         $homep_new = api_get_path(SYS_PATH).'home/'.$clean_url; //homep for Home Path added the url
         $new_url_dir = api_get_path(SYS_PATH).'home/'.$clean_url;
@@ -86,7 +83,7 @@ if (api_is_multiple_url_enabled()) {
     }
 } else {
     $homep_new = '';
-    $homep = api_get_path(SYS_PATH).'home/'; //homep for Home Path
+    $homep = api_get_path(SYS_DATA_PATH).'home/'; //homep for Home Path
 }
 
 $topf 	 = 'register_top'; //topf for Top File

+ 2 - 1
main/admin/course_create_content.php

@@ -23,7 +23,8 @@ Display::display_header($tool_name);
 if (api_get_setting('server_type') != 'test') {
     echo get_lang('DummyCourseOnlyOnTestServer');
 } elseif (isset($_POST['action'])) {
-    require_once('../coursecopy/classes/DummyCourseCreator.class.php');
+    require_once api_get_path(SYS_CODE_PATH).'coursecopy/classes/DummyCourseCreator.class.php';
+
     $dcc = new DummyCourseCreator();
     $dcc->create_dummy_course($_POST['course_code']);
     echo get_lang('Done');

+ 5 - 3
main/admin/course_list.php

@@ -16,13 +16,15 @@ require_once '../inc/global.inc.php';
 $this_section = SECTION_PLATFORM_ADMIN;
 
 api_protect_admin_script();
-require_once '../gradebook/lib/be/gradebookitem.class.php';
-require_once '../gradebook/lib/be/category.class.php';
+
+require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/be/gradebookitem.class.php';
+require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/be/category.class.php';
 
 /**
  * Get the number of courses which will be displayed
  */
-function get_number_of_courses() {
+function get_number_of_courses()
+{
     $course_table = Database :: get_main_table(TABLE_MAIN_COURSE);
     $sql = "SELECT COUNT(code) AS total_number_of_items FROM $course_table course";
 

+ 4 - 1
main/admin/index.php

@@ -7,6 +7,7 @@
 /**
  * Code
  */
+
 // Language files that need to be included.
 $language_file = array('admin', 'tracking','coursebackup');
 
@@ -86,7 +87,9 @@ if (api_is_platform_admin()) {
 	if (isset($extAuthSource) && isset($extAuthSource['ldap']) && count($extAuthSource['ldap']) > 0) {
 		$items[] = array('url'=>'ldap_users_list.php', 	'label' => get_lang('ImportLDAPUsersIntoPlatform'));
 	}
-	$items[] = array('url'=>'user_fields.php', 	'label' => get_lang('ManageUserFields'));
+	// $items[] = array('url'=>'user_fields.php', 	'label' => get_lang('ManageUserFields'));
+    $items[] = array('url'=>'extra_fields.php?type=user', 	'label' => get_lang('ManageUserFields'));
+    $items[] = array('url'=> api_get_path(WEB_PUBLIC_PATH).'admin/administrator/roles', 	'label' => get_lang('Roles'));
 } else {
  	$items = array(
  		array('url'=>'user_list.php', 	'label' => get_lang('UserList')),

+ 4 - 5
main/admin/ldap_synchro.php

@@ -13,11 +13,10 @@ $language_file = 'admin';
 
 $cidReset = true;
 
-require('../inc/global.inc.php');
+require '../inc/global.inc.php';
 $libpath = api_get_path(LIBRARY_PATH);
-require_once($libpath.'formvalidator/FormValidator.class.php');
-require_once($libpath.'usermanager.lib.php');
-require_once('../auth/ldap/authldap.php');
+require_once api_get_path(SYS_CODE_PATH).'auth/ldap/authldap.php';
+
 $annee_base = date('Y');
 // setting the section (for the tabs)
 $this_section = SECTION_PLATFORM_ADMIN;
@@ -190,4 +189,4 @@ foreach ($Sessions as $session) {
         $sql = "UPDATE $tbl_session SET nbr_users=$nbr_users WHERE id='$id_session'";
         Database::query($sql);
     }
-}
+}

+ 28 - 34
main/admin/settings.lib.php

@@ -1003,7 +1003,28 @@ function delete_template($id) {
     // Display a feedback message.
     Display::display_confirmation_message(get_lang('TemplateDeleted'));
 }
-/*
+/**
+ * Returns the list of timezone identifiers used to populate the select
+ * This function is called through a call_user_func() in the generate_settings_form function.
+ * @return array List of timezone identifiers
+ *
+ * @author Guillaume Viguier <guillaume.viguier@beeznest.com>
+ * @since Chamilo 1.8.7
+ */
+function select_timezone_value() {
+    return api_get_timezones();
+}
+
+/**
+ * Returns an array containing the list of options used to populate the gradebook_number_decimals variable
+ * This function is called through a call_user_func() in the generate_settings_form function.
+ * @return array List of gradebook_number_decimals options
+ *
+ * @author Guillaume Viguier <guillaume.viguier@beeznest.com>
+ */
+function select_gradebook_number_decimals() {
+    return array('0', '1', '2');
+}
 function select_gradebook_default_grade_model_id() {
     $grade_model = new GradeModel();
     $models = $grade_model->get_all();
@@ -1015,7 +1036,7 @@ function select_gradebook_default_grade_model_id() {
         }
     }
     return $options;
-}*/
+}
 
 /**
  * Updates the gradebook score custom values using the scoredisplay class of the
@@ -1025,7 +1046,6 @@ function select_gradebook_default_grade_model_id() {
  *
  * @author Guillaume Viguier <guillaume.viguier@beeznest.com>
  */
-/*
 function update_gradebook_score_display_custom_values($values) {
     require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/scoredisplay.class.php';
     $scoredisplay = ScoreDisplay::instance();
@@ -1040,16 +1060,16 @@ function update_gradebook_score_display_custom_values($values) {
         }
     }
     $scoredisplay->update_custom_score_display_settings($final);
-}*/
+}
 
 /**
  * @param array $settings
  * @param array $settings_by_access_list
  * @return FormValidator
  */
-function generate_settings_form($settings, $settings_by_access_list)
+function generate_settings_form($settings, $settings_by_access_list, $settings_to_avoid, $convert_byte_to_mega_list)
 {
-    global $_configuration, $settings_to_avoid, $convert_byte_to_mega_list;
+    global $_configuration;
     $table_settings_current = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
 
     $form = new FormValidator('settings', 'post', 'settings.php?category='.Security::remove_XSS($_GET['category']));
@@ -1115,10 +1135,10 @@ function generate_settings_form($settings, $settings_by_access_list)
                 if (empty($row['category']))
                     $row['category'] = 0;
 
-                if (is_array($settings_by_access_list[$row['variable']][ $row['subkey']][ $row['category']])) {
+                if (is_array($settings_by_access_list[ $row['variable'] ] [ $row['subkey'] ] [ $row['category'] ])) {
                     // We are sure that the other site have a selected value.
                     if ($settings_by_access_list[ $row['variable'] ] [ $row['subkey'] ] [ $row['category'] ]['selected_value'] != '') {
-                        $row['selected_value'] = $settings_by_access_list[$row['variable']][$row['subkey']][ $row['category']]['selected_value'];
+                        $row['selected_value'] =$settings_by_access_list[$row['variable']] [$row['subkey']] [ $row['category'] ]['selected_value'];
                     }
                 }
                 // There is no else{} statement because we load the default $row['selected_value'] of the main Chamilo site.
@@ -1137,32 +1157,6 @@ function generate_settings_form($settings, $settings_by_access_list)
                     $form->applyFilter($row['variable'], 'html_filter');
                     $default_values[$row['variable']] = $row['selected_value'];
 
-                    // For platform character set selection: Conversion of the textfield to a select box with valid values.
-                } elseif ($row['variable'] == 'platform_charset') {
-                    $current_system_encoding = api_refine_encoding_id(trim($row['selected_value']));
-                    $valid_encodings = array_flip(api_get_valid_encodings());
-                    if (!isset($valid_encodings[$current_system_encoding])) {
-                        $is_alias_encoding = false;
-                        foreach ($valid_encodings as $encoding) {
-                            if (api_equal_encodings($encoding, $current_system_encoding)) {
-                                $is_alias_encoding = true;
-                                $current_system_encoding = $encoding;
-                                break;
-                            }
-                        }
-                        if (!$is_alias_encoding) {
-                            $valid_encodings[$current_system_encoding] = $current_system_encoding;
-                        }
-                    }
-                    foreach ($valid_encodings as $key => &$encoding) {
-                        if (api_is_encoding_supported($key) && Database::is_encoding_supported($key)) {
-                            $encoding = $key;
-                        } else {
-                            unset($valid_encodings[$key]);
-                        }
-                    }
-                    $form->addElement('select', $row['variable'], array(get_lang($row['title']), get_lang($row['comment'])), $valid_encodings);
-                    $default_values[$row['variable']] = $current_system_encoding;
                 } else {
                     $hideme['class'] = 'span4';
                     $form->addElement('text', $row['variable'], array(get_lang($row['title']), get_lang($row['comment'])), $hideme);

+ 2 - 2
main/admin/settings.php

@@ -153,7 +153,7 @@ if (!empty($_GET['category']) && !in_array($_GET['category'], array('Plugins', '
 
     $settings = $settings_array['settings'];
     $settings_by_access_list = $settings_array['settings_by_access_list'];
-    $form = generate_settings_form($settings, $settings_by_access_list);
+    $form = generate_settings_form($settings, $settings_by_access_list, $settings_to_avoid, $convert_byte_to_mega_list);
 
     $message = array();
 
@@ -199,7 +199,7 @@ if (!empty($_GET['category']) && !in_array($_GET['category'], array('Plugins', '
                 $settings_array = get_settings($my_category);
                 $settings = $settings_array['settings'];
                 $settings_by_access_list = $settings_array['settings_by_access_list'];
-                $form = generate_settings_form($settings, $settings_by_access_list);
+                $form = generate_settings_form($settings, $settings_by_access_list, $settings_to_avoid, $convert_byte_to_mega_list);
             }
         }
         $pdf_export_watermark_path = $_FILES['pdf_export_watermark_path'];

+ 10 - 7
main/admin/statistics/index.php

@@ -9,7 +9,7 @@
 $language_file = array('admin', 'tracking');
 $cidReset = true;
 
-require_once '../../inc/global.inc.php';
+// require_once '../../inc/global.inc.php';
 api_protect_admin_script();
 
 $interbreadcrumb[] = array('url' => '../index.php', 'name' => get_lang('PlatformAdmin'));
@@ -63,8 +63,11 @@ foreach ($tools as $section => $items) {
 echo '</tr></table>';
 
 $course_categories = Statistics::get_course_categories();
-echo '<br/><br/>';//@todo: spaces between elements should be handled in the css, br should be removed if only there for presentation
-switch ($_REQUEST['report']) {
+echo '<br/><br/>';
+//@todo: spaces between elements should be handled in the css, br should be removed if only there for presentation
+$report = isset($_GET['report']) ? $_GET['report'] : null;
+
+switch ($report) {
     case 'courses':
         // total amount of courses
         foreach ($course_categories as $code => $name) {
@@ -81,7 +84,7 @@ switch ($_REQUEST['report']) {
         break;
     case 'courselastvisit':
         Statistics::print_course_last_visit();
-        break;    
+        break;
     case 'users':
         // total amount of users
         Statistics::print_stats(
@@ -115,10 +118,10 @@ switch ($_REQUEST['report']) {
         break;
     case 'zombies':
         ZombieReport::create(array('report' => 'zombies'))->display();
-        break;    
+        break;
     case 'activities':
         Statistics::print_activities_stats();
-        break;    
+        break;
     case 'messagesent':
         $messages_sent = Statistics::get_messages('sent');
         Statistics::print_stats(get_lang('MessagesSent'), $messages_sent);
@@ -133,4 +136,4 @@ switch ($_REQUEST['report']) {
         Statistics::print_stats(get_lang('CountFriends'), $friends);
         break;
 }
-Display::display_footer();
+Display::display_footer();

+ 2 - 1
main/admin/system_announcements.php

@@ -65,7 +65,8 @@ $show_announcement_list = true;
 $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : null;
 
 // Form was posted?
-if (isset ($_POST['action'])) {
+$action_todo = false;
+if (isset($_POST['action'])) {
     $action_todo = true;
 }
 

+ 3 - 4
main/admin/user_add.php

@@ -210,6 +210,7 @@ if (isset($drh_list) && is_array($drh_list)) {
 }
 $form->addElement('html', '</div>');
 
+/*
 if (api_is_platform_admin()) {
     // Platform admin
     $group = array();
@@ -219,7 +220,7 @@ if (api_is_platform_admin()) {
     $form->addElement('html', '<div id="id_platform_admin" style="display:'.$display.';">');
     $form->addGroup($group, 'admin', get_lang('PlatformAdmin'), '&nbsp;');
     $form->addElement('html', '</div>');
-}
+}*/
 
 $form->addElement('select_language', 'language', get_lang('Language'), null);
 
@@ -383,9 +384,7 @@ if ($form->validate()) {
                     UserManager::update_extra_field_value($user_id, substr($key, 6), $value);
                 }
             }
-            if ($platform_admin) {
-                UserManager::add_user_as_admin($user_id);
-            }
+
             $message = get_lang('UserAdded');
         }
         if (isset($user['submit_plus'])) {

+ 23 - 20
main/admin/user_fields_add.php

@@ -16,36 +16,39 @@ $this_section=SECTION_PLATFORM_ADMIN;
 // user permissions
 api_protect_admin_script();
 
+$showImg = Display::return_icon('div_show.gif');
+$hideImg = Display::return_icon('div_hide.gif');
+
 $htmlHeadXtra[] = '<script>
 function change_image_user_field (image_value) {
-	
+
 	if (image_value==1) {
 		document.getElementById(\'options\').style.display = \'none\';
-		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;<img style="vertical-align:middle;" src="../img/div_show.gif" alt="" />&nbsp;'.get_lang('AdvancedParameters').'\';
+		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;'.$showImg.'&nbsp;'.get_lang('AdvancedParameters').'\';
 		$("div#id_image_user_field").html("&nbsp;");
 		$("div#id_image_user_field").html('."'<br />".Display::return_icon('userfield_text.png', get_lang('AddUserFields'))."'".');
 
 	} else if (image_value==2) {
 		document.getElementById(\'options\').style.display = \'none\';
-		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;<img style="vertical-align:middle;" src="../img/div_show.gif" alt="" />&nbsp;'.get_lang('AdvancedParameters').'\';
+		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;'.$showImg.'&nbsp;'.get_lang('AdvancedParameters').'\';
 		$("div#id_image_user_field").html("&nbsp;");
 		$("div#id_image_user_field").html('."'<br />".Display::return_icon('userfield_text_area.png', get_lang('AddUserFields'))."'".');
 
 	} else if (image_value==3) {
 		document.getElementById(\'options\').style.display = \'block\';
-		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;<img style="vertical-align:middle;" src="../img/div_hide.gif" alt="" />&nbsp;'.get_lang('AdvancedParameters').'\';				
+		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;'.$hideImg.'&nbsp;'.get_lang('AdvancedParameters').'\';
 		$("div#id_image_user_field").html("&nbsp;");
 		$("div#id_image_user_field").html('."'<br />".Display::return_icon('add_user_field_howto.png', get_lang('AddUserFields'))."'".');
 
 	} else if (image_value==4) {
 		document.getElementById(\'options\').style.display = \'block\';
-		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;<img style="vertical-align:middle;" src="../img/div_hide.gif" alt="" />&nbsp;'.get_lang('AdvancedParameters').'\';		
+		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;'.$hideImg.'&nbsp;'.get_lang('AdvancedParameters').'\';
 		$("div#id_image_user_field").html("&nbsp;");
 		$("div#id_image_user_field").html('."'<br />".Display::return_icon('userfield_drop_down.png', get_lang('AddUserFields'))."'".');
 
 	} else if (image_value==5) {
 		document.getElementById(\'options\').style.display = \'block\';
-		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;<img style="vertical-align:middle;" src="../img/div_hide.gif" alt="" />&nbsp;'.get_lang('AdvancedParameters').'\';		
+		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;'.$hideImg.'&nbsp;'.get_lang('AdvancedParameters').'\';
 		$("div#id_image_user_field").html("&nbsp;");
 		$("div#id_image_user_field").html('."'<br />".Display::return_icon('userfield_multidropdown.png', get_lang('AddUserFields'))."'".');
 
@@ -56,39 +59,39 @@ function change_image_user_field (image_value) {
 
 	} else if (image_value==7) {
 		document.getElementById(\'options\').style.display = \'none\';
-		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;<img style="vertical-align:middle;" src="../img/div_show.gif" alt="" />&nbsp;'.get_lang('AdvancedParameters').'\';		
+		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;'.$showImg.'&nbsp;'.get_lang('AdvancedParameters').'\';
 		$("div#id_image_user_field").html("&nbsp;");
 		$("div#id_image_user_field").html('."'<br />".Display::return_icon('userfield_date_time.png', get_lang('AddUserFields'))."'".');
 
 	} else if (image_value==8) {
 		document.getElementById(\'options\').style.display = \'block\';
-		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;<img style="vertical-align:middle;" src="../img/div_hide.gif" alt="" />&nbsp;'.get_lang('AdvancedParameters').'\';			
+		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;'.$hideImg.'&nbsp;'.get_lang('AdvancedParameters').'\';
 		$("div#id_image_user_field").html("&nbsp;");
 		$("div#id_image_user_field").html('."'<br />".Display::return_icon('userfield_doubleselect.png', get_lang('AddUserFields'))."'".');
 
 	} else if (image_value==9) {
 		document.getElementById(\'options\').style.display = \'none\';
-		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;<img style="vertical-align:middle;" src="../img/div_show.gif" alt="" />&nbsp;'.get_lang('AdvancedParameters').'\';
+		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;'.$showImg.'&nbsp;'.get_lang('AdvancedParameters').'\';
 		$("div#id_image_user_field").html("&nbsp;");
 		$("div#id_image_user_field").html('."'<br />".Display::return_icon('userfield_divider.png', get_lang('AddUserFields'))."'".');
 
 	} else if (image_value==10) {
 		document.getElementById(\'options\').style.display = \'none\';
-		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;<img style="vertical-align:middle;" src="../img/div_show.gif" alt="" />&nbsp;'.get_lang('AdvancedParameters').'\';
+		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;'.$showImg.'&nbsp;'.get_lang('AdvancedParameters').'\';
 		$("div#id_image_user_field").html("&nbsp;");
 		$("div#id_image_user_field").html('."'<br />".Display::return_icon('userfield_user_tag.png', get_lang('UserTag'))."'".');
 
 	}
 }
 
-function advanced_parameters() {			
+function advanced_parameters() {
 	if(document.getElementById(\'options\').style.display == \'none\') {
 		document.getElementById(\'options\').style.display = \'block\';
-		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;<img style="vertical-align:middle;" src="../img/div_hide.gif" alt="" />&nbsp;'.get_lang('AdvancedParameters').'\';
+		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;'.$hideImg.'&nbsp;'.get_lang('AdvancedParameters').'\';
 
 	} else {
 		document.getElementById(\'options\').style.display = \'none\';
-		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;<img style="vertical-align:middle;" src="../img/div_show.gif" alt="" />&nbsp;'.get_lang('AdvancedParameters').'\';
+		document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;'.$showImg.'&nbsp;'.get_lang('AdvancedParameters').'\';
 	}
 }
 
@@ -124,8 +127,8 @@ $form->addElement('select','fieldtype',get_lang('FieldType'), $types, array('onc
 $form->addRule('fieldtype', get_lang('ThisFieldIsRequired'), 'required');
 
 //Advanced parameters
-$form -> addElement('advanced_settings','<a href="javascript://" onclick=" return advanced_parameters()"><span id="img_plus_and_minus"><div style="vertical-align:top;" ><img style="vertical-align:middle;" src="../img/div_show.gif" alt="" />&nbsp;'.get_lang('AdvancedParameters').'</div></span></a>');
-//When edit, the combobox displey the field type displeyed else none 	
+$form -> addElement('advanced_settings','<a href="javascript://" onclick=" return advanced_parameters()"><span id="img_plus_and_minus"><div style="vertical-align:top;" >'.$showImg.'&nbsp;'.get_lang('AdvancedParameters').'</div></span></a>');
+//When edit, the combobox displey the field type displeyed else none
 if ( (isset($_GET['action']) && $_GET['action'] == 'edit') && in_array($_GET['field_type'],array(3,4,5,8))) {
 	$form -> addElement('html','<div id="options" style="display:block">');
 } else {
@@ -180,7 +183,7 @@ $form->setDefaults($defaults);
 if(isset($_GET['field_id']) && !empty($_GET['field_id'])) {
 	$class="save";
 	$text=get_lang('buttonEditUserField');
-} else { 
+} else {
 	$class="add";
 	$text=get_lang('buttonAddUserField');
 }
@@ -190,11 +193,11 @@ $form->addElement('html','</div>');
 $form->addElement('style_submit_button', 'submit',$text, 'class='.$class.'');
 // Validate form
 if( $form->validate()) {
-	$check = Security::check_token('post'); 
+	$check = Security::check_token('post');
 	if($check) {
 		$field = $form->exportValues();
-		$fieldlabel = empty($field['fieldlabel'])?$field['fieldtitle']:$field['fieldlabel'];		
-		$fieldlabel = trim(strtolower(str_replace(" ","_",$fieldlabel)));	
+		$fieldlabel = empty($field['fieldlabel'])?$field['fieldtitle']:$field['fieldlabel'];
+		$fieldlabel = trim(strtolower(str_replace(" ","_",$fieldlabel)));
 		$fieldtype = $field['fieldtype'];
 		$fieldtitle = $field['fieldtitle'];
 		$fielddefault = $field['fielddefaultvalue'];
@@ -261,4 +264,4 @@ if(!empty($defaults['fieldtype'])) {
 echo '</div>';
 
 // footer
-Display::display_footer();
+Display::display_footer();

+ 12 - 6
main/admin/user_list.php

@@ -9,7 +9,6 @@
 // name of the language file that needs to be included
 $language_file = array ('registration','admin');
 $cidReset = true;
-require_once '../inc/global.inc.php';
 
 global $_configuration;
 
@@ -410,7 +409,7 @@ function get_user_data($from, $number_of_items, $column, $direction, $get_count
 		}
         if ($user[7] == 1 && $user[10] != '0000-00-00 00:00:00') {
             // check expiration date
-            $expiration_time = convert_sql_date($user[10]);
+            $expiration_time = api_convert_sql_date($user[10]);
             // if expiration date is passed, store a special value for active field
             if ($expiration_time < $t) {
         	   $user[7] = '-1';
@@ -449,7 +448,10 @@ function user_filter($name, $params, $row) {
  */
 function modify_filter($user_id, $url_params, $row) {
 	global $charset, $_admins_list, $delete_user_available;
-	$is_admin   = in_array($user_id,$_admins_list);
+    $is_admin = false;
+    if (is_array($_admins_list)) {
+	    $is_admin   = in_array($user_id,$_admins_list);
+    }
 	$statusname = api_get_status_langvars();
 	$user_is_anonymous = false;
     $current_user_status_label = $row['7'];
@@ -459,8 +461,9 @@ function modify_filter($user_id, $url_params, $row) {
 	}
 	$result = '';
 	if (!$user_is_anonymous) {
+        $icon = Display::return_icon('course.gif', get_lang('Courses'), array('onmouseout' =>'"clear_course_list (\'div_'.$user_id.'\')" '));
 		$result .= '<a href="javascript:void(0)" onclick="load_course_list(\'div_'.$user_id.'\','.$user_id.')" >
-					<img onmouseout="clear_course_list (\'div_'.$user_id.'\')" src="../img/course.gif" title="'.get_lang('Courses').'" alt="'.get_lang('Courses').'"/>
+					'.$icon.'
 					<div class="blackboard_hide" id="div_'.$user_id.'">&nbsp;&nbsp;</div>
 					</a>&nbsp;&nbsp;';
 	} else {
@@ -506,6 +509,9 @@ function modify_filter($user_id, $url_params, $row) {
         }
     } // Else don't show anything, because the option is not available at all
 
+
+    $result .= Display::url('<i class="icon-key icon-large"></i>', 'roles');
+
 	if ($current_user_status_label != $statusname[STUDENT]) {
 		$result .= Display::return_icon('statistics_na.gif', get_lang('Reporting')).'&nbsp;&nbsp;';
 	} else {
@@ -732,7 +738,7 @@ while ($row_admin = Database::fetch_row($res_admin)) {
 	$_admins_list[] = $row_admin[0];
 }
 
-// display advaced search form
+// display advanced search form
 $form = new FormValidator('advanced_search','get');
 
 $form->addElement('html','<div id="advanced_search_form" style="display:none;">');
@@ -906,4 +912,4 @@ $tpl = $app['template'];
 $tpl->assign('actions', $actions);
 $tpl->assign('message', $message);
 $tpl->assign('content', $form.$table_result.$extra_search_options);
-$tpl->display_one_col_template();
+//$tpl->display_one_col_template();

+ 19 - 2
main/announcements/announcements.php

@@ -29,6 +29,23 @@ $use_anonymous = true;
 // setting the global file that gets the general configuration, the databases, the languages, ...
 require_once '../inc/global.inc.php';
 
+$showImg = Display::return_icon('div_show.gif');
+$hideImg = Display::return_icon('div_hide.gif');
+
+$htmlHeadXtra[] = "
+<script>
+function plus_attachment() {
+    'use strict';
+    if (document.getElementById('options').style.display == 'none') {
+        document.getElementById('options').style.display = 'block';
+        document.getElementById('plus').innerHTML = '&nbsp;".$hideImg."&nbsp;' + lang.AddAnAttachment;
+    } else {
+        document.getElementById('options').style.display = 'none';
+        document.getElementById('plus').innerHTML = '&nbsp;".$showImg."&nbsp;' + lang.AddAnAttachment;
+    }
+}
+</script>";
+
 /* 	Sessions */
 
 $ctok = Security::getCurrentToken();
@@ -790,7 +807,7 @@ if ($display_form) {
     //File attachment
     echo '	<div class="control-group">
 				<div class="controls">
-				    <a href="javascript://" onclick="return plus_attachment();"><span id="plus"><img style="vertical-align:middle;" src="../img/div_show.gif" alt="" />&nbsp;'.get_lang(
+				    <a href="javascript://" onclick="return plus_attachment();"><span id="plus">'.$showImg.'&nbsp;'.get_lang(
         'AddAnAttachment'
     ).'</span></a>
 				    <br />
@@ -1197,4 +1214,4 @@ if (isset($_GET['action']) && $_GET['action'] == 'view') {
 if (empty($_GET['origin']) or $_GET['origin'] !== 'learnpath') {
     //we are not in learnpath tool
     Display::display_footer();
-}
+}

+ 27 - 36
main/announcements/resources/js/main.js

@@ -66,7 +66,7 @@ function move_selected_option(from, to){
 }
 
 function update_hidden_field(name){
-    
+
     var select = $('#' + name + '_selected');
     var options = $("option", select)
     //update hidden field
@@ -77,7 +77,7 @@ function update_hidden_field(name){
         keys.push(option.val());
     });
     keys = keys.join(',');
-    
+
     var hidden = $('#' + name);
     hidden.val(keys);
 }
@@ -96,9 +96,9 @@ function toggle_list_selector(name)
         list.hide();
         overview.show();
     }
-    
+
     var select = $('#' + name + '_selected');
-    
+
     //update overview
     var content = [];
     var options = $("option", select)
@@ -107,7 +107,7 @@ function toggle_list_selector(name)
         option = $(option);
         content.push(option.text());
     });
-    
+
     content = content.join(', ');
     content = (content == '') ? lang.Everybody : content;
     overview.text(content);
@@ -127,7 +127,7 @@ function toggle_sendto()
         list.hide();
         overview.show();
     }
-    
+
     var selected = $('#selectedform');
     var content = list_box_content(selected[0])
     content = (content == '') ? lang.Everybody : content;
@@ -158,7 +158,7 @@ function move(fbox, tbox) {
     var arrFboxIsDisabled = []; // if this from checkbox after move is disabled or not
     var arrTboxIsDisabled = []; // if this to checkbox after move is disabled or not
     var key_value = "";         // key for arrays arrFboxIsDisabled and arrTboxIsDisabled, use associative array key_value is the value of the array element (eg : GROUP:1 or USER:24)
-    
+
     var i;
     for (i = 0; i < tbox.options.length; i++) {
         arrLookup[tbox.options[i].text] = tbox.options[i].value;
@@ -178,8 +178,8 @@ function move(fbox, tbox) {
         {
             arrTbox[tLength] = fbox.options[i].text;
             tLength++;
-        } 
-        else 
+        }
+        else
         {
             arrFbox[fLength] = fbox.options[i].text;
             key_value = fbox.options[i].value;
@@ -187,14 +187,14 @@ function move(fbox, tbox) {
             fLength++;
         }
     }
-    
+
     arrFbox.sort();
     arrTbox.sort();
-    
+
     var arrFboxGroup = [];
     var arrFboxUser = [];
     var prefix_x;
-    
+
     var x;
     for (x = 0; x < arrFbox.length; x++) {
         prefix_x = arrFbox[x].substring(0, 2);
@@ -204,15 +204,15 @@ function move(fbox, tbox) {
             arrFboxUser.push(arrFbox[x]);
         }
     }
-    
+
     arrFboxGroup.sort();
     arrFboxUser.sort();
     arrFbox = arrFboxGroup.concat(arrFboxUser);
-    
+
     var arrTboxGroup = [];
     var arrTboxUser = [];
     var prefix_y;
-    
+
     var y;
     for (y = 0; y < arrTbox.length; y++) {
         prefix_y = arrTbox[y].substring(0, 2);
@@ -222,16 +222,16 @@ function move(fbox, tbox) {
             arrTboxUser.push(arrTbox[y]);
         }
     }
-    
+
     arrTboxGroup.sort();
     arrTboxUser.sort();
     arrTbox = arrTboxGroup.concat(arrTboxUser);
-    
+
     fbox.length = 0;
     tbox.length = 0;
-    
+
     var c;
-    for (c = 0; c < arrFbox.length; c++) 
+    for (c = 0; c < arrFbox.length; c++)
     {
         var no = new Option();
         no.value = arrLookup[arrFbox[c]];
@@ -242,7 +242,7 @@ function move(fbox, tbox) {
         }
         fbox[c] = no;
     }
-    for (c = 0; c < arrTbox.length; c++) 
+    for (c = 0; c < arrTbox.length; c++)
     {
         var no = new Option();
         no.value = arrLookup[arrTbox[c]];
@@ -250,12 +250,12 @@ function move(fbox, tbox) {
         key_value = no.value;
         if (arrTboxIsDisabled[key_value]) {
             no.disabled = "disabled";
-        }        
+        }
         tbox[c] = no;
     }
 }
 
-function validate() 
+function validate()
 {
     "use strict";
     var f = document.new_calendar_item;
@@ -266,7 +266,7 @@ function validate()
 
 function selectAll(cbList, bSelect, showwarning) {
     "use strict";
-    
+
     if (document.getElementById('emailTitle').value == '') {
         document.getElementById('msg_error').innerHTML = lang.FieldRequired;
         document.getElementById('msg_error').style.display = 'block';
@@ -286,11 +286,11 @@ function selectAll(cbList, bSelect, showwarning) {
     }
 }
 
-function reverseAll(cbList) 
+function reverseAll(cbList)
 {
     "use strict";
     var i;
-    for (i = 0; i < cbList.length; i++) 
+    for (i = 0; i < cbList.length; i++)
     {
         cbList[i].checked = !(cbList[i].checked);
         cbList[i].selected = !(cbList[i].selected);
@@ -298,14 +298,5 @@ function reverseAll(cbList)
 }
 
 
-function plus_attachment() {
-    "use strict";
-    if (document.getElementById('options').style.display == 'none') {
-        document.getElementById('options').style.display = 'block';
-        document.getElementById('plus').innerHTML = '&nbsp;<img style="vertical-align:middle;" src="../img/div_hide.gif" alt="" />&nbsp;' + lang.AddAnAttachment;
-    } else {
-        document.getElementById('options').style.display = 'none';
-        document.getElementById('plus').innerHTML = '&nbsp;<img style="vertical-align:middle;" src="../img/div_show.gif" alt="" />&nbsp;' + lang.AddAnAttachment;
-    }
-}
-// End
+
+// End

+ 15 - 15
main/auth/cas/lib/CAS.php

@@ -3,10 +3,10 @@
 /*
  * Copyright © 2003-2010, The ESUP-Portail consortium & the JA-SIG Collaborative.
  * All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
- * 
+ *
  *     * Redistributions of source code must retain the above copyright notice,
  *       this list of conditions and the following disclaimer.
  *     * Redistributions in binary form must reproduce the above copyright notice,
@@ -276,7 +276,7 @@ define('DEFAULT_DEBUG_DIR', '/tmp/');
 $GLOBALS['PHPCAS_CLIENT'] = null;
 
 /**
- * This global variable is used to store where the initializer is called from 
+ * This global variable is used to store where the initializer is called from
  * (to print a comprehensive error in case of multiple calls).
  *
  * @hideinitializer
@@ -334,7 +334,7 @@ include_once (dirname(__FILE__) . '/CAS/client.php');
  * @ingroup public
  * @author Pascal Aubry <pascal.aubry at univ-rennes1.fr>
  *
- * \internal All its methods access the same object ($PHPCAS_CLIENT, declared 
+ * \internal All its methods access the same object ($PHPCAS_CLIENT, declared
  * at the end of CAS/client.php).
  */
 
@@ -501,7 +501,7 @@ class phpCAS {
 	 */
 
 	/**
-	 * This method is a wrapper for debug_backtrace() that is not available 
+	 * This method is a wrapper for debug_backtrace() that is not available
 	 * in all PHP versions (>= 4.3.0 only)
 	 */
 	function backtrace() {
@@ -634,7 +634,7 @@ class phpCAS {
 	 */
 
 	/**
-	 * This method is used to set the language used by phpCAS. 
+	 * This method is used to set the language used by phpCAS.
 	 * @note Can be called only once.
 	 *
 	 * @param $lang a string representing the language.
@@ -722,7 +722,7 @@ class phpCAS {
 
 	/**
 	 * This method is used to tell phpCAS to store the response of the
-	 * CAS server to PGT requests onto the filesystem. 
+	 * CAS server to PGT requests onto the filesystem.
 	 *
 	 * @param $format the format used to store the PGT's (`plain' and `xml' allowed)
 	 * @param $path the path where the PGT's should be stored
@@ -752,9 +752,9 @@ class phpCAS {
 
 	/**
 	 * This method is used to tell phpCAS to store the response of the
-	 * CAS server to PGT requests into a database. 
-	 * @note The connection to the database is done only when needed. 
-	 * As a consequence, bad parameters are detected only when 
+	 * CAS server to PGT requests into a database.
+	 * @note The connection to the database is done only when needed.
+	 * As a consequence, bad parameters are detected only when
 	 * initializing PGT storage, except in debug mode.
 	 *
 	 * @param $user the user to access the data with
@@ -814,7 +814,7 @@ class phpCAS {
 
 	/**
 	 * This method is used to access an HTTP[S] service.
-	 * 
+	 *
 	 * @param $url the service to access.
 	 * @param $err_code an error code Possible values are PHPCAS_SERVICE_OK (on
 	 * success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE, PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE,
@@ -853,7 +853,7 @@ class phpCAS {
 
 	/**
 	 * This method is used to access an IMAP/POP3/NNTP service.
-	 * 
+	 *
 	 * @param $url a string giving the URL of the service, including the mailing box
 	 * for IMAP URLs, as accepted by imap_open().
 	 * @param $service a string giving for CAS retrieve Proxy ticket
@@ -908,7 +908,7 @@ class phpCAS {
 	 */
 
 	/**
-	 * Set the times authentication will be cached before really accessing the CAS server in gateway mode: 
+	 * Set the times authentication will be cached before really accessing the CAS server in gateway mode:
 	 * - -1: check only once, and then never again (until you pree login)
 	 * - 0: always check
 	 * - n: check every "n" time
@@ -954,8 +954,8 @@ class phpCAS {
 	}
 
 	/**
-	 * This method is called to force authentication if the user was not already 
-	 * authenticated. If the user is not authenticated, halt by redirecting to 
+	 * This method is called to force authentication if the user was not already
+	 * authenticated. If the user is not authenticated, halt by redirecting to
 	 * the CAS server.
 	 */
 	function forceAuthentication() {

+ 2 - 2
main/auth/inscription.php

@@ -40,7 +40,7 @@ $course_code_redirect = isset($_REQUEST['c']) && !empty($_REQUEST['c']) ? $_REQU
 $exercise_redirect = isset($_REQUEST['e']) && !empty($_REQUEST['e']) ? $_REQUEST['e'] : null;
 
 if (!empty($course_code_redirect)) {
-    Session::write('course_redirect',   $course_code_redirect);
+    Session::write('course_redirect', $course_code_redirect);
     Session::write('exercise_redirect', $exercise_redirect);
 }
 
@@ -236,7 +236,7 @@ if (!CustomPages::enabled()) {
         if ($access_url_id != -1) {
             $url_info = api_get_access_url($access_url_id);
             $url = api_remove_trailing_slash(preg_replace('/https?:\/\//i', '', $url_info['url']));
-            $clean_url = replace_dangerous_char($url);
+            $clean_url = api_replace_dangerous_char($url);
             $clean_url = str_replace('/', '-', $clean_url);
             $clean_url .= '/';
             $home_old  = api_get_path(SYS_PATH).'home/';

+ 1 - 1
main/auth/profile.php

@@ -398,7 +398,7 @@ function upload_user_production($user_id)
     if (!file_exists($production_repository)) {
         @mkdir($production_repository, api_get_permissions_for_new_directories(), true);
     }
-    $filename = replace_dangerous_char($_FILES['production']['name']);
+    $filename = api_replace_dangerous_char($_FILES['production']['name']);
     $filename = FileManager::disable_dangerous_file($filename);
 
     if (FileManager::filter_extension($filename)) {

+ 3 - 3
main/auth/shibboleth/app/shibboleth.class.php

@@ -97,13 +97,13 @@ class Shibboleth
 
             /*
              * Tests if the user tried to login directly in a protected course before to come here
-             * (this variable could be set in the modified code of /chamilo/inc/lib/main_api.lib.php)
+             * (this variable could be set in the modified code of /chamilo/inc/lib/api.lib.php)
              *
              * Note:
              *       this part was added to give the possibility to access Chamilo directly on a course URL from a link diplayed in a portal.
              *       This is not a direct Shibboleth related functionnality, but this could be used in a shibbolethized
              *       Dokeos installation, mainly if you have a SSO system in your network.
-             *       Please note that the file /claroline/inc/lib/main_api.lib.php must be adapted to your Shibboleth settings
+             *       Please note that the file /claroline/inc/lib/api.lib.php must be adapted to your Shibboleth settings
              *       If any interest or question, please contact Nicolas.Rod_at_adm.unige.ch
              *
              */
@@ -262,4 +262,4 @@ EOT;
         return (bool) $result;
     }
 
-}
+}

+ 2 - 2
main/blog/blog.php

@@ -194,7 +194,7 @@ if (isset($_GET['action']) && $_GET['action'] == 'view_post')
 /*
 	DISPLAY
 */
-$htmlHeadXtra[] = '<script src="tbl_change.js" type="text/javascript"></script>';
+$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/calendar/tbl_change.js"></script>';
 
 // Set bredcrumb
 switch ($current_page)
@@ -478,4 +478,4 @@ switch ($current_page) {
 </table>
 <?php
 // Display the footer
-Display::display_footer();
+Display::display_footer();

+ 1 - 1
main/blog/calendar.php

@@ -110,7 +110,7 @@ table.calendar .monthyear a:hover
     } // end if
 //-->
 </script>
-<script type="text/javascript" src="tbl_change.js"></script>
+<script src="<?php echo api_get_path(WEB_LIBRARY_PATH).'javascript/calendar/tbl_change.js'; ?>"></script>
 <script type="text/javascript">
 <!--
 var month_names = new Array(

+ 119 - 124
main/calendar/agenda.inc.php

@@ -648,7 +648,10 @@ function display_monthcalendar($month, $year, $agenda_items)
  */
 function to_javascript()
 {
-    return "<script type=\"text/javascript\" language=\"javascript\">
+    $showImg = Display::return_icon('div_show.gif');
+    $hideImg = Display::return_icon('div_hide.gif');
+
+    return "<script type=\"text/javascript\">
 $(function() {
     //js used when generating images on the fly see function Tracking::show_course_detail()
     $(\".dialog\").dialog(\"destroy\");
@@ -668,8 +671,6 @@ $(function() {
     });
 });
 
-<!-- Begin javascript menu swapper
-
 function move(fbox,	tbox)
 {
     // @todo : change associative arrays arrLookup and arrLookupTitle that use firstname/lastnam as key
@@ -768,23 +769,23 @@ function move(fbox,	tbox)
 
 function checkDate(month, day, year)
 {
-  var monthLength =
+    var monthLength =
     new Array(31,28,31,30,31,30,31,31,30,31,30,31);
 
-  if (!day || !month || !year)
+    if (!day || !month || !year)
     return false;
 
-  // check for bisestile year
-  if (year/4 == parseInt(year/4))
+    // check for bisestile year
+    if (year/4 == parseInt(year/4))
     monthLength[1] = 29;
 
-  if (month < 1 || month > 12)
+    if (month < 1 || month > 12)
     return false;
 
-  if (day > monthLength[month-1])
+    if (day > monthLength[month-1])
     return false;
 
-  return true;
+    return true;
 }
 
 function mktime() {
@@ -820,79 +821,76 @@ function validate() {
 }
 
 function selectAll(cbList,bSelect,showwarning) {
-		var start_day = document.new_calendar_item.fday.value;
-		var start_month = document.new_calendar_item.fmonth.value;
-		var start_year = document.new_calendar_item.fyear.value;
-		var start_hour = document.new_calendar_item.fhour.value;
-		var start_minute = document.new_calendar_item.fminute.value;
-		var start_date = mktime(start_hour,start_minute,0,start_month,start_day,start_year)
-
-		var ends_day = document.new_calendar_item.end_fday.value;
-		var ends_month = document.new_calendar_item.end_fmonth.value;
-		var ends_year = document.new_calendar_item.end_fyear.value;
-		var ends_hour = document.new_calendar_item.end_fhour.value;
-		var ends_minute = document.new_calendar_item.end_fminute.value;
-		var ends_date = mktime(ends_hour,ends_minute,0,ends_month,ends_day,ends_year)
-
-		msg_err1 = document.getElementById(\"err_date\");
-		msg_err2 = document.getElementById(\"err_start_date\");
-		msg_err3 = document.getElementById(\"err_end_date\");
-		msg_err4 = document.getElementById(\"err_title\");
-
-
-		var error = false;
-
-		if (start_date > ends_date) {
-			if ($('#empty_end_date').is(':checked')) {
-				msg_err1.innerHTML=\"\";
-				msg_err2.innerHTML=\"\";
-				msg_err3.innerHTML=\"\";
-
-			} else {
-				error = true;
-				msg_err1.style.display =\"block\";
-				msg_err1.innerHTML=\"".get_lang('EndDateCannotBeBeforeTheStartDate')."\";
-				msg_err2.innerHTML=\"\";
-				msg_err3.innerHTML=\"\";
-			}
-		}
-
-		if (!checkDate(start_month,start_day,start_year)) {
-			msg_err2.style.display =\"block\";
-			msg_err2.innerHTML=\"".get_lang('InvalidDate')."\";
-			msg_err1.innerHTML=\"\";
-			msg_err3.innerHTML=\"\";
-			error = true;
-		}
-
-		if (!checkDate(ends_month,ends_day,ends_year)) {
-			msg_err3.style.display =\"block\";
-			msg_err3.innerHTML=\"".get_lang('InvalidDate')."\";
-			msg_err1.innerHTML=\"\";msg_err2.innerHTML=\"\";
-			error = true;
-		}
+    var start_day = document.new_calendar_item.fday.value;
+    var start_month = document.new_calendar_item.fmonth.value;
+    var start_year = document.new_calendar_item.fyear.value;
+    var start_hour = document.new_calendar_item.fhour.value;
+    var start_minute = document.new_calendar_item.fminute.value;
+    var start_date = mktime(start_hour,start_minute,0,start_month,start_day,start_year)
+
+    var ends_day = document.new_calendar_item.end_fday.value;
+    var ends_month = document.new_calendar_item.end_fmonth.value;
+    var ends_year = document.new_calendar_item.end_fyear.value;
+    var ends_hour = document.new_calendar_item.end_fhour.value;
+    var ends_minute = document.new_calendar_item.end_fminute.value;
+    var ends_date = mktime(ends_hour,ends_minute,0,ends_month,ends_day,ends_year)
+
+    msg_err1 = document.getElementById(\"err_date\");
+    msg_err2 = document.getElementById(\"err_start_date\");
+    msg_err3 = document.getElementById(\"err_end_date\");
+    msg_err4 = document.getElementById(\"err_title\");
+
+
+    var error = false;
+
+    if (start_date > ends_date) {
+        if ($('#empty_end_date').is(':checked')) {
+            msg_err1.innerHTML=\"\";
+            msg_err2.innerHTML=\"\";
+            msg_err3.innerHTML=\"\";
 
-		if (document.new_calendar_item.title.value == '') {
-			msg_err4.style.display =\"block\";
-			msg_err4.innerHTML=\"".get_lang('FieldRequired')."\";
-			msg_err1.innerHTML=\"\";msg_err2.innerHTML=\"\";msg_err3.innerHTML=\"\";
-			error = true;
-		}
-		if (error == false) {
-            if (cbList) {
-    			if (cbList.length <	1) {
-    				if (!confirm(\"".get_lang('Send2All')."\")) {
-    					return false;
-    				}
-    			}
-    			for	(var i=0; i<cbList.length; i++)
-    			cbList[i].selected = cbList[i].checked = bSelect;
-			}
-			document.new_calendar_item.submit();
-		}
+        } else {
+            error = true;
+            msg_err1.style.display =\"block\";
+            msg_err1.innerHTML=\"".get_lang('EndDateCannotBeBeforeTheStartDate')."\";
+            msg_err2.innerHTML=\"\";
+            msg_err3.innerHTML=\"\";
+        }
+    }
 
+    if (!checkDate(start_month,start_day,start_year)) {
+        msg_err2.style.display =\"block\";
+        msg_err2.innerHTML=\"".get_lang('InvalidDate')."\";
+        msg_err1.innerHTML=\"\";
+        msg_err3.innerHTML=\"\";
+        error = true;
+    }
 
+    if (!checkDate(ends_month,ends_day,ends_year)) {
+        msg_err3.style.display =\"block\";
+        msg_err3.innerHTML=\"".get_lang('InvalidDate')."\";
+        msg_err1.innerHTML=\"\";msg_err2.innerHTML=\"\";
+        error = true;
+    }
 
+    if (document.new_calendar_item.title.value == '') {
+        msg_err4.style.display =\"block\";
+        msg_err4.innerHTML=\"".get_lang('FieldRequired')."\";
+        msg_err1.innerHTML=\"\";msg_err2.innerHTML=\"\";msg_err3.innerHTML=\"\";
+        error = true;
+    }
+    if (error == false) {
+        if (cbList) {
+            if (cbList.length <	1) {
+                if (!confirm(\"".get_lang('Send2All')."\")) {
+                    return false;
+                }
+            }
+            for	(var i=0; i<cbList.length; i++)
+            cbList[i].selected = cbList[i].checked = bSelect;
+        }
+        document.new_calendar_item.submit();
+    }
 }
 
 function reverseAll(cbList)
@@ -905,43 +903,41 @@ function reverseAll(cbList)
 }
 
 function plus_attachment() {
-				if (document.getElementById('options').style.display == 'none') {
-					document.getElementById('options').style.display = 'block';
-					document.getElementById('plus').innerHTML='&nbsp;<img style=\"vertical-align:middle;\" src=\"../img/div_hide.gif\" alt=\"\" />&nbsp;".get_lang(
-        'AddAnAttachment'
-    )."';
-				} else {
-				document.getElementById('options').style.display = 'none';
-				document.getElementById('plus').innerHTML='&nbsp;<img style=\"vertical-align:middle;\" src=\"../img/div_show.gif\" alt=\"\" />&nbsp;".get_lang(
-        'AddAnAttachment'
-    )."';
-				}
+    if (document.getElementById('options').style.display == 'none') {
+        document.getElementById('options').style.display = 'block';
+        document.getElementById('plus').innerHTML='&nbsp;".$hideImg."&nbsp;".get_lang(
+'AddAnAttachment'
+)."';
+    } else {
+    document.getElementById('options').style.display = 'none';
+    document.getElementById('plus').innerHTML='&nbsp;".$showImg."&nbsp;".get_lang(
+'AddAnAttachment'
+)."';
+    }
 }
 
 function plus_repeated_event() {
-				if (document.getElementById('options2').style.display == 'none') {
-					document.getElementById('options2').style.display = 'block';
-					document.getElementById('plus2').innerHTML='&nbsp;<img style=\"vertical-align:middle;\" src=\"../img/div_hide.gif\" alt=\"\" />&nbsp;".get_lang(
-        'RepeatEvent'
+    if (document.getElementById('options2').style.display == 'none') {
+        document.getElementById('options2').style.display = 'block';
+        document.getElementById('plus2').innerHTML='&nbsp;".$hideImg."&nbsp;".get_lang(
+    'RepeatEvent'
     )."';
-				} else {
-				document.getElementById('options2').style.display = 'none';
-				document.getElementById('plus2').innerHTML='&nbsp;<img style=\"vertical-align:middle;\" src=\"../img/div_show.gif\" alt=\"\" />&nbsp;".get_lang(
-        'RepeatEvent'
+    } else {
+    document.getElementById('options2').style.display = 'none';
+    document.getElementById('plus2').innerHTML='&nbsp;".$showImg."&nbsp;".get_lang(
+    'RepeatEvent'
     )."';
-				}
+    }
 }
 
 /*
 function plus_ical() {
-				if (document.getElementById('icalform').style.display == 'none') {
-					document.getElementById('icalform').style.display = 'block';
-					document.getElementById('plusical').innerHTML='';
-				}
+    if (document.getElementById('icalform').style.display == 'none') {
+        document.getElementById('icalform').style.display = 'block';
+        document.getElementById('plusical').innerHTML='';
+    }
 }
 */
-
-//	End	-->
 </script>";
 }
 
@@ -952,15 +948,12 @@ function plus_ical() {
  */
 function user_group_filter_javascript()
 {
-    return "<script language=\"JavaScript\" type=\"text/JavaScript\">
-	<!--
+    return "<script type=\"text/JavaScript\">
 	function MM_jumpMenu(targ,selObj,restore){
 	  eval(targ+\".location='\"+selObj.options[selObj.selectedIndex].value+\"'\");
 	  if (restore) selObj.selectedIndex=0;
 	}
-	//-->
-	</script>
-	";
+	</script>";
 }
 
 /**
@@ -1670,6 +1663,7 @@ function load_edit_users($tool, $id)
 
     $sql = "SELECT * FROM $TABLE_ITEM_PROPERTY WHERE c_id = $course_id AND tool='$tool' AND ref='$id'";
     $result = Database::query($sql) or die(Database::error());
+    $to = array();
     while ($row = Database::fetch_array($result)) {
         $to_group = $row['to_group_id'];
         switch ($to_group) {
@@ -2501,16 +2495,20 @@ function display_one_agenda_item($agenda_id)
  */
 function show_add_form($id = '', $type = null)
 {
-
-    global $MonthsLong;
+    $showImg = Display::return_icon('div_show.gif');
+    $hideImg = Display::return_icon('div_hide.gif');
+    $MonthsLong = api_get_months_long();
     $htmlHeadXtra[] = to_javascript();
     // the default values for the forms
-    if ($_GET['originalresource'] !== 'no') {
+    //if (isset(!$_GET['originalresource']) && $_GET['originalresource'] !== 'no') {
+    if (!isset($_GET['originalresource'])) {
         $day = date('d');
         $month = date('m');
         $year = date('Y');
         $hours = 9;
         $minutes = '00';
+        $title = null;
+        $content = null;
 
         $end_day = date('d');
         $end_month = date('m');
@@ -2523,7 +2521,7 @@ function show_add_form($id = '', $type = null)
         // When we clicked on the button to add resources we stored every form information into a session and now we
         // are doing the opposite thing: getting the information out of the session and putting it into variables to
         // display it in the forms.
-        $form_elements = $_SESSION['formelements'];
+        $form_elements = isset($_SESSION['formelements']) ? $_SESSION['formelements'] : null;
         $day = $form_elements['day'];
         $month = $form_elements['month'];
         $year = $form_elements['year'];
@@ -2542,6 +2540,8 @@ function show_add_form($id = '', $type = null)
         $repeat = $form_elements['repeat'];
     }
 
+
+
     //	switching the send to all/send to groups/send to users
     if (isset($_POST['To']) && $_POST['To']) {
         $day = $_POST['fday'];
@@ -2626,15 +2626,12 @@ function show_add_form($id = '', $type = null)
     $origin = isset($_GET['origin']) ? Security::remove_XSS($_GET['origin']) : null;
     $course_url = empty($course_info) ? null : api_get_cidreq();
     ?>
-
-<!-- START OF THE FORM  -->
-
     <form class="form-horizontal" enctype="multipart/form-data"  action="<?php echo api_get_self().'?type='.Security::remove_XSS($type).'&origin='.$origin.'&'.$course_url."&sort=asc&toolgroup=".api_get_group_id().'&action='.Security::remove_XSS($_GET['action']); ?>" method="post" name="new_calendar_item">
         <input type="hidden" name="id" value="<?php if (isset($id)) echo $id; ?>" />
         <input type="hidden" name="action" value="<?php if (isset($_GET['action'])) echo $_GET['action']; ?>" />
         <input type="hidden" name="id_attach" value="<?php echo isset($_REQUEST['id_attach']) ? intval($_REQUEST['id_attach']) : null; ?>" />
-<input type="hidden" name="sort" value="asc"/>
-<input type="hidden" name="submit_event" value="ok"/>
+        <input type="hidden" name="sort" value="asc"/>
+        <input type="hidden" name="submit_event" value="ok"/>
     <?php
     // The form title
     if (isset($id) AND $id <> '') {
@@ -2659,8 +2656,6 @@ function show_add_form($id = '', $type = null)
 							</div>
 						</div>';
 
-
-
     // selecting the users / groups
     $group_id = api_get_group_id();
     if (empty($id)) {
@@ -2676,7 +2671,7 @@ function show_add_form($id = '', $type = null)
         show_to_form($to);
         echo '</div>
 				</div>';
-    }
+        }
     }
 
     // start date and time
@@ -2893,7 +2888,7 @@ function show_add_form($id = '', $type = null)
 					<label class="control-label"></label>
 					<div class="controls">
 					<a href="javascript://" onclick="return plus_repeated_event();"><span id="plus2">
-	                       <img style="vertical-align:middle;" src="../img/div_show.gif" alt="" />&nbsp;'.get_lang('RepeatEvent').'</span>
+	                      '.$showImg.'&nbsp;'.get_lang('RepeatEvent').'</span>
 	                    </a>';
         ?>
     <table id="options2" style="display: none;">
@@ -3008,7 +3003,7 @@ function show_add_form($id = '', $type = null)
     echo '</div>
 			</div>';
 
-            if ($agendaObj->type == 'course') {
+            if (isset($agendaObj) && $agendaObj->type == 'course') {
 
     // File attachment
     echo '	<div class="control-group">

+ 0 - 1105
main/calendar/agenda.lib.php

@@ -1,1105 +0,0 @@
-<?php
-/* For licensing terms, see /license.txt */
-
-/**
- * @author: Julio Montoya <gugli100@gmail.com>
- * Class Agenda
- * @todo move this in main/inc/lib and update composer autoload
- */
-class Agenda
-{
-    public $events = array();
-    public $type = 'personal';
-
-    /**
-     *
-     */
-    public function __construct()
-    {
-        //Table definitions
-        $this->tbl_global_agenda   = Database::get_main_table(TABLE_MAIN_SYSTEM_CALENDAR);
-        $this->tbl_personal_agenda = Database::get_main_table(TABLE_PERSONAL_AGENDA);
-        $this->tbl_course_agenda   = Database::get_course_table(TABLE_AGENDA);
-
-        // Setting the course object if we are in a course
-        $this->course = null;
-        $course_info  = api_get_course_info();
-        if (!empty($course_info)) {
-            $this->course = $course_info;
-        }
-
-        $this->events = array();
-
-        //Event colors
-        $this->event_platform_color = 'red'; //red
-        $this->event_course_color   = '#458B00'; //green
-        $this->event_group_color    = '#A0522D'; //siena
-        $this->event_session_color  = '#00496D'; // kind of green
-        $this->event_personal_color = 'steel blue'; //steel blue
-    }
-
-    /**
-     * Agenda type: personal, admin or course
-     * @param string $type
-     */
-    public function setType($type)
-    {
-        $this->type = $type;
-    }
-
-    /**
-     * Sets course info
-     * @param array $course_info
-     */
-    public function set_course($course_info)
-    {
-        $this->course = $course_info;
-    }
-
-    /**
-     *
-     * Adds an event to the calendar
-     *
-     * @param   string  start datetime format: 2012-06-14 09:00:00
-     * @param   string  end datetime format: 2012-06-14 09:00:00
-     * @param   string  all day (true, false)
-     * @param   string  view agendaDay, agendaWeek, month @todo seems not to be used
-     * @param   string  title
-     * @param   string  content
-     * @param   array   users to send array('everyone') or a list of user ids
-     * @param   bool    add event as a *course* announcement
-     *
-     */
-    public function add_event(
-        $start,
-        $end,
-        $all_day,
-        $view,
-        $title,
-        $content,
-        $users_to_send = array(),
-        $add_as_announcement = false
-    ) {
-        $start   = api_get_utc_datetime($start);
-        $end     = api_get_utc_datetime($end);
-        $all_day = isset($all_day) && $all_day == 'true' ? 1 : 0;
-
-        $attributes = array();
-        $id         = null;
-        switch ($this->type) {
-            case 'personal':
-                $attributes['user']    = api_get_user_id();
-                $attributes['title']   = $title;
-                $attributes['text']    = $content;
-                $attributes['date']    = $start;
-                $attributes['enddate'] = $end;
-                $attributes['all_day'] = $all_day;
-                $id                    = Database::insert($this->tbl_personal_agenda, $attributes);
-                break;
-            case 'course':
-                $attributes['title']      = $title;
-                $attributes['content']    = $content;
-                $attributes['start_date'] = $start;
-                $attributes['end_date']   = $end;
-                $attributes['all_day']    = $all_day;
-                $attributes['session_id'] = api_get_session_id();
-                $attributes['c_id']       = $this->course['real_id'];
-
-                //simple course event
-                $id = Database::insert($this->tbl_course_agenda, $attributes);
-
-                if ($id) {
-                    $group_id = api_get_group_id();
-
-                    if ((!is_null($users_to_send)) or (!empty($group_id))) {
-                        $send_to = self::separate_users_groups($users_to_send);
-                        if (isset($send_to['everyone']) && $send_to['everyone']) {
-                            api_item_property_update(
-                                $this->course,
-                                TOOL_CALENDAR_EVENT,
-                                $id,
-                                "AgendaAdded",
-                                api_get_user_id(),
-                                $group_id,
-                                '',
-                                $start,
-                                $end
-                            );
-                        } else {
-                            // storing the selected groups
-                            if (isset($send_to['groups']) && is_array($send_to['groups'])) {
-                                foreach ($send_to['groups'] as $group) {
-                                    api_item_property_update(
-                                        $this->course,
-                                        TOOL_CALENDAR_EVENT,
-                                        $id,
-                                        "AgendaAdded",
-                                        api_get_user_id(),
-                                        $group,
-                                        0,
-                                        $start,
-                                        $end
-                                    );
-                                }
-                            }
-
-                            // storing the selected users
-                            if (isset($send_to['groups']) && is_array($send_to['users'])) {
-                                foreach ($send_to['users'] as $to_user_id) {
-                                    api_item_property_update(
-                                        $this->course,
-                                        TOOL_CALENDAR_EVENT,
-                                        $id,
-                                        "AgendaAdded",
-                                        api_get_user_id(),
-                                        $group_id,
-                                        $to_user_id,
-                                        $start,
-                                        $end
-                                    );
-                                }
-                            }
-                        }
-                    }
-
-                    if (isset($add_as_announcement) && !empty($add_as_announcement)) {
-                        self::store_agenda_item_as_announcement($id, $users_to_send);
-                    }
-                }
-                break;
-            case 'admin':
-                if (api_is_platform_admin()) {
-                    $attributes['title']         = $title;
-                    $attributes['content']       = $content;
-                    $attributes['start_date']    = $start;
-                    $attributes['end_date']      = $end;
-                    $attributes['all_day']       = $all_day;
-                    $attributes['access_url_id'] = api_get_current_access_url_id();
-                    $id                          = Database::insert($this->tbl_global_agenda, $attributes);
-                }
-                break;
-        }
-
-        return $id;
-    }
-
-
-    /**
-     * @param int id
-     * @param array sent to
-     **/
-
-    public function store_agenda_item_as_announcement($item_id, $sent_to = array())
-    {
-        $table_agenda = Database::get_course_table(TABLE_AGENDA);
-        $course_id    = api_get_course_int_id();
-
-        //check params
-        if (empty($item_id) or $item_id != strval(intval($item_id))) {
-            return -1;
-        }
-        //get the agenda item
-
-        $item_id = Database::escape_string($item_id);
-        $sql     = "SELECT * FROM $table_agenda WHERE c_id = $course_id AND id = ".$item_id;
-        $res     = Database::query($sql);
-
-        if (Database::num_rows($res) > 0) {
-            $row = Database::fetch_array($res, 'ASSOC');
-
-            //Sending announcement
-            if (!empty($sent_to)) {
-                $id = AnnouncementManager::add_announcement(
-                    $row['title'],
-                    $row['content'],
-                    $sent_to,
-                    null,
-                    null,
-                    $row['end_date']
-                );
-                AnnouncementManager::send_email($id);
-            }
-
-            return $id;
-        }
-
-        return -1;
-    }
-
-    /**
-     * Edits an event
-     *
-     * @param int       event id
-     * @param string    start datetime format: 2012-06-14 09:00:00
-     * @param string    end datetime format: 2012-06-14 09:00:00
-     * @param int       event is all day? 1|0
-     * @param string    view
-     * @param string    event title
-     * @param string    event content
-     */
-    public function edit_event($id, $start, $end, $all_day, $view, $title, $content)
-    {
-        $start = api_get_utc_datetime($start);
-
-        if ($all_day == '0') {
-            $end = api_get_utc_datetime($end);
-        }
-        $all_day = isset($all_day) && $all_day == '1' ? 1 : 0;
-
-        $attributes = array();
-
-        switch ($this->type) {
-            case 'personal':
-                $eventInfo = $this->get_event($id);
-                if ($eventInfo['user'] != api_get_user_id()) {
-                    break;
-                }
-                $attributes['title']   = $title;
-                $attributes['text']    = $content;
-                $attributes['date']    = $start;
-                $attributes['enddate'] = $end;
-                Database::update($this->tbl_personal_agenda, $attributes, array('id = ?' => $id));
-                break;
-            case 'course':
-                $course_id = api_get_course_int_id();
-                if (!empty($course_id) && api_is_allowed_to_edit(null, true)) {
-                    $attributes['title']      = $title;
-                    $attributes['content']    = $content;
-                    $attributes['start_date'] = $start;
-                    $attributes['end_date']   = $end;
-                    $attributes['all_day']    = $all_day;
-                    Database::update(
-                        $this->tbl_course_agenda,
-                        $attributes,
-                        array('id = ? AND c_id = ?' => array($id, $course_id))
-                    );
-                }
-                break;
-            case 'admin':
-                if (api_is_platform_admin()) {
-                    $attributes['title']      = $title;
-                    $attributes['content']    = $content;
-                    $attributes['start_date'] = $start;
-                    $attributes['end_date']   = $end;
-                    Database::update($this->tbl_global_agenda, $attributes, array('id = ?' => $id));
-                }
-                break;
-        }
-    }
-
-    /**
-     * @param int $id
-     */
-    public function delete_event($id)
-    {
-        switch ($this->type) {
-            case 'personal':
-                $eventInfo = $this->get_event($id);
-                if ($eventInfo['user'] == api_get_user_id()) {
-                    Database::delete($this->tbl_personal_agenda, array('id = ?' => $id));
-                }
-                break;
-            case 'course':
-                $course_id = api_get_course_int_id();
-                if (!empty($course_id) && api_is_allowed_to_edit(null, true)) {
-                    Database::delete($this->tbl_course_agenda, array('id = ? AND c_id = ?' => array($id, $course_id)));
-                }
-                break;
-            case 'admin':
-                if (api_is_platform_admin()) {
-                    Database::delete($this->tbl_global_agenda, array('id = ?' => $id));
-                }
-                break;
-        }
-    }
-
-    /**
-     *
-     * Get agenda events
-     * @param    int        start tms
-     * @param    int        end tms
-     * @param    int        course id *integer* not the course code
-     * @param   int     user id
-     *
-     */
-    public function get_events($start, $end, $course_id = null, $group_id = null, $user_id = 0)
-    {
-
-        switch ($this->type) {
-            case 'admin':
-                $this->get_platform_events($start, $end);
-                break;
-            case 'course':
-                $session_id  = api_get_session_id();
-                $course_info = api_get_course_info_by_id($course_id);
-                $this->get_course_events($start, $end, $course_info, $group_id, $session_id, $user_id);
-                break;
-            case 'personal':
-            default:
-                //Getting personal events
-                $this->get_personal_events($start, $end);
-
-                //Getting platform/admin events
-                $this->get_platform_events($start, $end);
-
-                //Getting course events
-                $my_course_list = array();
-
-                if (!api_is_anonymous()) {
-                    $session_list   = SessionManager::get_sessions_by_user(api_get_user_id());
-                    $my_course_list = CourseManager::get_courses_list_by_user_id(api_get_user_id(), true);
-                }
-
-                if (!empty($session_list)) {
-                    foreach ($session_list as $session_item) {
-                        $my_courses    = $session_item['courses'];
-                        $my_session_id = $session_item['session_id'];
-                        if (!empty($my_courses)) {
-                            foreach ($my_courses as $course_item) {
-                                $course_info = api_get_course_info_by_id($course_item['id']);
-                                $this->get_course_events($start, $end, $course_info, 0, $my_session_id);
-                            }
-                        }
-                    }
-                }
-
-                if (!empty($my_course_list)) {
-                    foreach ($my_course_list as $course_info_item) {
-                        if (isset($course_id) && !empty($course_id)) {
-                            if ($course_info_item['real_id'] == $course_id) {
-                                $this->get_course_events($start, $end, $course_info_item);
-                            }
-                        } else {
-                            $this->get_course_events($start, $end, $course_info_item);
-                        }
-                    }
-                }
-                break;
-        }
-        if (!empty($this->events)) {
-            return json_encode($this->events);
-        }
-
-        return '';
-    }
-
-    /**
-     * @param int $id
-     * @param int $day_delta
-     * @param int $minute_delta
-     * @return int
-     */
-    public function resize_event($id, $day_delta, $minute_delta)
-    {
-        // we convert the hour delta into minutes and add the minute delta
-        $delta = ($day_delta * 60 * 24) + $minute_delta;
-        $delta = intval($delta);
-
-        $event = $this->get_event($id);
-        if (!empty($event)) {
-            switch ($this->type) {
-                case 'personal':
-                    $sql    = "UPDATE $this->tbl_personal_agenda SET all_day = 0, enddate = DATE_ADD(enddate, INTERVAL $delta MINUTE)
-							WHERE id=".intval($id);
-                    $result = Database::query($sql);
-                    break;
-                case 'course':
-                    $sql    = "UPDATE $this->tbl_course_agenda SET all_day = 0,  end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
-							WHERE c_id = ".$this->course['real_id']." AND id=".intval($id);
-                    $result = Database::query($sql);
-                    break;
-                case 'admin':
-                    $sql    = "UPDATE $this->tbl_global_agenda SET all_day = 0, end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
-							WHERE id=".intval($id);
-                    $result = Database::query($sql);
-                    break;
-            }
-        }
-
-        return 1;
-
-    }
-
-    /**
-     * @param int $id
-     * @param int $day_delta
-     * @param int $minute_delta
-     * @return int
-     */
-    public function move_event($id, $day_delta, $minute_delta)
-    {
-        // we convert the hour delta into minutes and add the minute delta
-        $delta = ($day_delta * 60 * 24) + $minute_delta;
-        $delta = intval($delta);
-
-        $event = $this->get_event($id);
-
-        $all_day = 0;
-        if ($day_delta == 0 && $minute_delta == 0) {
-            $all_day = 1;
-        }
-
-        if (!empty($event)) {
-            switch ($this->type) {
-                case 'personal':
-                    $sql    = "UPDATE $this->tbl_personal_agenda SET all_day = $all_day, date = DATE_ADD(date, INTERVAL $delta MINUTE), enddate = DATE_ADD(enddate, INTERVAL $delta MINUTE)
-							WHERE id=".intval($id);
-                    $result = Database::query($sql);
-                    break;
-                case 'course':
-                    $sql    = "UPDATE $this->tbl_course_agenda SET all_day = $all_day, start_date = DATE_ADD(start_date,INTERVAL $delta MINUTE), end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
-							WHERE c_id = ".$this->course['real_id']." AND id=".intval($id);
-                    $result = Database::query($sql);
-                    break;
-                case 'admin':
-                    $sql    = "UPDATE $this->tbl_global_agenda SET all_day = $all_day, start_date = DATE_ADD(start_date,INTERVAL $delta MINUTE), end_date = DATE_ADD(end_date, INTERVAL $delta MINUTE)
-							WHERE id=".intval($id);
-                    $result = Database::query($sql);
-                    break;
-            }
-        }
-
-        return 1;
-    }
-
-    /**
-     * Gets a single event
-     *
-     * @param int event id
-     * @return array
-     */
-    public function get_event($id)
-    {
-        // make sure events of the personal agenda can only be seen by the user himself
-        $id    = intval($id);
-        $event = null;
-        switch ($this->type) {
-            case 'personal':
-                $sql    = " SELECT * FROM ".$this->tbl_personal_agenda." WHERE id = $id AND user = ".api_get_user_id();
-                $result = Database::query($sql);
-                if (Database::num_rows($result)) {
-                    $event                = Database::fetch_array($result, 'ASSOC');
-                    $event['description'] = $event['text'];
-                    $event['start_date']  = $event['date'];
-                    $event['end_date']    = $event['enddate'];
-                }
-                break;
-            case 'course':
-                if (!empty($this->course['real_id'])) {
-                    $sql    = " SELECT * FROM ".$this->tbl_course_agenda." WHERE c_id = ".$this->course['real_id']." AND id = ".$id;
-                    $result = Database::query($sql);
-                    if (Database::num_rows($result)) {
-                        $event                = Database::fetch_array($result, 'ASSOC');
-                        $event['description'] = $event['content'];
-                    }
-                }
-                break;
-            case 'admin':
-            case 'platform':
-                $sql    = " SELECT * FROM ".$this->tbl_global_agenda." WHERE id=".$id;
-                $result = Database::query($sql);
-                if (Database::num_rows($result)) {
-                    $event                = Database::fetch_array($result, 'ASSOC');
-                    $event['description'] = $event['content'];
-                }
-                break;
-        }
-
-        return $event;
-    }
-
-    /**
-     *
-     * Gets personal events
-     * @param int    start date tms
-     * @param int    end   date tms
-     */
-    public function get_personal_events($start, $end)
-    {
-        $start   = intval($start);
-        $end     = intval($end);
-        $start   = api_get_utc_datetime($start);
-        $end     = api_get_utc_datetime($end);
-        $user_id = api_get_user_id();
-
-        $sql = "SELECT * FROM ".$this->tbl_personal_agenda."
-				   WHERE date >= '".$start."' AND (enddate <='".$end."' OR enddate IS NULL) AND user = $user_id";
-
-        $result    = Database::query($sql);
-        $my_events = array();
-        if (Database::num_rows($result)) {
-            while ($row = Database::fetch_array($result, 'ASSOC')) {
-                $event                = array();
-                $event['id']          = 'personal_'.$row['id'];
-                $event['title']       = $row['title'];
-                $event['className']   = 'personal';
-                $event['borderColor'] = $event['backgroundColor'] = $this->event_personal_color;
-                $event['editable']    = true;
-
-                $event['sent_to'] = get_lang('Me');
-                $event['type']    = 'personal';
-
-                if (!empty($row['date']) && $row['date'] != '0000-00-00 00:00:00') {
-                    $event['start'] = $this->format_event_date($row['date']);
-                }
-
-                if (!empty($row['enddate']) && $row['enddate'] != '0000-00-00 00:00:00') {
-                    $event['end'] = $this->format_event_date($row['enddate']);
-                }
-                $event['description'] = $row['text'];
-                $event['allDay']      = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
-                $my_events[]          = $event;
-                $this->events[]       = $event;
-            }
-        }
-
-        return $my_events;
-    }
-
-    /**
-     * @param int $start
-     * @param int $end
-     * @param array $course_info
-     * @param int $group_id
-     * @param int $session_id
-     * @param int $user_id
-     * @return array
-     */
-    public function get_course_events($start, $end, $course_info, $group_id = 0, $session_id = 0, $user_id = 0)
-    {
-        $course_id  = $course_info['real_id'];
-        $user_id    = intval($user_id);
-        $group_list = GroupManager::get_group_list(null, $course_info['code']);
-
-        $group_name_list = array();
-        if (!empty($group_list)) {
-            foreach ($group_list as $group) {
-                $group_name_list[$group['id']] = $group['name'];
-            }
-        }
-
-        if (!api_is_allowed_to_edit()) {
-            $group_memberships = GroupManager::get_group_ids($course_id, api_get_user_id());
-            $user_id           = api_get_user_id();
-        } else {
-            $group_memberships = array_keys($group_name_list);
-        }
-
-        $tlb_course_agenda = Database::get_course_table(TABLE_AGENDA);
-        $tbl_property      = Database::get_course_table(TABLE_ITEM_PROPERTY);
-
-
-        if (!empty($group_id)) {
-            $group_memberships = array($group_id);
-        }
-
-        $session_id = intval($session_id);
-
-        if (is_array($group_memberships) && count($group_memberships) > 0) {
-            if (api_is_allowed_to_edit()) {
-                if (!empty($user_id)) {
-                    $where_condition = "( ip.to_user_id = $user_id AND ip.to_group_id is null OR ip.to_group_id IN (0, ".implode(
-                        ", ",
-                        $group_memberships
-                    ).") ) ";
-                } else {
-                    $where_condition = "( ip.to_group_id is null OR ip.to_group_id IN (0, ".implode(
-                        ", ",
-                        $group_memberships
-                    ).") ) ";
-                }
-            } else {
-                $where_condition = "( ip.to_user_id = $user_id OR ip.to_group_id IN (0, ".implode(
-                    ", ",
-                    $group_memberships
-                ).") ) ";
-            }
-
-            $sql = "SELECT DISTINCT
-                    agenda.*,
-                    ip.visibility,
-                    ip.to_group_id,
-                    ip.insert_user_id,
-                    ip.ref,
-                    to_user_id
-                    FROM ".$tlb_course_agenda." agenda, ".$tbl_property." ip
-                    WHERE   agenda.id       = ip.ref  AND
-                            ip.tool         ='".TOOL_CALENDAR_EVENT."' AND
-                            $where_condition AND
-                            ip.visibility   = '1' AND
-                            agenda.c_id     = $course_id AND
-                            ip.c_id         = $course_id
-                    GROUP BY id";
-
-        } else {
-            if (api_is_allowed_to_edit()) {
-                $where_condition = "";
-            } else {
-                $where_condition = "( ip.to_user_id=$user_id OR ip.to_group_id='0') AND ";
-            }
-
-            $sql = "SELECT DISTINCT agenda.*, ip.visibility, ip.to_group_id, ip.insert_user_id, ip.ref, to_user_id
-                    FROM ".$tlb_course_agenda." agenda, ".$tbl_property." ip
-                    WHERE   agenda.id = ip.ref AND
-                            ip.tool='".TOOL_CALENDAR_EVENT."' AND
-                            $where_condition
-                            ip.visibility='1' AND
-                            agenda.c_id = $course_id AND
-                            ip.c_id = $course_id AND
-                            agenda.session_id = $session_id AND
-                            ip.id_session = $session_id
-                    ";
-
-        }
-
-        $result = Database::query($sql);
-        $events = array();
-        if (Database::num_rows($result)) {
-            $events_added = array();
-            while ($row = Database::fetch_array($result, 'ASSOC')) {
-                //to gather sent_tos
-                $sql            = "SELECT to_user_id, to_group_id
-                    FROM ".$tbl_property." ip
-                    WHERE   ip.tool         = '".TOOL_CALENDAR_EVENT."' AND
-                            ref             = {$row['ref']} AND
-                            ip.visibility   = '1' AND
-                            ip.c_id         = $course_id";
-                $sent_to_result = Database::query($sql);
-                $user_to_array  = array();
-                $group_to_array = array();
-                while ($row_send_to = Database::fetch_array($sent_to_result, 'ASSOC')) {
-                    if (!empty($row_send_to['to_group_id'])) {
-                        $group_to_array[] = $row_send_to['to_group_id'];
-                    }
-                    if (!empty($row_send_to['to_user_id'])) {
-                        $user_to_array[] = $row_send_to['to_user_id'];
-                    }
-                }
-
-                //Only show events from the session
-                /*if (api_get_course_int_id()) {
-                    if ($row['session_id'] != api_get_session_id()) {
-                        continue;
-                    }
-                }*/
-
-                $event = array();
-
-                $event['id'] = 'course_'.$row['id'];
-
-                //To avoid doubles
-                if (in_array($row['id'], $events_added)) {
-                    continue;
-                }
-
-                $events_added[] = $row['id'];
-
-                $attachment = get_attachment($row['id'], $course_id);
-
-                $has_attachment = '';
-
-                if (!empty($attachment)) {
-                    $has_attachment      = Display::return_icon('attachment.gif', get_lang('Attachment'));
-                    $user_filename       = $attachment['filename'];
-                    $full_file_name      = 'download.php?file='.$attachment['path'].'&course_id='.$course_id;
-                    $event['attachment'] = $has_attachment.Display::url($user_filename, $full_file_name);
-                } else {
-                    $event['attachment'] = '';
-                }
-
-                $event['title']     = $row['title'];
-                $event['className'] = 'course';
-                $event['allDay']    = 'false';
-
-                $event['course_id'] = $course_id;
-
-                $event['borderColor'] = $event['backgroundColor'] = $this->event_course_color;
-                if (isset($row['session_id']) && !empty($row['session_id'])) {
-                    $event['borderColor'] = $event['backgroundColor'] = $this->event_session_color;
-                }
-
-                if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
-                    $event['borderColor'] = $event['backgroundColor'] = $this->event_group_color;
-                }
-
-                $event['editable'] = false;
-
-                if (api_is_allowed_to_edit() && $this->type == 'course') {
-                    $event['editable'] = true;
-                }
-
-                if (!empty($row['start_date']) && $row['start_date'] != '0000-00-00 00:00:00') {
-                    $event['start'] = $this->format_event_date($row['start_date']);
-                }
-                if (!empty($row['end_date']) && $row['end_date'] != '0000-00-00 00:00:00') {
-                    $event['end'] = $this->format_event_date($row['end_date']);
-                }
-
-                $event['sent_to'] = '';
-                //$event['type']    = $this->type;
-                $event['type'] = 'course';
-                if ($row['session_id'] != 0) {
-                    $event['type'] = 'session';
-                }
-
-                //Event Sent to a group?
-                if (isset($row['to_group_id']) && !empty($row['to_group_id'])) {
-                    $sent_to = array();
-                    if (!empty($group_to_array)) {
-                        foreach ($group_to_array as $group_item) {
-                            $sent_to[] = $group_name_list[$group_item];
-                        }
-                    }
-                    $sent_to          = implode('@@', $sent_to);
-                    $sent_to          = str_replace('@@', '</div><div class="label_tag notice">', $sent_to);
-                    $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
-                    $event['type']    = 'group';
-                }
-
-                //Event sent to a user?
-                if (isset($row['to_user_id'])) {
-                    $sent_to = array();
-                    if (!empty($user_to_array)) {
-                        foreach ($user_to_array as $item) {
-                            $user_info = api_get_user_info($item);
-                            // add username as tooltip for $event['sent_to'] - ref #4226
-                            $username  = api_htmlentities(
-                                sprintf(get_lang('LoginX'), $user_info['username']),
-                                ENT_QUOTES
-                            );
-                            $sent_to[] = "<span title='".$username."'>".$user_info['complete_name']."</span>";
-                        }
-                    }
-                    $sent_to          = implode('@@', $sent_to);
-                    $sent_to          = str_replace('@@', '</div><div class="label_tag notice">', $sent_to);
-                    $event['sent_to'] = '<div class="label_tag notice">'.$sent_to.'</div>';
-                }
-
-                //Event sent to everyone!
-                if (empty($event['sent_to'])) {
-                    $event['sent_to'] = '<div class="label_tag notice">'.get_lang('Everyone').'</div>';
-                }
-
-                $event['description'] = $row['content'];
-                $event['allDay']      = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
-
-                $this->events[] = $event;
-            }
-        }
-
-        return $this->events;
-    }
-
-    /**
-     * @param int $start
-     * @param int $end
-     * @return array
-     */
-    public function get_platform_events($start, $end)
-    {
-        $start = intval($start);
-        $end   = intval($end);
-
-        $start = api_get_utc_datetime($start);
-        $end   = api_get_utc_datetime($end);
-
-        $access_url_id = api_get_current_access_url_id();
-
-        $sql = "SELECT * FROM ".$this->tbl_global_agenda."
-				   WHERE start_date >= '".$start."' AND end_date <= '".$end."' AND access_url_id = $access_url_id ";
-
-        $result    = Database::query($sql);
-        $my_events = array();
-        if (Database::num_rows($result)) {
-            while ($row = Database::fetch_array($result, 'ASSOC')) {
-                $event                = array();
-                $event['id']          = 'platform_'.$row['id'];
-                $event['title']       = $row['title'];
-                $event['className']   = 'platform';
-                $event['allDay']      = 'false';
-                $event['borderColor'] = $event['backgroundColor'] = $this->event_platform_color;
-                $event['editable']    = false;
-
-                $event['type'] = 'admin';
-
-                if (api_is_platform_admin() && $this->type == 'admin') {
-                    $event['editable'] = true;
-                }
-
-                if (!empty($row['start_date']) && $row['start_date'] != '0000-00-00 00:00:00') {
-                    $event['start'] = $this->format_event_date($row['start_date']);
-                }
-                if (!empty($row['end_date']) && $row['end_date'] != '0000-00-00 00:00:00') {
-                    $event['end'] = $this->format_event_date($row['end_date']);
-                }
-
-                $event['description'] = $row['content'];
-                $event['allDay']      = isset($row['all_day']) && $row['all_day'] == 1 ? $row['all_day'] : 0;
-
-                $my_events[]    = $event;
-                $this->events[] = $event;
-            }
-        }
-
-        return $my_events;
-    }
-
-    /**
-     * Format needed for the Fullcalendar js lib
-     * @param string UTC time
-     * @return string
-     */
-    public function format_event_date($utc_time)
-    {
-        return date('c', api_strtotime(api_get_local_time($utc_time)));
-    }
-
-    /**
-     * this function shows the form with the user that were not selected
-     * @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
-     * @return string html code
-     */
-    static function construct_not_selected_select_form(
-        $group_list = null,
-        $user_list = null,
-        $to_already_selected = array()
-    ) {
-        $html = '<select id="users_to_send_id" data-placeholder="'.get_lang(
-            'Select'
-        ).'" name="users_to_send[]" multiple="multiple" style="width:250px" class="chzn-select">';
-
-        if ($to_already_selected == 'everyone') {
-            $html .= '<option value="everyone" checked="checked">'.get_lang('Everyone').'</option>';
-        } else {
-            $html .= '<option value="everyone">'.get_lang('Everyone').'</option>';
-        }
-
-        if (is_array($group_list)) {
-            $html .= '<optgroup label="'.get_lang('Groups').'">';
-            foreach ($group_list as $this_group) {
-                if (!is_array($to_already_selected) || !in_array("GROUP:".$this_group['id'], $to_already_selected)) {
-                    // $to_already_selected is the array containing the groups (and users) that are already selected
-                    $count_users = isset($this_group['count_users']) ? $this_group['count_users'] : $this_group['userNb'];
-                    $count_users = " &ndash; $count_users ".get_lang('Users');
-
-                    $html .= '<option value="GROUP:'.$this_group['id'].'"> '.$this_group['name'].$count_users.'</option>';
-                }
-            }
-            $html .= '</optgroup>';
-        }
-
-        // adding the individual users to the select form
-        if (is_array($group_list)) {
-            $html .= '<optgroup label="'.get_lang('Users').'">';
-        }
-        foreach ($user_list as $this_user) {
-            // $to_already_selected is the array containing the users (and groups) that are already selected
-            if (!is_array($to_already_selected) || !in_array("USER:".$this_user['user_id'], $to_already_selected)) {
-                $username = api_htmlentities(sprintf(get_lang('LoginX'), $this_user['username']), ENT_QUOTES);
-                // @todo : add title attribute $username in the jqdialog window. wait for a chosen version to inherit title attribute
-                $html .= '<option title="'.$username.'" value="USER:'.$this_user['user_id'].'">'.api_get_person_name(
-                    $this_user['firstname'],
-                    $this_user['lastname']
-                ).' ('.$this_user['username'].') </option>';
-            }
-        }
-        if (is_array($group_list)) {
-            $html .= '</optgroup>';
-            $html .= "</select>";
-        }
-
-        return $html;
-    }
-
-    static function construct_not_selected_select_form_validator(
-        $form,
-        $group_list = null,
-        $user_list = null,
-        $to_already_selected = array()
-    ) {
-
-        $params = array(
-            'id'               => 'users_to_send_id',
-            'data-placeholder' => get_lang('Select'),
-            'multiple'         => 'multiple',
-            'style'            => 'width:250px',
-            'class'            => 'chzn-select'
-        );
-
-        $select = $form->addElement('select', 'users_to_send', get_lang('To'), null, $params);
-
-        $select->addOption(get_lang('Everyone'), 'everyone');
-
-        $options = array();
-        if (is_array($group_list)) {
-            foreach ($group_list as $this_group) {
-                if (!is_array($to_already_selected) || !in_array("GROUP:".$this_group['id'], $to_already_selected)) {
-                    // $to_already_selected is the array containing the groups (and users) that are already selected
-                    $count_users = isset($this_group['count_users']) ? $this_group['count_users'] : $this_group['userNb'];
-                    $count_users = " &ndash; $count_users ".get_lang('Users');
-                    $options[]   = array(
-                        'text'  => $this_group['name'].$count_users,
-                        'value' => "GROUP:".$this_group['id']
-                    );
-                }
-            }
-            $select->addOptGroup($options, get_lang('Groups'));
-        }
-
-        // adding the individual users to the select form
-        if (is_array($group_list)) {
-            $options = array();
-            foreach ($user_list as $this_user) {
-                // $to_already_selected is the array containing the users (and groups) that are already selected
-                if (!is_array($to_already_selected) || !in_array("USER:".$this_user['user_id'], $to_already_selected)) {
-                    //$username = api_htmlentities(sprintf(get_lang('LoginX'), $this_user['username']), ENT_QUOTES);
-                    // @todo : add title attribute $username in the jqdialog window. wait for a chosen version to inherit title attribute
-                    // from <option> to <li>
-                    //$html .= '<option title="'.$username.'" value="USER:'.$this_user['user_id'].'">'.api_get_person_name($this_user['firstname'], $this_user['lastname']).' ('.$this_user['username'].') </option>';
-                    $options[] = array(
-                        'text'  => api_get_person_name(
-                            $this_user['firstname'],
-                            $this_user['lastname']
-                        ).' ('.$this_user['username'].')',
-                        'value' => "USER:".$this_user['user_id']
-                    );
-                }
-            }
-            $select->addOptGroup($options, get_lang('Users'));
-        }
-    }
-
-    /**
-     * This public function separates the users from the groups
-     * users have a value USER:XXX (with XXX the dokeos id
-     * groups have a value GROUP:YYY (with YYY the group id)
-     * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
-     * @param array
-     * @return array
-     */
-    public function separate_users_groups($to)
-    {
-        $grouplist = array();
-        $userlist  = array();
-        $send_to   = null;
-
-        $send_to['everyone'] = false;
-        if (is_array($to) && count($to) > 0) {
-            foreach ($to as $to_item) {
-                if ($to_item == 'everyone') {
-                    $send_to['everyone'] = true;
-                } else {
-                    list($type, $id) = explode(':', $to_item);
-                    switch ($type) {
-                        case 'GROUP':
-                            $grouplist[] = $id;
-                            break;
-                        case 'USER':
-                            $userlist[] = $id;
-                            break;
-                    }
-                }
-            }
-            $send_to['groups'] = $grouplist;
-            $send_to['users']  = $userlist;
-
-        }
-
-        return $send_to;
-    }
-
-    /**
-     * @param array $params
-     */
-    static function show_form($params = array())
-    {
-        $form = new FormValidator('add_event', 'POST', api_get_self().'?'.api_get_cidreq(), null, array('enctype' => 'multipart/form-data'));
-        $id   = isset($params['id']) ? $params['id'] : null;
-
-        if ($id) {
-            $form_title = get_lang('ModifyCalendarItem');
-            $button     = get_lang('ModifyEvent');
-        } else {
-            $form_title = get_lang('AddCalendarItem');
-            $button     = get_lang('AgendaAdd');
-        }
-
-        $form->addElement('header', $form_title);
-        $form->addElement('hidden', 'id', $id);
-        $form->addElement('hidden', 'action', $params['action']);
-        $form->addElement('hidden', 'id_attach', $params['id_attach']);
-
-        $form->addElement('text', 'title', get_lang('ItemTitle'));
-
-        $group_id = api_get_group_id();
-
-        if (isset ($group_id) && !empty($group_id)) {
-            $form->addElement('hidden', 'selected_form[0]', "GROUP:'.$group_id.'");
-            $form->addElement('hidden', 'to', 'true');
-        } else {
-            self::show_to_form($form, $to);
-        }
-
-        $form->addElement('text', 'start_date', get_lang('StartDate'));
-        $form->addElement('text', 'end_date', get_lang('EndDate'));
-
-        if (empty($id)) {
-            $form->addElement(
-                'advanced_settings',
-                '<a href="javascript://" onclick="return plus_repeated_event();"><span id="plus2">
-                                                  <img style="vertical-align:middle;" src="../img/div_show.gif" alt="" />&nbsp;'.get_lang(
-                    'RepeatEvent'
-                ).'</span>
-                                </a>'
-            );
-            $form->addElement('html', '<div style="display:block">');
-
-            $form->addElement('checkbox', 'repeat', null, get_lang('RepeatEvent'));
-
-            $repeat_events = array(
-                'daily'         => get_lang('RepeatDaily'),
-                'weekly'        => get_lang('RepeatWeekly'),
-                'monthlyByDate' => get_lang('RepeatMonthlyByDate'),
-                'yearly'        => get_lang('RepeatYearly')
-            );
-
-            $form->addElement('select', 'repeat_type', get_lang('RepeatType'), $repeat_events);
-            $form->addElement('text', 'repeat_end_day', get_lang('RepeatEnd'));
-            $form->addElement('html', '</div>');
-
-            if (!api_is_allowed_to_edit(null, true)) {
-                $toolbar = 'AgendaStudent';
-            } else {
-                $toolbar = 'Agenda';
-            }
-            //$form->addElement('html_editor', 'content', get_lang('Description'), null, array('ToolbarSet' => $toolbar, 'Width' => '100%', 'Height' => '200'));
-
-            $form->addElement('file', 'user_upload', get_lang('AddAnAttachment'));
-            $form->addElement('text', 'file_comment', get_lang('Comment'));
-        }
-
-        $form->addElement('button', 'submit', $button);
-        $form->display();
-    }
-
-    /**
-     * @param array $form
-     * @param $to_already_selected
-     */
-    public static function show_to_form($form, $to_already_selected)
-    {
-        $order = 'lastname';
-        if (api_is_western_name_order()) {
-            $order = 'firstname';
-        }
-        $user_list  = CourseManager::get_user_list_from_course_code(
-            api_get_course_id(),
-            api_get_session_id(),
-            null,
-            $order
-        );
-        $group_list = CourseManager::get_group_list_of_course(api_get_course_id(), api_get_session_id());
-
-        self::construct_not_selected_select_form_validator($form, $group_list, $user_list, $to_already_selected);
-    }
-}

+ 2 - 2
main/calendar/agenda.php

@@ -41,7 +41,7 @@ if (empty($action)) {
 
 /* 	Resource linker */
 $_SESSION['source_type'] = 'Agenda';
-require_once '../resourcelinker/resourcelinker.inc.php';
+require_once api_get_path(SYS_CODE_PATH).'resourcelinker/resourcelinker.inc.php';
 
 if (!empty($addresources)) {
     // When the "Add Resource" button is clicked we store all the form data into a session
@@ -122,7 +122,7 @@ $htmlHeadXtra[] = to_javascript();
 $htmlHeadXtra[] = user_group_filter_javascript();
 
 // this loads the javascript that is needed for the date popup selection
-$htmlHeadXtra[] = "<script src=\"tbl_change.js\" type=\"text/javascript\" language=\"javascript\"></script>";
+$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/calendar/tbl_change.js" type="text/javascript" ></script>';
 
 // setting the name of the tool
 $nameTools = get_lang('Agenda'); // language variable in trad4all.inc.php

+ 1 - 2
main/calendar/agenda_js.php

@@ -21,7 +21,6 @@ if ($type == 'personal') {
 }
 
 require_once '../inc/global.inc.php';
-require_once 'agenda.lib.php';
 require_once 'agenda.inc.php';
 
 $current_course_tool  = TOOL_CALENDAR_EVENT;
@@ -197,4 +196,4 @@ if ((api_is_allowed_to_edit() || $is_group_tutor) && $course_code != '-1' && $ty
     $select = $agenda->construct_not_selected_select_form($group_list, $user_list, array());
     $tpl->assign('visible_to', $select);
 }
-$tpl->display('default/agenda/month.tpl');
+$tpl->display('default/agenda/month.tpl');

+ 1 - 2
main/calendar/allagendas.php

@@ -49,7 +49,6 @@ if (!empty ($course_path)) {
 	$interbreadcrumb[] = array ('url' => api_get_path(WEB_COURSE_PATH).urlencode($course_path).'/index.php', 'name' => Security::remove_XSS($_GET['courseCode']));
 }
 // this loads the javascript that is needed for the date popup selection
-//$htmlHeadXtra[] = "<script src=\"tbl_change.js\" type=\"text/javascript\" language=\"javascript\"></script>";
 
 // showing the header
 Display::display_header(get_lang('MyAgenda'));
@@ -381,4 +380,4 @@ if (isset ($_user['user_id'])) {
 	}
 }
 echo "</td></tr></table>";
-Display :: display_footer();
+Display :: display_footer();

+ 1 - 1
main/calendar/calendar.php

@@ -95,7 +95,7 @@ table.calendar td
     } // end if
 /* ]]> */
 </script>
-<script type="text/javascript" src="tbl_change.js"></script>
+<script src="<?php echo api_get_path(WEB_LIBRARY_PATH).'javascript/calendar/tbl_change.js'; ?>"></script>
 <script type="text/javascript">
 /* <![CDATA[ */
 var month_names = new Array(

+ 1 - 2
main/calendar/ical_export.php

@@ -18,7 +18,6 @@ $this_section = SECTION_MYAGENDA;
 api_block_anonymous_users();
 
 require_once api_get_path(LIBRARY_PATH).'icalcreator/iCalcreator.class.php';
-require_once api_get_path(SYS_CODE_PATH).'calendar/agenda.lib.php';
 
 // setting the name of the tool
 $nameTools = get_lang('MyAgenda');
@@ -141,4 +140,4 @@ if (!empty($event)) {
 } else {
 	header('location:'.Security::remove_XSS($_SERVER['HTTP_REFERER']));
 	die();
-}
+}

+ 2 - 1
main/calendar/myagenda.php

@@ -29,7 +29,8 @@ if (!empty ($course_path)) {
 }
 // this loads the javascript that is needed for the date popup selection
 $htmlHeadXtra[] = to_javascript();
-$htmlHeadXtra[] = "<script src=\"tbl_change.js\" type=\"text/javascript\" language=\"javascript\"></script>";
+$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/calendar/tbl_change.js" type="text/javascript" ></script>';
+
 $htmlHeadXtra[] = "<script>
 $(function() {
     $(\".dialog\").dialog(\"destroy\");

+ 1 - 1
main/conference/api.php

@@ -298,4 +298,4 @@ if ($action == "uploadgui") {
             }
         }
     }
-}
+}

+ 1 - 1
main/conference/get_translation.lib.php

@@ -2,7 +2,7 @@
 /* See license terms in /license.txt */
 /**
  * Library for language translation from Chamilo language files to XML for videoconference
- * @uses main_api.lib.php for api_get_path()
+ * @uses api.lib.php for api_get_path()
  */
 /**
  * This function reads a Chamilo language file and transforms it into XML,

+ 2 - 1
main/course_home/course_home.php

@@ -102,8 +102,9 @@ if (!isset($coursesAlreadyVisited[$course_code])) {
 
 $show_autolaunch_exercise_warning = false;
 
-//Exercise auto-launch
+// Exercise auto-launch
 $auto_launch = api_get_course_setting('enable_exercise_auto_launch');
+
 if (!empty($auto_launch)) {
     $session_id = api_get_session_id();
      //Exercise list

+ 3 - 4
main/course_info/delete_course.php

@@ -14,9 +14,8 @@
 // Language files that need to be included
 $language_file = array('admin', 'course_info');
 
-require_once '../inc/global.inc.php';
-require_once '../gradebook/lib/be/gradebookitem.class.php';
-require_once '../gradebook/lib/be/category.class.php';
+require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/be/gradebookitem.class.php';
+require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/be/category.class.php';
 $this_section = SECTION_COURSES;
 $current_course_tool  = TOOL_COURSE_MAINTENANCE;
 api_protect_course_script(true);
@@ -42,7 +41,7 @@ if (isset($_GET['delete']) && $_GET['delete'] == 'yes') {
     $message .=get_lang('HasDel');
 	$message .= '<br /><br /><a href="../../index.php">'.get_lang('BackHome').' '.api_get_setting('siteName').'</a>';
 
-} else {	
+} else {
     $message = '<h3>'.get_lang('Course').' : '.$current_course_name.' ('.$current_course_code.') </h3>';
     $message .= '<p>'.get_lang('ByDel').'</p><p><a class="btn btn-primary" href="maintenance.php">'.get_lang('No').'</a>&nbsp;<a class="btn" href="'.api_get_self().'?delete=yes">'.get_lang('Yes').'</a></p>';
 	$interbreadcrumb[] = array('url' => 'maintenance.php', 'name' => get_lang('Maintenance'));

+ 1 - 2
main/course_info/download.php

@@ -7,7 +7,6 @@
 /**
  * Code
  */
-//session_cache_limiter('public');
 require_once '../inc/global.inc.php';
 $this_section = SECTION_COURSES;
 
@@ -46,11 +45,11 @@ if (Security::check_abs_path($archive_path.$archive_file, $archive_path)) {
     header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
     header('Cache-Control: public');
     header('Pragma: no-cache');
-
     header('Content-Type: '.$content_type);
     header('Content-Length: '.filesize($archive_path.$archive_file));
     header('Content-Disposition: attachment; filename='.$archive_file);
     readfile($archive_path.$archive_file);
+    exit;
 } else {
     api_not_allowed(true);
 }

+ 8 - 7
main/course_info/infocours.php

@@ -109,7 +109,7 @@ while ($cat = Database::fetch_array($res)) {
 $linebreak = '<div class="row"><div class="label"></div><div class="formw" style="border-bottom:1px dashed grey"></div></div>';
 
 // Build the form
-$form = new FormValidator('update_course');
+$form = new FormValidator('update_course', 'post', api_get_self().'?'.api_get_cidreq());
 
 // COURSE SETTINGS
 $form->addElement('html', '<div><h3>'.Display::return_icon('settings.png', Security::remove_XSS(get_lang('CourseSettings')),'',ICON_SIZE_SMALL).' '.Security::remove_XSS(get_lang('CourseSettings')).'</h3><div>');
@@ -161,7 +161,6 @@ $form->applyFilter('department_name', 'trim');
 $form->add_textfield('department_url', get_lang('DepartmentUrl'), false, array('class' => 'span5'));
 //$form->addRule('tutor_name', get_lang('ThisFieldIsRequired'), 'required');
 
-
 // Picture
 $form->addElement('file', 'picture', get_lang('AddPicture'));
 $allowed_picture_types = array ('jpg', 'jpeg', 'png', 'gif');
@@ -430,7 +429,7 @@ $form->setDefaults($values);
 if ($form->validate() && is_settings_editable()) {
     $update_values = $form->exportValues();
 
-    $pdf_export_watermark_path = $_FILES['pdf_export_watermark_path'];
+    $pdf_export_watermark_path = isset($_FILES['pdf_export_watermark_path']) ? $_FILES['pdf_export_watermark_path'] : null;
 
     if (!empty($pdf_export_watermark_path['name'])) {
         $pdf_export_watermark_path_result = PDF::upload_watermark($pdf_export_watermark_path['name'], $pdf_export_watermark_path['tmp_name'], $course_code);
@@ -438,13 +437,14 @@ if ($form->validate() && is_settings_editable()) {
     }
 
     //Variables that will be saved in the TABLE_MAIN_COURSE table
-    $update_in_course_table = array('title', 'course_language','category_code','department_name', 'department_url','visibility',
-    								'subscribe', 'unsubscribe','tutor_name','course_registration_password', 'legal', 'activate_legal');
+    $update_in_course_table = array(
+        'title', 'course_language','category_code','department_name', 'department_url','visibility',
+        'subscribe', 'unsubscribe','tutor_name','course_registration_password', 'legal', 'activate_legal'
+    );
 
-    foreach ($update_values as $index =>$value) {
+    foreach ($update_values as $index => $value) {
         $update_values[$index] = Database::escape_string($value);
     }
-    unset($value);
     $table_course = Database :: get_main_table(TABLE_MAIN_COURSE);
 
     $sql = "UPDATE $table_course SET
@@ -460,6 +460,7 @@ if ($form->validate() && is_settings_editable()) {
         activate_legal          = '".$update_values['activate_legal']."',
         registration_code 	    = '".$update_values['course_registration_password']."'
         WHERE code = '".$course_code."'";
+
     Database::query($sql);
 
     // Update course_settings table - this assumes those records exist, otherwise triggers an error

+ 8 - 10
main/coursecopy/classes/CourseArchiver.class.php

@@ -23,7 +23,7 @@ class CourseArchiver
         if ($handle = @ opendir($dir)) {
             while (($file = readdir($handle)) !== false) {
                 if ($file != "." && $file != ".." && strpos($file, 'CourseArchiver_') === 0 && is_dir($dir . '/' . $file)) {
-                    rmdirr($dir . '/' . $file);
+                    api_rmdirr($dir . '/' . $file);
                 }
             }
             closedir($handle);
@@ -41,11 +41,11 @@ class CourseArchiver
         CourseArchiver::clean_backup_dir();
 
         // Create a temp directory
-        $tmp_dir_name = 'CourseArchiver_'.api_get_unique_id();
-        $backup_dir = api_get_path(SYS_ARCHIVE_PATH).$tmp_dir_name . '/';
+        $tmp_dir_name = 'CourseArchiver_' . api_get_unique_id();
+        $backup_dir = api_get_path(SYS_ARCHIVE_PATH) . $tmp_dir_name . '/';
 
         // All course-information will be stored in course_info.dat
-        $course_info_file = $backup_dir.'course_info.dat';
+        $course_info_file = $backup_dir . 'course_info.dat';
         $zip_dir = api_get_path(SYS_ARCHIVE_PATH);
         $user = api_get_user_info();
         $date = new DateTime(api_get_local_time());
@@ -72,6 +72,7 @@ class CourseArchiver
             error_log(__FILE__ . ' line ' . __LINE__ . ': ' . (ini_get('track_errors') != false ? $php_errormsg : 'error not recorded because track_errors is off in your php.ini'), 0);
         }
 
+
         // Copy all documents to the temp-dir
         if (isset($course->resources[RESOURCE_DOCUMENT]) && is_array($course->resources[RESOURCE_DOCUMENT])) {
             foreach ($course->resources[RESOURCE_DOCUMENT] as $document) {
@@ -124,7 +125,7 @@ class CourseArchiver
         $zip->create($zip_dir . $tmp_dir_name, PCLZIP_OPT_REMOVE_PATH, $zip_dir . $tmp_dir_name . '/');
         //$zip->deleteByIndex(0);
         // Remove the temp-dir.
-        rmdirr($backup_dir);
+        api_rmdirr($backup_dir);
         return $zip_file;
     }
 
@@ -182,8 +183,7 @@ class CourseArchiver
         mkdir($unzip_dir, api_get_permissions_for_new_directories(), true);
         copy(api_get_path(SYS_ARCHIVE_PATH).$filename, $unzip_dir.'/backup.zip');
         // unzip the archive
-
-        $zip = new PclZip($unzip_dir.'/backup.zip');
+        $zip = new PclZip($unzip_dir . '/backup.zip');
         chdir($unzip_dir);
         $list = $zip->extract(PCLZIP_OPT_TEMP_FILE_ON);
 
@@ -192,19 +192,17 @@ class CourseArchiver
             $errorMessage = $zip->errorInfo(true);
             $app['session']->getFlashBag()->add('warning', $errorMessage);*/
         }
-
         // remove the archive-file
         if ($delete) {
             if (file_exists(api_get_path(SYS_ARCHIVE_PATH).$filename)) {
                 unlink(api_get_path(SYS_ARCHIVE_PATH).$filename);
-            }
+        }
         }
 
         // Read the course
         if (!is_file('course_info.dat')) {
             return new Course();
         }
-
         $contents = file_get_contents('course_info.dat');
         // CourseCopyLearnpath class appeared in Chamilo 1.8.7, it is the former Learnpath class in the "Copy course" tool.
         // For backward comaptibility with archives created on Chamilo 1.8.6.2 or older systems, we have to do the following:

+ 2 - 2
main/coursecopy/classes/CourseRecycler.class.php

@@ -79,7 +79,7 @@ class CourseRecycler
         if ($this->course->has_resources(RESOURCE_DOCUMENT)) {
             $table = Database :: get_course_table(TABLE_DOCUMENT);
             foreach ($this->course->resources[RESOURCE_DOCUMENT] as $id => $document) {
-                rmdirr($this->course->backup_path.'/'.$document->path);
+                api_rmdirr($this->course->backup_path.'/'.$document->path);
             }
             $ids = implode(',', (array_keys($this->course->resources[RESOURCE_DOCUMENT])));
             $sql = "DELETE FROM ".$table." WHERE c_id = ".$this->course_id." AND id IN(".$ids.")";
@@ -446,7 +446,7 @@ class CourseRecycler
                     {
                         // The directory trat contains files of the SCORM package is to be deleted.
                         $scorm_package_dir = realpath($this->course->path . 'scorm/' . $learnpath->path);
-                        rmdirr($scorm_package_dir);
+                        api_rmdirr($scorm_package_dir);
                     }
                 }
 

+ 2 - 2
main/coursecopy/classes/CourseRestorer.class.php

@@ -564,7 +564,7 @@ class CourseRestorer
 
                                         $path_title = '/'.$new_base_foldername.'/'.$document_path[2];
 
-                                        copy_folder_course_session(
+                                        api_copy_folder_course_session(
                                             $basedir_dest_path,
                                             $base_path_document,
                                             $session_id,
@@ -841,7 +841,7 @@ class CourseRestorer
                 if (file_exists($path.$document->path)) {
                     switch ($this->file_option) {
                         case FILE_OVERWRITE :
-                            rmdirr($path.$document->path);
+                            api_rmdirr($path.$document->path);
                             FileManager::copyDirTo(
                                 $this->course->backup_path.'/'.$document->path,
                                 $path.dirname($document->path),

+ 1 - 1
main/coursecopy/classes/DummyCourseCreator.class.php

@@ -62,7 +62,7 @@ class DummyCourseCreator
 		$cr = new CourseRestorer($this->course);
 		$cr->set_file_option(FILE_OVERWRITE);
 		$cr->restore($course_code);
-		rmdirr($tmp_path);
+		api_rmdirr($tmp_path);
 	}
 	/**
 	 * Create dummy documents

+ 8 - 10
main/coursecopy/classes/Resource.class.php

@@ -77,11 +77,11 @@ class Resource
      */
     function Resource($id, $type)
     {
-        $this->source_id        = $id;
-        $this->type             = $type;
-        $this->destination_id   = -1;
+        $this->source_id = $id;
+        $this->type = $type;
+        $this->destination_id = -1;
         $this->linked_resources = array();
-        $this->item_properties  = array();
+        $this->item_properties = array();
     }
 
     /**
@@ -111,7 +111,6 @@ class Resource
         ) {
             return in_array($resource->get_id(), $this->linked_resources[$resource->get_type()]);
         }
-
         return false;
     }
 
@@ -136,8 +135,8 @@ class Resource
     /**
      * Get the constant which defines the tool of this resource. This is
      * used in the item_properties table.
-     * @param bool $for_item_property_table (optional)    Added by Ivan, 29-AUG-2009: A parameter for resolving differencies between defined TOOL_* constants and hardcoded strings that are stored in the database.
-     * Example: The constant TOOL_THREAD is defined in the main_api.lib.php with the value 'thread', but the "Forums" tool records in the field 'tool' in the item property table the hardcoded value 'forum_thread'.
+     * @param bool $for_item_property_table (optional)	Added by Ivan, 29-AUG-2009: A parameter for resolving differencies between defined TOOL_* constants and hardcoded strings that are stored in the database.
+     * Example: The constant TOOL_THREAD is defined in the api.lib.php with the value 'thread', but the "Forums" tool records in the field 'tool' in the item property table the hardcoded value 'forum_thread'.
      * @todo once the RESOURCE_* constants are replaced by the globally
      * defined TOOL_* constants, this function will be replaced by get_type()
      */
@@ -157,14 +156,13 @@ class Resource
             case RESOURCE_ANNOUNCEMENT:
                 return TOOL_ANNOUNCEMENT;
             case RESOURCE_FORUMCATEGORY:
-                return 'forum_category'; // Ivan, 29-AUG-2009: A constant like TOOL_FORUM_CATEGORY is missing in main_api.lib.php. Such a constant has been defined in the forum tool for local needs.
+                return 'forum_category'; // Ivan, 29-AUG-2009: A constant like TOOL_FORUM_CATEGORY is missing in api.lib.php. Such a constant has been defined in the forum tool for local needs.
             case RESOURCE_FORUM:
                 return TOOL_FORUM;
             case RESOURCE_FORUMTOPIC:
                 if ($for_item_property_table) {
                     return 'forum_thread'; // Ivan, 29-AUG-2009: A hardcoded value that the "Forums" tool stores in the item property table.
                 }
-
                 return TOOL_THREAD;
             case RESOURCE_FORUMPOST:
                 return TOOL_POST;
@@ -222,4 +220,4 @@ class Resource
     {
         //echo 'RESOURCE: '.$this->get_id().' '.$type[$this->get_type()].' ';
     }
-}
+}

+ 4 - 1
main/coursecopy/import_backup.php

@@ -57,6 +57,7 @@ if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form') || (is
     if (isset($_POST['action']) && $_POST['action'] == 'course_select_form') {
         // Partial backup here we recover the documents posted
         $course = CourseSelectForm::get_posted_course();
+
     } else {
         $backupServer = isset($_POST['backup_server']) ? $_POST['backup_server'] : null;
         if ($backupServer == 'server') {
@@ -81,6 +82,7 @@ if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form') || (is
         }
     }
 
+
     if (!$error && $course->has_resources()) {
 
         $cr = new CourseRestorer($course);
@@ -138,7 +140,7 @@ if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form') || (is
     $backups = CourseArchiver::get_available_backups($user);
     $backups_available = count($backups) > 0;
 
-    $form = new FormValidator('import_backup_form', 'post', api_get_path(WEB_CODE_PATH).'coursecopy/import_backup.php', '', 'multipart/form-data');
+    $form = new FormValidator('import_backup_form', 'post', api_get_path(WEB_PUBLIC_PATH).'main/coursecopy/import_backup.php', '', 'multipart/form-data');
     $form->addElement('header', get_lang('SelectBackupFile'));
     $renderer = $form->defaultRenderer();
     $renderer->setElementTemplate('<div>{element}</div> ');
@@ -198,6 +200,7 @@ if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form') || (is
     );
 
     $form->addElement('html', '<br /><br />');
+
     $form->addElement('html', get_lang('SameFilename'));
     $form->addElement('html', '<br /><br />');
     $form->addElement(

+ 3 - 5
main/create_course/add_course.php

@@ -43,12 +43,12 @@ $htmlHeadXtra[] = '<script>
     function advanced_parameters() {
         if(document.getElementById(\'options\').style.display == \'none\') {
             document.getElementById(\'options\').style.display = \'block\';
-            document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;<img style="vertical-align:middle;" src="../img/div_hide.gif" alt="" />&nbsp;'.get_lang(
+            document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;'.Display::return_icon('div_hide.gif').'&nbsp;'.get_lang(
     'AdvancedParameters'
 ).'\';
         } else {
             document.getElementById(\'options\').style.display = \'none\';
-            document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;<img style="vertical-align:middle;" src="../img/div_show.gif" alt="" />&nbsp;'.get_lang(
+            document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;'.Display::return_icon('div_show.gif').'&nbsp;'.get_lang(
     'AdvancedParameters'
 ).'\';
         }
@@ -87,7 +87,7 @@ $form->addElement(
 $form->applyFilter('title', 'html_filter');
 $form->addRule('title', get_lang('ThisFieldIsRequired'), 'required');
 
-$advanced = '<a href="javascript://" onclick=" return advanced_parameters()"><span id="img_plus_and_minus"><div style="vertical-align:top;" ><img style="vertical-align:middle;" src="../img/div_show.gif" alt="" />&nbsp;'.get_lang(
+$advanced = '<a href="javascript://" onclick=" return advanced_parameters()"><span id="img_plus_and_minus"><div style="vertical-align:top;" >'.Display::return_icon('div_show.gif').'&nbsp;'.get_lang(
     'AdvancedParameters'
 ).'</div></span></a>';
 $form->addElement('advanced_settings', $advanced);
@@ -265,7 +265,6 @@ if ($form->validate()) {
 
                 $template = $tpl->get_template('create_course/add_course.tpl');
                 $tpl->display($template);
-                exit;
             } else {
                 $message = Display :: return_message(get_lang('CourseCreationFailed'), 'error', false);
                 // Display the form.
@@ -315,4 +314,3 @@ if ($form->validate()) {
 
 $tpl->assign('message', $message);
 $tpl->assign('content', $content);
-$tpl->display();

+ 6 - 3
main/css/base.css

@@ -5152,12 +5152,13 @@ i.size-32.icon-new-work {
 
 .pagination .current a {
     cursor: default;
+    color:white !important;
     background-color: #3a87ad !important;
 }
 
 .pagination .before a, .pagination .before a:hover {
-    background-color: #999;
-    color: white;
+    background-color: #EEECE1;
+    color: #0D0D0C;
 }
 
 .pagination .after a, .pagination .after a:hover {
@@ -5167,7 +5168,8 @@ i.size-32.icon-new-work {
 
 .pagination .remind a, .pagination .remind a:hover {
     /* text-decoration: underline; */
-    background-color: #f89406
+    background-color: #f89406;
+    color:white;
 }
 
 .pagination .not_answered a , .pagination .not_answered a:hover {
@@ -5176,6 +5178,7 @@ i.size-32.icon-new-work {
 
 .pagination .answered a , .pagination .answered a:hover {
     background-color: green;
+    color: white;
 }
 
 .exercise_reminder_item {

+ 3 - 3
main/document/create_document.php

@@ -293,7 +293,7 @@ if (!$is_certificate_mode) {
         "name" => get_lang('Documents')
     );
 } else {
-    $interbreadcrumb[] = array('url' => '../gradebook/'.$_SESSION['gradebook_dest'], 'name' => get_lang('Gradebook'));
+    $interbreadcrumb[] = array('url' => api_get_path(WEB_CODE_PATH).'gradebook/'.$_SESSION['gradebook_dest'], 'name' => get_lang('Gradebook'));
 }
 if (!($is_allowed_to_edit || $_SESSION['group_member_with_upload_rights'] || is_my_shared_folder(
     $_user['user_id'],
@@ -347,7 +347,7 @@ function document_exists($filename)
     global $filepath;
     $filename = addslashes(trim($filename));
     $filename = Security::remove_XSS($filename);
-    $filename = replace_dangerous_char($filename);
+    $filename = api_replace_dangerous_char($filename);
     $filename = FileManager::disable_dangerous_file($filename);
 
     return !file_exists($filepath.$filename.'.html');
@@ -518,7 +518,7 @@ if ($form->validate()) {
     $filename = $values['title'];
     $filename = addslashes(trim($filename));
     $filename = Security::remove_XSS($filename);
-    $filename = replace_dangerous_char($filename);
+    $filename = api_replace_dangerous_char($filename);
     $filename = FileManager::disable_dangerous_file($filename);
 
     //Setting the title

+ 2 - 2
main/document/document.php

@@ -533,7 +533,7 @@ $_SESSION['image_files_only'] = '';
 $image_files_only = '';
 
 if ($is_certificate_mode) {
-    $interbreadcrumb[] = array('url' => '../gradebook/index.php', 'name' => get_lang('Gradebook'));
+    $interbreadcrumb[] = array('url' => api_get_path(WEB_CODE_PATH).'gradebook/index.php', 'name' => get_lang('Gradebook'));
 } else {
     if ((isset($_GET['id']) && $_GET['id'] != 0) || isset($_GET['curdirpath']) || isset($_GET['createdir'])) {
         $interbreadcrumb[] = array('url' => 'document.php', 'name' => get_lang('Documents'));
@@ -892,7 +892,7 @@ if ($is_allowed_to_edit || $group_member_with_upload_rights || is_my_shared_fold
                 $curdirpath = $document_data['path'];
             }
             $added_slash = ($curdirpath == '/') ? '' : '/';
-            $dir_name = $curdirpath.$added_slash.replace_dangerous_char($post_dir_name);
+            $dir_name = $curdirpath.$added_slash.api_replace_dangerous_char($post_dir_name);
             $dir_name = FileManager::disable_dangerous_file($dir_name);
             $dir_check = $base_work_dir.$dir_name;
 

+ 1 - 1
main/document/document_lite.php

@@ -632,7 +632,7 @@ if ($is_allowed_to_edit || $group_member_with_upload_rights || is_my_shared_fold
                 $curdirpath = $document_data['path'];
             }
             $added_slash = ($curdirpath == '/') ? '' : '/';
-            $dir_name = $curdirpath.$added_slash.replace_dangerous_char($post_dir_name);
+            $dir_name = $curdirpath.$added_slash.api_replace_dangerous_char($post_dir_name);
             $dir_name = FileManager::disable_dangerous_file($dir_name);
             $dir_check = $base_work_dir.$dir_name;
 

+ 3 - 1
main/document/document_slideshow.inc.php

@@ -70,8 +70,10 @@ $image_files_only = sort_files($array_to_search);
 $_SESSION['image_files_only'] = $image_files_only;
 
 function sort_files($table) {
-
 	global $tablename_direction, $accepted_extensions;
+    if (!is_array($accepted_extensions)) {
+        $accepted_extensions = array();
+    }
 	$temp = array();
 
 	foreach ($table as & $file_array) {

+ 2 - 2
main/document/save_pixlr.php

@@ -70,7 +70,7 @@ $contents = file_get_contents($urlcontents_to_save);//replace line 45.
 //a bit title security
 $filename = addslashes(trim($filename));
 $filename = Security::remove_XSS($filename);
-$filename = replace_dangerous_char($filename, 'strict');
+$filename = api_replace_dangerous_char($filename, 'strict');
 $filename = FileManager::disable_dangerous_file($filename);
 
 if (strlen(trim($filename)) == 0) {
@@ -246,4 +246,4 @@ if (!isset($_SESSION['exit_pixlr'])) {
     $location = api_get_path(WEB_CODE_PATH).'document/document.php?id='.Security::remove_XSS($_SESSION['exit_pixlr']);
     echo '<script>window.parent.location.href="'.$location.'"</script>';
     unset($_SESSION['exit_pixlr']);
-}
+}

+ 4 - 4
main/dropbox/dropbox_config.inc.php

@@ -27,10 +27,10 @@ $dropbox_cnf['sysPath'] 				= api_get_path(SYS_COURSE_PATH) . $_course['path'] .
 $dropbox_cnf['webPath'] 				= api_get_path(WEB_COURSE_PATH) . $_course['path'] . '/dropbox';
 $dropbox_cnf['maxFilesize'] 			= api_get_setting('dropbox_max_filesize'); //file size limit as imposed by the platform admin (see Chamilo Config Settings on the platform administration section)
 //$dropbox_cnf['version'] 				= '1.4';
-$dropbox_cnf['allowOverwrite'] 			= string_2_boolean(api_get_setting('dropbox_allow_overwrite'));
-$dropbox_cnf['allowJustUpload'] 		= string_2_boolean(api_get_setting('dropbox_allow_just_upload'));
-$dropbox_cnf['allowStudentToStudent'] 	= string_2_boolean(api_get_setting('dropbox_allow_student_to_student'));
-$dropbox_cnf['allowGroup'] 				= string_2_boolean(api_get_setting('dropbox_allow_group'));
+$dropbox_cnf['allowOverwrite'] 			= api_string_2_boolean(api_get_setting('dropbox_allow_overwrite'));
+$dropbox_cnf['allowJustUpload'] 		= api_string_2_boolean(api_get_setting('dropbox_allow_just_upload'));
+$dropbox_cnf['allowStudentToStudent'] 	= api_string_2_boolean(api_get_setting('dropbox_allow_student_to_student'));
+$dropbox_cnf['allowGroup'] 				= api_string_2_boolean(api_get_setting('dropbox_allow_group'));
 
 /**
  * INITIALISE MAILING VARIABLES

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

@@ -908,7 +908,7 @@ function store_add_dropbox()
     // Try to add an extension to the file if it hasn't got one
     $dropbox_filename = FileManager::add_ext_on_mime($dropbox_filename, $dropbox_filetype);
     // Replace dangerous characters
-    $dropbox_filename = replace_dangerous_char($dropbox_filename);
+    $dropbox_filename = api_replace_dangerous_char($dropbox_filename);
     // Transform any .php file in .phps fo security
     $dropbox_filename = FileManager::php2phps($dropbox_filename);
 

+ 1 - 1
main/dropbox/dropbox_submit.php

@@ -91,7 +91,7 @@ if (isset($_POST['submitWork'])) {
             // Try to add an extension to the file if it hasn't got one
             $dropbox_filename = FileManager::add_ext_on_mime($dropbox_filename, $dropbox_filetype);
             // Replace dangerous characters
-            $dropbox_filename = replace_dangerous_char($dropbox_filename);
+            $dropbox_filename = api_replace_dangerous_char($dropbox_filename);
             // Transform any .php file in .phps fo security
             $dropbox_filename = FileManager::php2phps($dropbox_filename);
             if (!FileManager::filter_extension($dropbox_filename)) {

+ 18 - 16
main/exercice/admin.php

@@ -58,6 +58,8 @@ require_once 'answer.class.php';
 $language_file = 'exercice';
 
 require_once '../inc/global.inc.php';
+$urlMainExercise = api_get_path(WEB_CODE_PATH).'exercice/';
+
 $current_course_tool = TOOL_QUIZ;
 $this_section = SECTION_COURSES;
 
@@ -116,11 +118,11 @@ if (empty($questionId)) {
 delete_all_incomplete_attempts(api_get_user_id(), $exerciseId, api_get_course_int_id(), api_get_session_id());
 
 /** @var Exercise $objExercise */
-$objExercise = isset($_SESSION['objExercise']) ? $_SESSION['objExercise'] : 0;
+$objExercise = Session::read('objExercise');
 /** @var Question $objQuestion */
-$objQuestion = isset($_SESSION['objQuestion']) ? $_SESSION['objQuestion'] : 0;
+$objQuestion = Session::read('objQuestion');
 /** @var Answer $objAnswer */
-$objAnswer = isset($_SESSION['objAnswer']) ? $_SESSION['objAnswer'] : 0;
+$objAnswer = Session::read('objAnswer');
 
 // document path
 $documentPath = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document';
@@ -215,7 +217,7 @@ if (!empty($cancelExercise)) {
     } else {
         // new exercise
         // goes back to the exercise list
-        header('Location: exercice.php');
+        header('Location: '.$urlMainExercise.'exercice.php');
         exit();
     }
 }
@@ -225,7 +227,7 @@ if (!empty($cancelQuestion)) {
     // if we are creating a new question from the question pool
     if (!$exerciseId && !$questionId) {
         // goes back to the question pool
-        header('Location: question_pool.php');
+        header('Location: '.$urlMainExercise.'question_pool.php');
         exit();
     } else {
         // goes back to the question viewing
@@ -234,7 +236,6 @@ if (!empty($cancelQuestion)) {
     }
 }
 
-
 if (!empty($clone_question) && !empty($objExercise->id)) {
 
     $old_question_obj = Question::read($clone_question, api_get_course_int_id());
@@ -252,7 +253,7 @@ if (!empty($clone_question) && !empty($objExercise->id)) {
     // Reloading tne $objExercise obj
     $objExercise->read($objExercise->id);
 
-    header('Location: admin.php?'.api_get_cidreq().'&exerciseId='.$objExercise->id);
+    header('Location: '.$urlMainExercise.'admin.php?'.api_get_cidreq().'&exerciseId='.$objExercise->id);
     exit;
 }
 
@@ -281,9 +282,9 @@ if (!empty($gradebook) && $gradebook == 'view') {
     );
 }
 
-$interbreadcrumb[] = array("url" => "exercice.php", "name" => get_lang('Exercices'));
+$interbreadcrumb[] = array("url" => $urlMainExercise."exercice.php", "name" => get_lang('Exercices'));
 if (isset($_GET['newQuestion']) || isset($_GET['editQuestion'])) {
-    $interbreadcrumb[] = array("url" => "admin.php?exerciseId=".$objExercise->id, "name" => $objExercise->name);
+    $interbreadcrumb[] = array("url" => $urlMainExercise."admin.php?exerciseId=".$objExercise->id, "name" => $objExercise->name);
 } else {
     $interbreadcrumb[] = array("url" => "#", "name" => $objExercise->name);
 }
@@ -296,6 +297,7 @@ if (!empty($modifyIn) && $modifyIn == 'thisExercise') {
         $noPHP_SELF = true;
     }
 }
+
 $htmlHeadXtra[] = '<script>
 
 function multiple_answer_true_false_onchange(variable) {
@@ -471,7 +473,7 @@ $inATest = isset($exerciseId) && $exerciseId > 0;
 if ($inATest) {
     echo '<div class="actions">';
     if (isset($_GET['hotspotadmin']) || isset($_GET['newQuestion']) || isset($_GET['myid'])) {
-        echo '<a href="admin.php?exerciseId='.$exerciseId.'">'.Display::return_icon(
+        echo '<a href="'.$urlMainExercise.'admin.php?exerciseId='.$exerciseId.'">'.Display::return_icon(
             'back.png',
             get_lang('GoBackToQuestionList'),
             '',
@@ -480,14 +482,14 @@ if ($inATest) {
     }
 
     if (!isset($_GET['hotspotadmin']) && !isset($_GET['newQuestion']) && !isset($_GET['myid']) && !isset($_GET['editQuestion'])) {
-        echo '<a href="exercice.php?'.api_get_cidReq().'">'.Display::return_icon(
+        echo '<a href="'.$urlMainExercise.'exercice.php?'.api_get_cidReq().'">'.Display::return_icon(
             'back.png',
             get_lang('BackToExercisesList'),
             '',
             ICON_SIZE_MEDIUM
         ).'</a>';
     }
-    echo '<a href="overview.php?'.api_get_cidreq().'&exerciseId='.$objExercise->id.'&preview=1">'.Display::return_icon(
+    echo '<a href="'.$urlMainExercise.'overview.php?'.api_get_cidreq().'&exerciseId='.$objExercise->id.'&preview=1">'.Display::return_icon(
         'preview_view.png',
         get_lang('Preview'),
         '',
@@ -496,7 +498,7 @@ if ($inATest) {
 
     echo Display::url(
         Display::return_icon('test_results.png', get_lang('Results'), '', ICON_SIZE_MEDIUM),
-        'exercise_report.php?'.api_get_cidReq().'&exerciseId='.$objExercise->id
+        $urlMainExercise.'exercise_report.php?'.api_get_cidReq().'&exerciseId='.$objExercise->id
     );
 
     if ($objExercise->edit_exercise_in_lp == false) {
@@ -507,7 +509,7 @@ if ($inATest) {
             ICON_SIZE_MEDIUM
         ).'</a>';
     } else {
-        echo '<a href="exercise_admin.php?'.api_get_cidreq().'&modifyExercise=yes&exerciseId='.$objExercise->id.'">'.Display::return_icon(
+        echo '<a href="'.$urlMainExercise.'exercise_admin.php?'.api_get_cidreq().'&modifyExercise=yes&exerciseId='.$objExercise->id.'">'.Display::return_icon(
             'settings.png',
             get_lang('ModifyExercise'),
             '',
@@ -532,7 +534,7 @@ if ($inATest) {
     if (isset($_GET['newQuestion'])) {
         // we are in create a new question from question pool not in a test
         echo '<div class="actions">';
-        echo '<a href="admin.php?'.api_get_cidreq().'">.'.Display::return_icon(
+        echo '<a href="'.$urlMainExercise.'admin.php?'.api_get_cidreq().'">.'.Display::return_icon(
             'back.png',
             get_lang('GoBackToQuestionList'),
             '',
@@ -542,7 +544,7 @@ if ($inATest) {
     } else {
         // If we are in question_poolbut not in an test, go back to question create in pool
         echo '<div class="actions">';
-        echo '<a href="question_pool.php">'.Display::return_icon(
+        echo '<a href="'.$urlMainExercise.'question_pool.php">'.Display::return_icon(
             'back.png',
             get_lang('GoBackToQuestionList'),
             '',

+ 4 - 4
main/exercice/adminhp.php

@@ -62,8 +62,9 @@ $nameTools = get_lang('adminHP');
 Display::display_header($nameTools,"Exercise");
 
 /** @todo probably wrong !!!! */
-require_once(api_get_path(SYS_CODE_PATH).'/exercice/hotpotatoes.lib.php');
+require_once api_get_path(SYS_CODE_PATH).'exercice/hotpotatoes.lib.php';
 
+$urlMainExercise = api_get_path(WEB_CODE_PATH).'exercice/';
 ?>
 
 <h4>
@@ -75,15 +76,14 @@ if (isset($newName)) {
     if ($newName!="") {
         //alter database record for that test
         SetComment($hotpotatoesName,$newName);
-        echo "<script language='Javascript' type='text/javascript'> window.location='exercice.php'; </script>";
+        echo "<script type='text/javascript'>window.location='".$urlMainExercise."exercice.php'; </script>";
     }
 }
 
-echo "<form action=\"".api_get_self()."\" method='post' name='form1'>";
+echo "<form action=\"".$urlMainExercise."adminhp.php\" method='post' name='form1'>";
 echo "<input type=\"hidden\" name=\"hotpotatoesName\" value=\"$hotpotatoesName\">";
 echo "<input type=\"text\" name=\"newName\" value=\"";
 
-
 $lstrComment = "";
 $lstrComment = GetComment($hotpotatoesName);
 if ($lstrComment=="") {

+ 6 - 4
main/exercice/answer_admin.inc.php

@@ -17,6 +17,8 @@ if (!is_object($objQuestion)) {
     $objQuestion = Question :: read($_GET['modifyAnswers']);
 }
 
+$urlMainExercise = api_get_path(WEB_CODE_PATH).'exercice/';
+
 $questionName = $objQuestion->selectTitle();
 $answerType = $objQuestion->selectType();
 $pictureName = $objQuestion->selectPicture();
@@ -147,7 +149,7 @@ if ($submitAnswers || $buttonBack) {
             } else {
                 // adds the answer into the object
                 $objAnswer->createAnswer($reponse[$i], $goodAnswer, $comment[$i], $weighting[$i], $i);
-                $mainurl = "admin.php";
+                $mainurl = $urlMainExercise."admin.php";
                 ?>
                 <script>
                     window.location.href='<?php echo $mainurl; ?>';
@@ -216,7 +218,7 @@ if ($submitAnswers || $buttonBack) {
                     $objAnswer->createAnswer($reponse, 0, '', 0, '');
                     $objAnswer->save();
                     //added
-                    $mainurl = "admin.php";
+                    $mainurl = $urlMainExercise."admin.php";
                     ?>
                     <script>
                         window.location.href='<?php echo $mainurl; ?>';
@@ -325,7 +327,7 @@ if ($submitAnswers || $buttonBack) {
                     $objQuestion->save($exerciseId);
                     $editQuestion = $questionId;
                     unset($modifyAnswers); //added
-                    $mainurl = "admin.php";
+                    $mainurl = $urlMainExercise."admin.php";
                     ?>
                     <script>
                         window.location.href='<?php echo $mainurl; ?>';
@@ -399,7 +401,7 @@ if ($submitAnswers || $buttonBack) {
                 else {
                     // adds the answer into the object
                     $objAnswer->createAnswer($match[$i], $sel[$i], '', $weighting[$i], $i);
-                    $mainurl = "admin.php";
+                    $mainurl = $urlMainExercise."admin.php";
                     ?>
                     <script>
                         window.location.href='<?php echo $mainurl; ?>';

+ 3 - 2
main/exercice/exercice.php

@@ -22,7 +22,7 @@ $language_file = array('exercice', 'tracking');
 require_once '../inc/global.inc.php';
 $current_course_tool = TOOL_QUIZ;
 
-require_once '../gradebook/lib/be.inc.php';
+require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/be.inc.php';
 
 // Setting the tabs
 $this_section = SECTION_COURSES;
@@ -627,7 +627,8 @@ if (!empty($exercise_list)) {
                         $class_tip = 'link_tooltip';
                     }
                     //$class_tip = 'exercise_link';
-                    $url = $move.'<a '.$alt_title.' class="'.$class_tip.'" id="tooltip_'.$my_exercise_id.'" href="overview.php?'.api_get_cidreq().$myorigin.$mylpid.$mylpitemid.'&exerciseId='.$my_exercise_id.'"><img src="../img/quiz.gif" /> '.$title.' </a>';
+                    $urlOverview =  'overview.php?'.api_get_cidreq().$myorigin.$mylpid.$mylpitemid.'&exerciseId='.$my_exercise_id;
+                    $url = $move.'<a '.$alt_title.' class="'.$class_tip.'" id="tooltip_'.$my_exercise_id.'" href="'.$urlOverview.'">'.Display::return_icon('quiz.gif').' '.$title.' </a>';
 
                     $item = Display::tag('td', $url.' '.$session_img.$lp_blocked);
 

+ 53 - 38
main/exercice/exercise.class.php

@@ -2658,11 +2658,12 @@ class Exercise
                         send_form();
                     }
                 });
+
                 $('#clock_warning').dialog('open');
 
                 $('#counter_to_redirect').epiclock({
                     mode: $.epiclock.modes.countdown,
-                    offset: {seconds: 5},
+                    offset: { seconds: 5 },
                     format: 's'
                 }).bind('timer', function () {
                     send_form();
@@ -2674,7 +2675,7 @@ class Exercise
                 if ($('#exercise_form').length) {
                     $('#exercise_form').submit();
                 } else {
-                    //In reminder
+                    // In reminder
                     final_submit();
                 }
             }
@@ -2684,7 +2685,7 @@ class Exercise
                 $('#exercise_form').hide();
                 $('#expired-message-id').show();
 
-                //Fixes bug #5263
+                // Fixes bug #5263.
                 $('#num_current_id').attr('value', '".$this->selectNbrQuestions()."');
                 open_clock_warning();
             }
@@ -2692,7 +2693,8 @@ class Exercise
 			$(document).ready(function() {
 
 				var current_time = new Date().getTime();
-                var time_left    = parseInt(".$time_left."); // time in seconds when using minutes there are some seconds lost
+				// Time in seconds. When using minutes there are some seconds lost.
+                var time_left    = parseInt(".$time_left.");
 				var expired_time = current_time + (time_left*1000);
 				var expired_date = get_expired_date_string(expired_time);
 
@@ -2704,6 +2706,7 @@ class Exercise
                 }).bind('timer', function () {
                     onExpiredTimeExercise();
                 });
+
 	       		$('#submit_save').click(function () {});
 	    });
 	    </script>";
@@ -3017,9 +3020,9 @@ class Exercise
 
             switch ($answerType) {
                 // for unique answer
-                case UNIQUE_ANSWER :
-                case UNIQUE_ANSWER_IMAGE :
-                case UNIQUE_ANSWER_NO_OPTION :
+                case UNIQUE_ANSWER:
+                case UNIQUE_ANSWER_IMAGE:
+                case UNIQUE_ANSWER_NO_OPTION:
                     if ($from_database) {
                         $queryans = "SELECT answer FROM ".$TBL_TRACK_ATTEMPT." WHERE exe_id = '".$exeId."' AND question_id= '".$questionId."'";
                         $resultans = Database::query($queryans);
@@ -3038,8 +3041,8 @@ class Exercise
                         }
                     }
                     break;
-                // for multiple answers
-                case MULTIPLE_ANSWER_TRUE_FALSE :
+                    // for multiple answers
+                case MULTIPLE_ANSWER_TRUE_FALSE:
                     if ($from_database) {
                         $choice = array();
                         $queryans = "SELECT answer FROM ".$TBL_TRACK_ATTEMPT." WHERE exe_id = ".$exeId." AND question_id = ".$questionId;
@@ -3073,7 +3076,7 @@ class Exercise
                     }
                     $totalScore = $questionScore;
                     break;
-                case MULTIPLE_ANSWER : //2
+                case MULTIPLE_ANSWER: //2
                     if ($from_database) {
                         $choice = array();
                         $queryans = "SELECT answer FROM ".$TBL_TRACK_ATTEMPT." WHERE exe_id = '".$exeId."' AND question_id= '".$questionId."'";
@@ -3340,22 +3343,30 @@ class Exercise
                     }
                     break;
                 // for free answer
-                case FREE_ANSWER :
+                case FREE_ANSWER:
                     if ($from_database) {
                         $query = "SELECT answer, marks FROM ".$TBL_TRACK_ATTEMPT." WHERE exe_id = '".$exeId."' AND question_id= '".$questionId."'";
                         $resq = Database::query($query);
-                        $choice = Database::result($resq, 0, 'answer');
-                        $choice = str_replace('\r\n', '', $choice);
-                        $choice = stripslashes($choice);
-                        $questionScore = Database::result($resq, 0, "marks");
+                        $questionScore = 0;
+                        $choice = null;
+                        if ($resq) {
+                            $row = Database::fetch_array($resq);
+                            $choice = $row['answer'];
+                            $questionScore = $row['marks'];
+                            $choice = str_replace('\r\n', '', $choice);
+                            $choice = stripslashes($choice);
+                        }
+
                         if ($questionScore == -1) {
                             $totalScore += 0;
                         } else {
                             $totalScore += $questionScore;
                         }
+
                         if ($questionScore == '') {
                             $questionScore = 0;
                         }
+
                         $arrques = $questionName;
                         $arrans = $choice;
                     } else {
@@ -4264,21 +4275,21 @@ class Exercise
                         if ($final_answer == 0) {
                             $questionScore = 0;
                         }
-                        saveExerciseAttempt($questionScore, 1, $quesId, $exeId, 0); // we always insert the answer_id 1 = delineation
+                        saveQuestionAttempt($questionScore, 1, $quesId, $exeId, 0); // we always insert the answer_id 1 = delineation
                         //in delineation mode, get the answer from $hotspot_delineation_result[1]
                         saveExerciseAttemptHotspot($exeId, $quesId, $objAnswerTmp->getRealAnswerIdFromList(1), $hotspot_delineation_result[1], $exerciseResultCoordinates[$quesId]);
                     } else {
                         if ($final_answer == 0) {
                             $questionScore = 0;
                             $answer = 0;
-                            saveExerciseAttempt($questionScore, $answer, $quesId, $exeId, 0);
+                            saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0);
                             if (is_array($exerciseResultCoordinates[$quesId])) {
                                 foreach ($exerciseResultCoordinates[$quesId] as $idx => $val) {
                                     saveExerciseAttemptHotspot($exeId, $quesId, $objAnswerTmp->getRealAnswerIdFromList($idx), 0, $val);
                                 }
                             }
                         } else {
-                            saveExerciseAttempt($questionScore, $answer, $quesId, $exeId, 0);
+                            saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0);
                             if (is_array($exerciseResultCoordinates[$quesId])) {
                                 foreach ($exerciseResultCoordinates[$quesId] as $idx => $val) {
                                     saveExerciseAttemptHotspot($exeId, $quesId, $objAnswerTmp->getRealAnswerIdFromList($idx), $choice[$idx], $val);
@@ -4341,13 +4352,13 @@ class Exercise
                     $reply = array_keys($choice);
                     for ($i = 0; $i < sizeof($reply); $i++) {
                         $ans = $reply[$i];
-                        saveExerciseAttempt($questionScore, $ans.':'.$choice[$ans], $quesId, $exeId, $i, $this->id);
+                        saveQuestionAttempt($questionScore, $ans.':'.$choice[$ans], $quesId, $exeId, $i, $this->id);
                         if ($debug) {
                             error_log('result =>'.$questionScore.' '.$ans.':'.$choice[$ans]);
                         }
                     }
                 } else {
-                    saveExerciseAttempt($questionScore, 0, $quesId, $exeId, 0, $this->id);
+                    saveQuestionAttempt($questionScore, 0, $quesId, $exeId, 0, $this->id);
                 }
             } elseif ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) {
                 if ($choice != 0) {
@@ -4358,46 +4369,46 @@ class Exercise
                     }
                     for ($i = 0; $i < sizeof($reply); $i++) {
                         $ans = $reply[$i];
-                        saveExerciseAttempt($questionScore, $ans, $quesId, $exeId, $i, $this->id);
+                        saveQuestionAttempt($questionScore, $ans, $quesId, $exeId, $i, $this->id);
                     }
                 } else {
-                    saveExerciseAttempt($questionScore, 0, $quesId, $exeId, 0, $this->id);
+                    saveQuestionAttempt($questionScore, 0, $quesId, $exeId, 0, $this->id);
                 }
             } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION) {
                 if ($choice != 0) {
                     $reply = array_keys($choice);
                     for ($i = 0; $i < sizeof($reply); $i++) {
                         $ans = $reply[$i];
-                        saveExerciseAttempt($questionScore, $ans, $quesId, $exeId, $i, $this->id);
+                        saveQuestionAttempt($questionScore, $ans, $quesId, $exeId, $i, $this->id);
                     }
                 } else {
-                    saveExerciseAttempt($questionScore, 0, $quesId, $exeId, 0, $this->id);
+                    saveQuestionAttempt($questionScore, 0, $quesId, $exeId, 0, $this->id);
                 }
             } elseif ($answerType == MATCHING || $answerType == DRAGGABLE) {
                 if (isset($matching)) {
                     foreach ($matching as $j => $val) {
-                        saveExerciseAttempt($questionScore, $val, $quesId, $exeId, $j, $this->id);
+                        saveQuestionAttempt($questionScore, $val, $quesId, $exeId, $j, $this->id);
                     }
                 }
             } elseif ($answerType == FREE_ANSWER) {
                 $answer = $choice;
-                saveExerciseAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id);
+                saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id);
             } elseif ($answerType == ORAL_EXPRESSION) {
                 $answer = $choice;
-                saveExerciseAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id, $nano);
+                saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id, $nano);
             } elseif ($answerType == UNIQUE_ANSWER || $answerType == UNIQUE_ANSWER_IMAGE || $answerType == UNIQUE_ANSWER_NO_OPTION) {
                 $answer = $choice;
-                saveExerciseAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id);
+                saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id);
                 //            } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) {
             } elseif ($answerType == HOT_SPOT) {
-                saveExerciseAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id);
+                saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id);
                 if (isset($exerciseResultCoordinates[$questionId]) && !empty($exerciseResultCoordinates[$questionId])) {
                     foreach ($exerciseResultCoordinates[$questionId] as $idx => $val) {
                         saveExerciseAttemptHotspot($exeId, $quesId, $objAnswerTmp->getRealAnswerIdFromList($idx), $choice[$idx], $val, $this->id);
                     }
                 }
             } else {
-                saveExerciseAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id);
+                saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id);
             }
         }
 
@@ -4824,7 +4835,12 @@ class Exercise
 
     /**
      * Checks if the exercise is visible due a lot of conditions - visibility, time limits, student attempts
-     * @return bool true if is active
+     *
+     * @param int $lp_id
+     * @param int $lp_item_id
+     * @param int $lp_item_view_id
+     * @param bool $filter_by_admin
+     * @return array
      */
     public function is_visible($lp_id = 0, $lp_item_id = 0, $lp_item_view_id = 0, $filter_by_admin = true)
     {
@@ -5072,7 +5088,7 @@ class Exercise
     }
 
     /**
-     * Sets the question list when the exercise->read() is executed created depending of a parameter
+     * Sets the question list when the exercise->read() is executed
      */
     public function setQuestionList()
     {
@@ -5260,17 +5276,16 @@ class Exercise
     }
 
     /**
+     * Returns a time limit message
      * @return string
      */
     public function returnTimeLeftDiv()
     {
-        $html = '<div id="clock_warning" style="display:none">'.Display::return_message(
-            get_lang('ReachedTimeLimit'),
-            'warning'
-        ).' '.sprintf(
-            get_lang('YouWillBeRedirectedInXSeconds'),
+        $message = Display::return_message(
+            get_lang('ReachedTimeLimit'), 'warning' ).' '.sprintf(get_lang('YouWillBeRedirectedInXSeconds'),
             '<span id="counter_to_redirect" class="red_alert"></span>'
-        ).'</div>';
+        );
+        $html = '<div id="clock_warning" style="display:none">'.$message.'</div>';
         $html .= '<div class="row"><div class="pull-right"><div id="exercise_clock_warning" class="well count_down"></div></div></div>';
 
         return $html;

+ 3 - 1
main/exercice/exercise_history.php

@@ -16,6 +16,8 @@
 $language_file='exercice';
 
 require_once '../inc/global.inc.php';
+$urlMainExercise = api_get_path(WEB_CODE_PATH).'exercice/';
+
 $this_section=SECTION_COURSES;
 api_protect_course_script(true);
 
@@ -30,7 +32,7 @@ $is_allowedToEdit = api_is_allowed_to_edit(null,true);
 $is_tutor = api_is_allowed_to_edit(true);
 
 if(!$is_allowedToEdit){
-	header('Location: /main/exercice/exercice.php?cidReq='.Security::remove_XSS($_GET['cidReq']));
+	header('Location: '.$urlMainExercise.'exercice.php?cidReq='.Security::remove_XSS($_GET['cidReq']));
 	exit;
 }
 

+ 6 - 4
main/exercice/exercise_reminder.php

@@ -105,12 +105,14 @@ if ($time_control) {
 
 echo Display::div('', array('id' => 'message'));
 
+$urlMainExercise = api_get_path(WEB_CODE_PATH).'exercice/';
+
 echo '<script>
 		lp_data = $.param({"learnpath_id": '.$learnpath_id.', "learnpath_item_id" : '.$learnpath_item_id.', "learnpath_item_view_id": '.$learnpath_item_view_id.'});
 
         function final_submit() {
-        	//Normal inputs
-        	window.location = "exercise_result.php?origin='.$origin.'&exe_id='.$exe_id.'&" + lp_data;
+        	// Normal inputs
+        	window.location = "'.$urlMainExercise.'exercise_result.php?origin='.$origin.'&exe_id='.$exe_id.'&" + lp_data;
 		}
 
 		function review_questions() {
@@ -126,7 +128,7 @@ echo '<script>
 				$("#message").addClass("warning-message");
 				$("#message").html("'.addslashes(get_lang('SelectAQuestionToReview')).'");
 			}
-			window.location = "exercise_submit.php?'.api_get_cidreq().'&exerciseId='.$objExercise->id.'&reminder=2&origin='.$origin.'&" + lp_data;
+			window.location = "'.$urlMainExercise.'exercise_submit.php?'.api_get_cidreq().'&exerciseId='.$objExercise->id.'&reminder=2&origin='.$origin.'&" + lp_data;
 		}
 
 		function save_remind_item(obj, question_id) {
@@ -187,7 +189,7 @@ foreach ($question_list as $questionId) {
     }
 
     $checkbox = Display::input('checkbox', 'remind_list['.$questionId.']', '', $attributes);
-    $url = 'exercise_submit.php?exerciseId='.$objExercise->id.'&num='.$counter.'&reminder=1';
+    $url = $urlMainExercise.'exercise_submit.php?exerciseId='.$objExercise->id.'&num='.$counter.'&reminder=1';
 
     $counter++;
     if ($objExercise->type == ONE_PER_PAGE) {

+ 8 - 5
main/exercice/exercise_report.php

@@ -17,7 +17,8 @@ $language_file = array('exercice');
 
 // including the global library
 require_once '../inc/global.inc.php';
-require_once '../gradebook/lib/be.inc.php';
+require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/be.inc.php';
+$urlMainExercise = api_get_path(WEB_CODE_PATH).'exercice/';
 
 // Setting the tabs
 $this_section = SECTION_COURSES;
@@ -27,6 +28,8 @@ $htmlHeadXtra[] = api_get_jqgrid_js();
 // Access control
 api_protect_course_script(true, false, true);
 
+
+
 // including additional libraries
 require_once 'exercise.class.php';
 require_once 'question.class.php';
@@ -223,7 +226,7 @@ if (isset($_REQUEST['comments']) && $_REQUEST['comments'] == 'update' && ($is_al
         MessageManager::send_message_simple($student_id, $subject, $message, api_get_user_id());
     }
 
-    //Updating LP score here
+    // Updating LP score here
     if (in_array($origin, array('tracking_course', 'user_course', 'correct_exercise_in_lp'))) {
         $sql_update_score = "UPDATE $TBL_LP_ITEM_VIEW SET score = '".floatval(
             $tot
@@ -231,12 +234,12 @@ if (isset($_REQUEST['comments']) && $_REQUEST['comments'] == 'update' && ($is_al
         Database::query($sql_update_score);
         if ($origin == 'tracking_course') {
             //Redirect to the course detail in lp
-            header('location: exercice.php?course='.Security :: remove_XSS($_GET['course']));
+            header('Location: '.$urlMainExercise.'exercice.php?course='.Security :: remove_XSS($_GET['course']));
             exit;
         } else {
-            //Redirect to the reporting
+            // Redirect to the reporting
             header(
-                'location: ../mySpace/myStudents.php?origin='.$origin.'&student='.$student_id.'&details=true&course='.$course_id.'&session_id='.$session_id
+                'Location: '.api_get_path(WEB_CODE_PATH).'mySpace/myStudents.php?origin='.$origin.'&student='.$student_id.'&details=true&course='.$course_id.'&session_id='.$session_id
             );
             exit;
         }

+ 10 - 2
main/exercice/exercise_result.class.php

@@ -181,6 +181,9 @@ class ExerciseResult
             $hpresults[] = $rowx;
 		}
 
+        $filter_by_not_revised = false;
+        $filter_by_revised = false;
+
 		if ($filter) {
 			switch ($filter) {
 				case 1 :
@@ -207,8 +210,13 @@ class ExerciseResult
 				if (Database :: num_rows($query) > 0)
                     $revised = true;
 
-				if ($filter_by_not_revised && $revised) continue;
-				if ($filter_by_revised && !$revised) continue;
+				if ($filter_by_not_revised && $revised) {
+                    continue;
+                }
+
+				if ($filter_by_revised && !$revised) {
+                    continue;
+                }
 
 				$return[$i] = array();
 

+ 2 - 2
main/exercice/exercise_result.php

@@ -2,7 +2,7 @@
 /* For licensing terms, see /license.txt */
 /**
  * 	Exercise result
- * 	This script gets informations from the script "exercise_submit.php",
+ * 	This script gets information from the script "exercise_submit.php",
  * 	through the session, and calculates the score of the student for
  * 	that exercise.
  * 	Then it shows the results on the screen.
@@ -169,7 +169,7 @@ if ($origin != 'learnpath') {
     Display::display_footer();
 } else {
     $lp_mode = $_SESSION['lp_mode'];
-    $url = '../newscorm/lp_controller.php?cidReq='.api_get_course_id().'&action=view&lp_id='.$learnpath_id.'&lp_item_id='.$learnpath_item_id.'&exeId='.$exercise_stat_info['exe_id'].'&fb_type='.$objExercise->feedback_type;
+    $url = api_get_path(WEB_CODE_PATH).'newscorm/lp_controller.php?cidReq='.api_get_course_id().'&action=view&lp_id='.$learnpath_id.'&lp_item_id='.$learnpath_item_id.'&exeId='.$exercise_stat_info['exe_id'].'&fb_type='.$objExercise->feedback_type;
     $href = ($lp_mode == 'fullscreen') ? ' window.opener.location.href="'.$url.'" ' : ' top.location.href="'.$url.'"';
 
     if (api_is_allowed_to_session_edit()) {

+ 9 - 9
main/exercice/exercise_show.php

@@ -24,6 +24,7 @@ require_once 'exercise.class.php';
 require_once 'question.class.php'; //also defines answer type constants
 require_once 'answer.class.php';
 require_once '../inc/global.inc.php';
+$urlMainExercise = api_get_path(WEB_CODE_PATH).'exercice/';
 
 if (empty($origin) ) {
     $origin = isset($_REQUEST['origin']) ? $_REQUEST['origin'] : null;
@@ -113,8 +114,8 @@ if (!empty($gradebook) && $gradebook=='view') {
 
 $fromlink = '';
 
-$interbreadcrumb[]= array("url" => "exercice.php?gradebook=$gradebook","name" => get_lang('Exercices'));
-$interbreadcrumb[]= array("url" => "overview.php?exerciseId=".$exercise_id.'&id_session='.api_get_session_id(),"name" => $objExercise->name);
+$interbreadcrumb[]= array("url" => $urlMainExercise."exercice.php?gradebook=$gradebook","name" => get_lang('Exercices'));
+$interbreadcrumb[]= array("url" => $urlMainExercise."overview.php?exerciseId=".$exercise_id.'&id_session='.api_get_session_id(),"name" => $objExercise->name);
 $interbreadcrumb[]= array("url" => "#","name" => get_lang('Result'));
 
 $this_section = SECTION_COURSES;
@@ -175,7 +176,8 @@ if (!empty($track_exercise_info)) {
 			    echo '<table width="100%" border="0" cellspacing="0" cellpadding="0">
                       <tr>
                         <td colspan="2">';
-				Display::display_warning_message(get_lang('ThankYouForPassingTheTest').'<br /><br /><a href="exercice.php">'.(get_lang('BackToExercisesList')).'</a>', false);
+				Display::display_warning_message(get_lang('ThankYouForPassingTheTest').'<br /><br />
+				<a href="'.$urlMainExercise.'exercice.php">'.(get_lang('BackToExercisesList')).'</a>', false);
 				echo '</td>
 				</tr>
 				</table>';
@@ -317,12 +319,10 @@ foreach ($questionList as $questionId) {
         $questionScore   = $question_result['score'];
         $totalScore     += $question_result['score'];
 	} elseif ($answerType == FREE_ANSWER) {
-        $answer = $str;
         $question_result = $objExercise->manageAnswers($id, $questionId, $choice,'exercise_show', array(), false, true, $show_results);
         $questionScore   = $question_result['score'];
         $totalScore     += $question_result['score'];
 	} elseif ($answerType == ORAL_EXPRESSION) {
-		$answer = $str;
 		$question_result = $objExercise->manageAnswers($id, $questionId, $choice,'exercise_show', array(), false, true, $show_results);
 		$questionScore   = $question_result['score'];
 		$totalScore     += $question_result['score'];
@@ -705,14 +705,14 @@ if (is_array($arrid) && is_array($arrmarks)) {
 
 if ($is_allowedToEdit && $locked == false && !api_is_drh()) {
 	if (in_array($origin, array('tracking_course','user_course','correct_exercise_in_lp'))) {
-		echo '<form name="myform" id="myform" action="exercise_report.php?exerciseId='.$exercise_id.'&filter=2&comments=update&exeid='.$id.'&origin='.$origin.'&details=true&course='.Security::remove_XSS($_GET['cidReq']).$fromlink.'" method="post">';
+		echo '<form name="myform" id="myform" action="'.$urlMainExercise.'exercise_report.php?exerciseId='.$exercise_id.'&filter=2&comments=update&exeid='.$id.'&origin='.$origin.'&details=true&course='.Security::remove_XSS($_GET['cidReq']).$fromlink.'" method="post">';
 		echo '<input type = "hidden" name="lp_item_id"       value="'.$learnpath_id.'">';
 		echo '<input type = "hidden" name="lp_item_view_id"  value="'.$lp_item_view_id.'">';
 		echo '<input type = "hidden" name="student_id"       value="'.$student_id.'">';
 		echo '<input type = "hidden" name="total_score"      value="'.$totalScore.'"> ';
 		echo '<input type = "hidden" name="my_exe_exo_id"    value="'.$exercise_id.'"> ';
 	} else {
-		echo ' <form name="myform" id="myform" action="exercise_report.php?exerciseId='.$exercise_id.'&filter=1&comments=update&exeid='.$id.'" method="post">';
+		echo ' <form name="myform" id="myform" action="'.$urlMainExercise.'exercise_report.php?exerciseId='.$exercise_id.'&filter=1&comments=update&exeid='.$id.'" method="post">';
 	}
 	if ($origin !='learnpath' && $origin!='student_progress') {
 
@@ -732,7 +732,7 @@ if ($origin =='student_progress') { ?>
 <?php
 } else if($origin=='myprogress') {
 ?>
-	<button type="button" class="save" onclick="top.location.href='../auth/my_progress.php?course=<?php echo api_get_course_id()?>'" value="<?php echo get_lang('Finish'); ?>" >
+	<button type="button" class="save" onclick="top.location.href='<?php echo api_get_path(WEB_CODE_PATH); ?>auth/my_progress.php?course=<?php echo api_get_course_id()?>'" value="<?php echo get_lang('Finish'); ?>" >
         <?php echo get_lang('Finish');?>
     </button>
 <?php
@@ -744,7 +744,7 @@ if ($origin != 'learnpath') {
 } else {
 	if (!isset($_GET['fb_type'])) {
 		$lp_mode =  $_SESSION['lp_mode'];
-		$url = '../newscorm/lp_controller.php?'.api_get_cidreq().'&action=view&lp_id='.$learnpath_id.'&lp_item_id='.$learnpath_item_id.'&exeId='.$exeId.'&fb_type='.$feedback_type;
+		$url = api_get_path(WEB_CODE_PATH).'newscorm/lp_controller.php?'.api_get_cidreq().'&action=view&lp_id='.$learnpath_id.'&lp_item_id='.$learnpath_item_id.'&exeId='.$exeId.'&fb_type='.$feedback_type;
 		$href = ($lp_mode == 'fullscreen')?' window.opener.location.href="'.$url.'" ':' top.location.href="'.$url.'" ';
 		echo '<script type="text/javascript">'.$href.'</script>';
 

+ 117 - 67
main/exercice/exercise_submit.php

@@ -37,13 +37,18 @@ require_once 'answer.class.php';
 $language_file = 'exercice';
 
 require_once '../inc/global.inc.php';
+$urlMainExercise = api_get_path(WEB_CODE_PATH).'exercice/';
 $current_course_tool  = TOOL_QUIZ;
 
 $nameTools = get_lang('Quiz');
 
 $this_section = SECTION_COURSES;
 
-if ($debug) { error_log('--- Enter to the exercise_submit.php ---- '); error_log('0. POST variables : '.print_r($_POST,1)); }
+$debug = false;
+if ($debug) {
+    error_log('--- Enter to the exercise_submit.php ---- ');
+    error_log('0. POST variables : '.print_r($_POST,1));
+}
 
 // Notice for unauthorized people.
 api_protect_course_script(true);
@@ -310,36 +315,48 @@ $(function(){
 
 // General parameters passed via POST/GET
 
-$learnpath_id 			= isset($_REQUEST['learnpath_id']) ? intval($_REQUEST['learnpath_id']) : 0;
-$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;
+/*
+     <input type="hidden" name="formSent"				value="1" />
+     <input type="hidden" name="exerciseId" 			value="'.$exerciseId . '" />
+     <input type="hidden" name="num" 					value="'.$current_question.'" id="num_current_id" />
+     <input type="hidden" name="exe_id" 				value="'.$exe_id . '" />
+     <input type="hidden" name="origin" 				value="'.$origin . '" />
+     <input type="hidden" name="learnpath_id" 			value="'.$learnpath_id . '" />
+     <input type="hidden" name="learnpath_item_id" 		value="'.$learnpath_item_id . '" />
+     <input type="hidden" name="learnpath_item_view_id" value="'.$learnpath_item_view_id . '" />';*/
+
+// @todo check get and posts
+$learnpath_id 			= isset($_GET['learnpath_id']) ? intval($_GET['learnpath_id']) : 0;
+$learnpath_item_id 		= isset($_GET['learnpath_item_id']) ? intval($_GET['learnpath_item_id']) : 0;
+$learnpath_item_view_id	= isset($_GET['learnpath_item_view_id']) ? intval($_GET['learnpath_item_view_id']) : 0;
+$origin 				= isset($_GET['origin']) ? Security::remove_XSS($_GET['origin']) : '';
+$reminder 				= isset($_GET['reminder']) ? intval($_GET['reminder']) : 0;
+$remind_question_id 	= isset($_GET['remind_question_id']) ? intval($_GET['remind_question_id']) : 0;
 $exerciseId				= isset($_REQUEST['exerciseId']) ? intval($_REQUEST['exerciseId']) : 0;
-$formSent               = isset($_REQUEST['formSent']) ? $_REQUEST['formSent'] : null;
-$exerciseResult         = isset($_REQUEST['exerciseResult']) ? $_REQUEST['exerciseResult'] : null;
-$choice                 = isset($_REQUEST['choice']) ? $_REQUEST['choice'] : null;
-$choice                 = empty($choice) ? isset($_REQUEST['choice2']) ? $_REQUEST['choice2'] : null : null;
-$exerciseResultCoordinates = isset($_REQUEST['exerciseResultCoordinates']) ? $_REQUEST['exerciseResultCoordinates'] : null;
+$formSent               = isset($_POST['formSent']) ? $_POST['formSent'] : null;
+$exerciseResult         = isset($_GET['exerciseResult']) ? $_GET['exerciseResult'] : null;
+$choice                 = isset($_GET['choice']) ? $_GET['choice'] : null;
+$choice                 = empty($choice) ? isset($_GET['choice2']) ? $_GET['choice2'] : null : null;
+$exerciseResultCoordinates = isset($_GET['exerciseResultCoordinates']) ? $_GET['exerciseResultCoordinates'] : null;
 $current_question       = isset($_REQUEST['num']) ? intval($_REQUEST['num']) : null;
 
 //Error message
 $error = '';
 
-
-/*  Teacher takes an exam and want to see a preview, we delete the objExercise from the session in order to get the latest changes in the exercise */
+/*  Teacher takes an exam and want to see a preview,
+we delete the objExercise from the session in order to get the latest changes in the exercise */
 if (api_is_allowed_to_edit(null,true) && isset($_GET['preview']) && $_GET['preview'] == 1) {
     Session::erase('objExercise');
 }
+$exerciseInSession = Session::read('objExercise');
 
 // 1. Loading the $objExercise variable
-if (!isset($_SESSION['objExercise']) || isset($_SESSION['objExercise']) && ($_SESSION['objExercise']->id != $_REQUEST['exerciseId'])) {
+if (!isset($exerciseInSession) || isset($exerciseInSession) && ($exerciseInSession->id != $_GET['exerciseId'])) {
     // Construction of Exercise
     /** @var Exercise $objExercise */
     $objExercise = new Exercise();
     if ($debug) {error_log('1. Setting the $objExercise variable'); };
-    unset($_SESSION['questionList']);
+    Session::erase('questionList');
 
     // if the specified exercise doesn't exist or is disabled
     if (!$objExercise->read($exerciseId) || (!$objExercise->selectStatus() && !$is_allowedToEdit && ($origin != 'learnpath'))) {
@@ -349,22 +366,26 @@ if (!isset($_SESSION['objExercise']) || isset($_SESSION['objExercise']) && ($_SE
     } else {
         // Saves the object into the session
         Session::write('objExercise', $objExercise);
-        if ($debug) { error_log('1.1. $_SESSION[objExercise] was unset - set now - end'); };
+        if ($debug) {
+            error_log('1.1. $exerciseInSession was unset - set now - end');
+        };
     }
 }
 
 // $objExercise = new Exercise(); $objExercise->read($exerciseId);
 
 //2. Checking if $objExercise is set
-if (!isset($objExercise) && isset($_SESSION['objExercise'])) {
+if (!isset($objExercise) && isset($exerciseInSession)) {
 	if ($debug) { error_log('2. Loading $objExercise from session'); };
-    $objExercise = $_SESSION['objExercise'];
+    $objExercise = $exerciseInSession;
 }
 
 //3. $objExercise is not set, then return to the exercise list
 if (!is_object($objExercise)) {
-	if ($debug) {error_log('3. $objExercise was not set, kill the script'); };
-    header('Location: exercice.php');
+	if ($debug) {
+        error_log('3. $objExercise was not set, kill the script');
+    };
+    header('Location: '.$urlMainExercise.'exercice.php');
     exit;
 }
 
@@ -372,7 +393,7 @@ if (!is_object($objExercise)) {
 if ($objExercise->review_answers) {
 	if ($remind_question_id == -1) {
         $paramsReminder = "exerciseId=$exerciseId&origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&learnpath_item_view_id=$learnpath_item_view_id&".api_get_cidreq();
-        header('Location: exercise_reminder.php?'.$paramsReminder);
+        header('Location: '.$urlMainExercise.'exercise_reminder.php?'.$paramsReminder);
         exit;
 	}
 }
@@ -391,7 +412,12 @@ if ($debug) {
     error_log("4. current_expired_time_key: $current_expired_time_key ");
 }
 
-$_SESSION['duration_time'][$current_expired_time_key] = $current_timestamp;
+$durationTime = array(
+    $current_expired_time_key => $current_timestamp
+);
+Session::write('duration_time', $durationTime);
+
+//$_SESSION['duration_time'][$current_expired_time_key] = $current_timestamp;
 
 if ($time_control) {
     // Get the expired time of the current exercise in track_e_exercices.
@@ -406,6 +432,13 @@ $user_id = api_get_user_id();
 if ($objExercise->selectAttempts() > 0) {
     $attempt_html = null;
     $attempt_count = get_attempt_count($user_id, $exerciseId, $learnpath_id, $learnpath_item_id, $learnpath_item_view_id);
+    $warningMessage = Display::return_message(
+        sprintf(get_lang('ReachedMaxAttempts'),
+        $exercise_title,
+        $objExercise->selectAttempts()),
+        'warning',
+        false
+    );
 
 	if ($attempt_count >= $objExercise->selectAttempts()) {
 		$show_clock = false;
@@ -413,14 +446,19 @@ if ($objExercise->selectAttempts() > 0) {
 
 			if ($objExercise->results_disabled == 0 && $origin != 'learnpath') {
 
-				//Showing latest attempt according with task BT#1628
-				$exercise_stat_info = getExerciseResultsByUser($user_id, $exerciseId, api_get_course_int_id(), api_get_session_id());
+				// Showing latest attempt according with task BT#1628.
+				$exercise_stat_info = getExerciseResultsByUser(
+                    $user_id,
+                    $exerciseId,
+                    api_get_course_int_id(),
+                    api_get_session_id()
+                );
 
 				if (!empty($exercise_stat_info)) {
 					$max_exe_id = max(array_keys($exercise_stat_info));
 					$last_attempt_info = $exercise_stat_info[$max_exe_id];
 					$attempt_html .= Display::div(get_lang('Date').': '.api_get_local_time($last_attempt_info['exe_date']), array('id'=>''));
-					$attempt_html .= Display::return_message(sprintf(get_lang('ReachedMaxAttempts'), $exercise_title, $objExercise->selectAttempts()), 'warning', false);
+					$attempt_html .= $warningMessage;
 
 					if (!empty($last_attempt_info['question_list'])) {
 						foreach($last_attempt_info['question_list'] as $question_data) {
@@ -435,13 +473,13 @@ if ($objExercise->selectAttempts() > 0) {
 					$score = ExerciseLib::show_score($last_attempt_info['exe_result'], $last_attempt_info['exe_weighting']);
 					$attempt_html .= Display::div(get_lang('YourTotalScore').' '.$score, array('id'=>'question_score'));
 				} else {
-					$attempt_html .= Display::return_message(sprintf(get_lang('ReachedMaxAttempts'), $exercise_title, $objExercise->selectAttempts()), 'warning', false);
+					$attempt_html .= $warningMessage;
 				}
 			} else {
-				$attempt_html .= Display::return_message(sprintf(get_lang('ReachedMaxAttempts'), $exercise_title, $objExercise->selectAttempts()), 'warning', false);
+				$attempt_html .= $warningMessage;
 			}
 		} else {
-			$attempt_html .= Display :: return_message(sprintf(get_lang('ReachedMaxAttempts'), $exercise_title, $objExercise->selectAttempts()), 'warning', false);
+			$attempt_html .= $warningMessage;
 		}
 
 		if ($origin == 'learnpath') {
@@ -462,7 +500,8 @@ if ($objExercise->selectAttempts() > 0) {
 $exercise_stat_info = $objExercise->getStatTrackExerciseInfo($learnpath_id, $learnpath_item_id, $learnpath_item_view_id);
 
 //if (1) {
-if (!isset($_SESSION['questionList'])) {
+$questionListInSession = Session::read('questionList');
+if (!isset($questionListInSession)) {
     // Selects the list of question ID
     $questionList = $objExercise->getQuestionList();
 
@@ -476,7 +515,7 @@ if (!isset($_SESSION['questionList'])) {
     Session::write('questionList', $questionList);
     if ($debug > 0) { error_log('$_SESSION[questionList] was set'); }
 } else {
-	if (isset($objExercise) && isset($_SESSION['objExercise'])) {
+	if (isset($objExercise) && isset($exerciseInSession)) {
         $questionList = Session::read('questionList');
 	}
 }
@@ -507,8 +546,11 @@ if (empty($exercise_stat_info)) {
 		if ($debug) error_log('5.3. $expected_time '.$clock_expired_time);
 
 		//Sessions  that contain the expired time
-		$_SESSION['expired_time'][$current_expired_time_key] 	 = $clock_expired_time;
-		if ($debug) { error_log('5.4. Setting the $_SESSION[expired_time]: '.$_SESSION['expired_time'][$current_expired_time_key] ); };
+		$expiredTime = array(
+            $current_expired_time_key => $clock_expired_time
+        );
+        Session::write('expired_time', $expiredTime);
+		if ($debug) { error_log('5.4. Setting the $expiredTime: '.$expiredTime[$current_expired_time_key] ); };
 	}
 	$exe_id = $objExercise->save_stat_track_exercise_info($clock_expired_time, $learnpath_id, $learnpath_item_id, $learnpath_item_view_id, $questionListUncompressed, $total_weight);
 	$exercise_stat_info = $objExercise->getStatTrackExerciseInfo($learnpath_id, $learnpath_item_id, $learnpath_item_view_id);
@@ -534,7 +576,7 @@ if ($debug) { error_log("6.1 params: $params"); };
 
 if ($reminder == 2 && empty($my_remind_list)) {
     if ($debug) { error_log("6.2 calling the exercise_reminder.php "); };
-	header('Location: exercise_reminder.php?'.$params);
+	header('Location: '.$urlMainExercise.'exercise_reminder.php?'.$params);
 	exit;
 }
 
@@ -544,20 +586,22 @@ if ($reminder == 2 && empty($my_remind_list)) {
  */
 
 if ($time_control) {
-	if ($debug) error_log('7.1. Time control is enabled');
-	if ($debug) error_log('7.2. $current_expired_time_key  '.$current_expired_time_key);
-	if ($debug) error_log('7.3. $_SESSION[expired_time][$current_expired_time_key]  '.$_SESSION['expired_time'][$current_expired_time_key]);
+    $expiredTimeInSession = Session::read('expired_time');
 
-    if (!isset($_SESSION['expired_time'][$current_expired_time_key])) {
+	if ($debug) error_log('7.1. Time control is enabled.');
+	if ($debug) error_log('7.2. $current_expired_time_key:'.$current_expired_time_key);
+    if (!isset($expiredTimeInSession[$current_expired_time_key])) {
+        if ($debug) error_log('7.3. $expiredTimeInSession[$current_expired_time_key] not set.');
         //Timer - Get expired_time for a student
         if (!empty($exercise_stat_info)) {
         	if ($debug) {error_log('7.4 Seems that the session ends and the user want to retake the exam'); };
 	        $expired_time_of_this_attempt = $exercise_stat_info['expired_time_control'];
 			if ($debug) {error_log('7.5 $expired_time_of_this_attempt: '.$expired_time_of_this_attempt); }
-	        //Get the last attempt of an exercice
+	        // Get the last attempt of an exercise.
 	    	$last_attempt_date = getLastAttemptDateOfExercise($exercise_stat_info['exe_id']);
 
-	    	//This means that the user enters the exam but do not answer the first question we get the date from the track_e_exercises not from the track_et_attempt see #2069
+	    	/* This means that the user enters the exam but do not answer the first question we get the date
+            from the track_e_exercises not from the track_et_attempt see #2069 */
 	    	if (empty($last_attempt_date)) {
 	    		$diff = $current_timestamp - api_strtotime($exercise_stat_info['start_date'], 'UTC');
 	    		$last_attempt_date = api_get_utc_datetime(api_strtotime($exercise_stat_info['start_date'],'UTC') + $diff);
@@ -573,7 +617,7 @@ if ($time_control) {
 	        if ($debug) {error_log('7.7. $new_expired_time_in_seconds: '.$new_expired_time_in_seconds); }
 
 	        $expected_time	= $current_timestamp + $new_expired_time_in_seconds;
-	        if ($debug) {error_log('7.8. $expected_time1: '.$expected_time); }
+	        if ($debug) {error_log('7.8. $expected_time: '.$expected_time); }
 
 	        $clock_expired_time  = api_get_utc_datetime($expected_time);
 	        if ($debug) {error_log('7.9. $clock_expired_time: '.$clock_expired_time); }
@@ -583,11 +627,15 @@ if ($time_control) {
             ExerciseLib::update_attempt_date($exercise_stat_info['exe_id'], $last_attempt_date);
 
 	        //Sessions  that contain the expired time
-	        $_SESSION['expired_time'][$current_expired_time_key] 		= $clock_expired_time;
-	        if ($debug) {error_log('7.11. Setting the $_SESSION[expired_time]: '.$_SESSION['expired_time'][$current_expired_time_key] ); };
+	        $expiredTimeInSession[$current_expired_time_key] 		= $clock_expired_time;
+            Session::write('expired_time', $expiredTimeInSession);
+	        if ($debug) {
+                error_log('7.11. Setting the $expiredTimeInSession: '.$expiredTimeInSession[$current_expired_time_key] );
+            };
         }
     } else {
-        $clock_expired_time =  $_SESSION['expired_time'][$current_expired_time_key];
+        if ($debug) error_log('7.3. $expiredTimeInSession[$current_expired_time_key]: '.$expiredTimeInSession[$current_expired_time_key]);
+        $clock_expired_time =  $expiredTimeInSession[$current_expired_time_key];
     }
 } else {
     if ($debug) { error_log("7. No time control"); };
@@ -608,6 +656,7 @@ if ($time_control) {
 if ($debug) error_log('8. Question list loaded '.print_r($questionList, 1));
 
 $question_count = $objExercise->getCountCompressedQuestionList();
+$urlMainExercise = api_get_path(WEB_CODE_PATH).'exercice/';
 
 if ($formSent && isset($_POST)) {
     if ($debug) { error_log('9. $formSent was sent'); }
@@ -619,8 +668,8 @@ if ($formSent && isset($_POST)) {
     }
 
     // Only for hot spot
-    if (!isset($choice) && isset($_REQUEST['hidden_hotspot_id'])) {
-        $hotspot_id = (int)($_REQUEST['hidden_hotspot_id']);
+    if (!isset($choice) && isset($_GET['hidden_hotspot_id'])) {
+        $hotspot_id = (int)($_GET['hidden_hotspot_id']);
         $choice     = array($hotspot_id => '');
     }
 
@@ -671,8 +720,8 @@ if ($formSent && isset($_POST)) {
     Session::write('exerciseResultCoordinates',$exerciseResultCoordinates);
 
     // if all questions on one page OR if it is the last question (only for an exercise with one question per page)
-
     if (($objExercise->type == ALL_ON_ONE_PAGE || $current_question >= $question_count)) {
+
         if (api_is_allowed_to_session_edit()) {
             // goes to the script that will show the result of the exercise
             if ($objExercise->type == ALL_ON_ONE_PAGE) {
@@ -692,7 +741,7 @@ if ($formSent && isset($_POST)) {
                         }
                     }
                 }
-                header("Location: exercise_result.php?".api_get_cidreq()."&exe_id=$exe_id&origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&learnpath_item_view_id=$learnpath_item_view_id");
+                header("Location: ".$urlMainExercise."exercise_result.php?".api_get_cidreq()."&exe_id=$exe_id&origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&learnpath_item_view_id=$learnpath_item_view_id");
                 exit;
             } else {
                 //Time control is only enabled for ONE PER PAGE
@@ -707,12 +756,12 @@ if ($formSent && isset($_POST)) {
                     }
                 }
                 if ($debug) { error_log('10. Redirecting to exercise_show.php'); }
-                header("Location: exercise_result.php?".api_get_cidreq()."&exe_id=$exe_id&origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&learnpath_item_view_id=$learnpath_item_view_id");
+                header("Location: ".$urlMainExercise."exercise_result.php?".api_get_cidreq()."&exe_id=$exe_id&origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&learnpath_item_view_id=$learnpath_item_view_id");
                 exit;
             }
         } else {
             if ($debug) { error_log('10. Redirecting to exercise_submit.php'); }
-            header("Location: exercise_submit.php?".api_get_cidreq()."&exerciseId=$exerciseId&origin=$origin");
+            header("Location: ".$urlMainExercise."exercise_submit.php?".api_get_cidreq()."&exerciseId=$exerciseId&origin=$origin");
             exit;
         }
     }
@@ -769,10 +818,10 @@ if ($question_count != 0) {
 	                }
 	            }
 	            if ($objExercise->review_answers) {
-	            	header('Location: exercise_reminder.php?'.$params);
+	            	header('Location: '.$urlMainExercise.'exercise_reminder.php?'.$params);
 	            	exit;
 	            } else {
-	            	header("Location: exercise_result.php?".api_get_cidreq()."&exe_id=$exe_id&origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&learnpath_item_view_id=$learnpath_item_view_id");
+	            	header("Location: ".$urlMainExercise."exercise_result.php?".api_get_cidreq()."&exe_id=$exe_id&origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&learnpath_item_view_id=$learnpath_item_view_id");
                     exit;
 	            }
 	        }
@@ -800,7 +849,7 @@ if (!empty ($_GET['gradebook']) && $_GET['gradebook'] == 'view') {
 if (!empty ($gradebook) && $gradebook == 'view') {
     $interbreadcrumb[]= array ('url' => '../gradebook/' . Security::remove_XSS($_SESSION['gradebook_dest']),'name' => get_lang('ToolGradebook'));
 }
-$interbreadcrumb[]= array ("url" => "exercice.php?gradebook=$gradebook",	"name" => get_lang('Exercices'));
+$interbreadcrumb[]= array ("url" => $urlMainExercise."exercice.php?gradebook=$gradebook",	"name" => get_lang('Exercices'));
 $interbreadcrumb[]= array ("url" => "#","name" => $objExercise->name);
 
 if ($origin != 'learnpath') { //so we are not in learnpath tool
@@ -819,7 +868,7 @@ $show_quiz_edition = $objExercise->added_in_lp();
 if (api_is_course_admin() && $origin != 'learnpath') {
     echo '<div class="actions">';
     if ($show_quiz_edition == false) {
-    	echo '<a href="exercise_admin.php?' . api_get_cidreq() . '&modifyExercise=yes&exerciseId=' . $objExercise->id . '">'.Display :: return_icon('settings.png', get_lang('ModifyExercise'),'',ICON_SIZE_MEDIUM).'</a>';
+    	echo '<a href="'.$urlMainExercise.'exercise_admin.php?' . api_get_cidreq() . '&modifyExercise=yes&exerciseId=' . $objExercise->id . '">'.Display :: return_icon('settings.png', get_lang('ModifyExercise'),'',ICON_SIZE_MEDIUM).'</a>';
     } else {
     	echo '<a href="#">'.Display::return_icon('settings_na.png', get_lang('ModifyExercise'),'',ICON_SIZE_MEDIUM).'</a>';
     }
@@ -953,23 +1002,24 @@ if ($reminder == 2)  {
     } else {
     	if ($objExercise->review_answers) {
             if ($debug) { error_log('. redirecting to exercise_reminder.php '); }
-	    	header("Location: exercise_reminder.php?$params");
+	    	header("Location: ".$urlMainExercise."exercise_reminder.php?$params");
 	    	exit;
     	}
     }
 }
 
 if ($objExercise->review_answers) {
-	$script_php = 'exercise_reminder.php';
+	$script_php = $urlMainExercise.'exercise_reminder.php';
 } else {
-	$script_php = 'exercise_result.php';
+	$script_php = $urlMainExercise.'exercise_result.php';
 }
 
 if (!empty($error)) {
     Display :: display_error_message($error, false);
 } else {
     if (!empty($exercise_sound)) {
-        echo "<a href=\"../document/download.php?doc_url=%2Faudio%2F".Security::remove_XSS($exercise_sound)."\" target=\"_blank\">", "<img src=\"../img/sound.gif\" border=\"0\" align=\"absmiddle\" alt=", get_lang('Sound') . "\" /></a>";
+        echo '<a href="'.api_get_path(WEB_CODE_PATH).'document/download.php?doc_url=%2Faudio%2F'.Security::remove_XSS($exercise_sound).'" target="_blank">
+        '.Display::return_icon('sound.gif', get_lang('Sound')).'</a>';
     }
 
     // Get number of hotspot questions for javascript validation
@@ -1020,12 +1070,12 @@ if (!empty($error)) {
     		});
 
 			function previous_question(question_num) {
-				url = "exercise_submit.php?'.$params.'&num="+question_num;
+				url = "'.$urlMainExercise.'exercise_submit.php?'.$params.'&num="+question_num;
 				window.location = url;
 			}
 
             function previous_question_and_save(previous_question_id, question_id_to_save) {
-                url = "exercise_submit.php?'.$params.'&num="+previous_question_id;
+                url = "'.$urlMainExercise.'exercise_submit.php?'.$params.'&num="+previous_question_id;
                 //Save the current question
                 save_now(question_id_to_save, url);
             }
@@ -1036,11 +1086,11 @@ if (!empty($error)) {
                 });
                 var url = "";
                 if ('.$reminder.' == 1 ) {
-                    url = "exercise_reminder.php?'.$params.'&num='.$current_question.'";
+                    url = "'.$urlMainExercise.'exercise_reminder.php?'.$params.'&num='.$current_question.'";
                 } else if ('.$reminder.' == 2 ) {
-                    url = "exercise_submit.php?'.$params.'&num='.$current_question.'&remind_question_id='.$remind_question_id.'&reminder=2";
+                    url = "'.$urlMainExercise.'exercise_submit.php?'.$params.'&num='.$current_question.'&remind_question_id='.$remind_question_id.'&reminder=2";
                 } else {
-                    url = "exercise_submit.php?'.$params.'&num='.$current_question.'&remind_question_id='.$remind_question_id.'";
+                    url = "'.$urlMainExercise.'exercise_submit.php?'.$params.'&num='.$current_question.'&remind_question_id='.$remind_question_id.'";
                 }
                 //$("#save_for_now_"+question_id).html("'.addslashes(Display::return_icon('save.png', get_lang('Saved'), array(), ICON_SIZE_SMALL)).'");
                 window.location = url;
@@ -1093,11 +1143,11 @@ if (!empty($error)) {
 
                             var url = "";
                             if ('.$reminder.' == 1 ) {
-                                url = "exercise_reminder.php?'.$params.'&num='.$current_question.'";
+                                url = "'.$urlMainExercise.'exercise_reminder.php?'.$params.'&num='.$current_question.'";
                             } else if ('.$reminder.' == 2 ) {
-                                url = "exercise_submit.php?'.$params.'&num='.$current_question.'&remind_question_id='.$remind_question_id.'&reminder=2";
+                                url = "'.$urlMainExercise.'exercise_submit.php?'.$params.'&num='.$current_question.'&remind_question_id='.$remind_question_id.'&reminder=2";
                             } else {
-                                url = "exercise_submit.php?'.$params.'&num='.$current_question.'&remind_question_id='.$remind_question_id.'";
+                                url = "'.$urlMainExercise.'exercise_submit.php?'.$params.'&num='.$current_question.'&remind_question_id='.$remind_question_id.'";
                             }
 
                             if (url_extra) {
@@ -1188,7 +1238,7 @@ if (!empty($error)) {
         $remind_list = explode(',', $exercise_stat_info['questions_to_check']);
     }
 
-    echo '<form id="exercise_form" method="post" action="'.api_get_self().'?'.api_get_cidreq().'&autocomplete=off&gradebook='.$gradebook."&exerciseId=".$exerciseId .'" name="frm_exercise" '.$onsubmit.'>
+    echo '<form id="exercise_form" method="post" action="'.api_get_path(WEB_PUBLIC_PATH).'main/exercice/exercise_submit.php?'.api_get_cidreq().'&autocomplete=off&gradebook='.$gradebook."&exerciseId=".$exerciseId .'" name="frm_exercise" '.$onsubmit.'>
      <input type="hidden" name="formSent"				value="1" />
      <input type="hidden" name="exerciseId" 			value="'.$exerciseId . '" />
      <input type="hidden" name="num" 					value="'.$current_question.'" id="num_current_id" />

+ 6 - 6
main/exercice/exercise_submit_modal.php

@@ -28,6 +28,8 @@ if (empty ($exerciseResult)) {
     $exerciseResult = $_SESSION['exerciseResult'];
 }
 
+$urlMainExercise = api_get_path(WEB_CODE_PATH).'exercice/';
+
 if (empty($exerciseResultCoordinates)) {
     $exerciseResultCoordinates = $_REQUEST['exerciseResultCoordinates'];
 }
@@ -108,7 +110,7 @@ if (empty($choice_value)) {
 	";
 	// IMPORTANT
 	//this is the real redirect function
-	echo 'window.location.href = "exercise_submit_modal.php?learnpath_id='.$learnpath_id.'&learnpath_item_id='.$learnpath_item_id.'&hotspotcoord="+ hotspotcoord + "&hotspot="+ hotspot + "&choice="+ choice_js + "&exerciseId='.$exerciseId.'&num='.$questionNum.'&exerciseType='.$exerciseType.'&origin='.$origin.'&gradebook='.$gradebook.'";</script>';
+	echo 'window.location.href = "'.$urlMainExercise.'exercise_submit_modal.php?learnpath_id='.$learnpath_id.'&learnpath_item_id='.$learnpath_item_id.'&hotspotcoord="+ hotspotcoord + "&hotspot="+ hotspot + "&choice="+ choice_js + "&exerciseId='.$exerciseId.'&num='.$questionNum.'&exerciseType='.$exerciseType.'&origin='.$origin.'&gradebook='.$gradebook.'";</script>';
 }
 
 $choice = array();
@@ -514,16 +516,14 @@ if ($destinationid==-1) {
 		$links.= Display :: return_icon('quiz.gif', '', array ('style' => 'padding-left:0px;padding-right:5px;')).'<a onclick="SendEx('.$num_value_array[0].');" href="#">'.get_lang('GoToQuestion').' '.$num_value_array[0].'</a><br /><br />';
 	}
 }
-
 echo '<script>
 		function SendEx(num) {
-
 		  	if (num == -1) {
-		  		self.parent.window.location.href = "exercise_result.php?take_session=1&exerciseId='.$exerciseId.'&num="+num+"&exerciseType='.$exerciseType.'&origin='.$origin.'&learnpath_item_id='.$learnpath_item_id.'&learnpath_id='.$learnpath_id.'";
+		  		self.parent.window.location.href = "'.$urlMainExercise.'exercise_result.php?take_session=1&exerciseId='.$exerciseId.'&num="+num+"&exerciseType='.$exerciseType.'&origin='.$origin.'&learnpath_item_id='.$learnpath_item_id.'&learnpath_id='.$learnpath_id.'";
 		   		self.parent.tb_remove();
 		  	} else {
                 num -= 1;
-		  		self.parent.window.location.href = "exercise_submit.php?tryagain=1&exerciseId='.$exerciseId.'&num="+num+"&exerciseType='.$exerciseType.'&origin='.$origin.'&learnpath_item_id='.$learnpath_item_id.'&learnpath_id='.$learnpath_id.'";
+		  		self.parent.window.location.href = "'.$urlMainExercise.'exercise_submit.php?tryagain=1&exerciseId='.$exerciseId.'&num="+num+"&exerciseType='.$exerciseType.'&origin='.$origin.'&learnpath_item_id='.$learnpath_item_id.'&learnpath_id='.$learnpath_id.'";
 		   		self.parent.tb_remove();
 		  	}
 		}
@@ -567,7 +567,7 @@ if ($links!='') {
 } else {
 	$questionNum++;
 	echo '<script>
-			self.parent.window.location.href = "exercise_submit.php?exerciseId='.$exerciseId.'&num='.$questionNum.'&exerciseType='.$exerciseType.'&origin='.$origin.'";
+			self.parent.window.location.href = "'.$urlMainExercise.'exercise_submit.php?exerciseId='.$exerciseId.'&num='.$questionNum.'&exerciseType='.$exerciseType.'&origin='.$origin.'";
    			//self.parent.tb_remove();
  	 	</script>';
 }

+ 1 - 1
main/exercice/hotpotatoes.php

@@ -113,7 +113,7 @@ if ((api_is_allowed_to_edit(null, true)) && (($finish == 0) || ($finish == 2)))
 
             if ($finish == 0) {
                 // Generate new test folder if on first step of file upload.
-                $filename = replace_dangerous_char(trim($_FILES['userFile']['name']), 'strict');
+                $filename = api_replace_dangerous_char(trim($_FILES['userFile']['name']), 'strict');
                 $fld = GenerateHpFolder($document_sys_path.$uploadPath.'/');
 
                 //$doc_id = FileManager::add_document($_course, '/HotPotatoes_files/'.$fld, 'folder', 0, $fld);

+ 1 - 1
main/exercice/hotpotatoes_exercise_report.php

@@ -14,7 +14,7 @@ $language_file = array('exercice');
 
 // including the global library
 require_once '../inc/global.inc.php';
-require_once '../gradebook/lib/be.inc.php';
+require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/be.inc.php';
 
 // Setting the tabs
 $this_section = SECTION_COURSES;

+ 1 - 1
main/exercice/hotspot_admin.inc.php

@@ -66,7 +66,7 @@ if ($modifyIn) {
     unset($buttonBack);
 }
 
-$hotspot_admin_url = api_get_path(WEB_CODE_PATH) . 'exercice/admin.php?' . api_get_cidreq() . '&exerciseId=' . $exerciseId;
+$hotspot_admin_url = api_get_path(WEB_CODE_PATH).'exercice/admin.php?'.api_get_cidreq().'&exerciseId='.$exerciseId;
 
 // the answer form has been submitted
 if ($submitAnswers || $buttonBack) {

+ 2 - 2
main/exercice/live_stats.php

@@ -23,7 +23,7 @@ if (!$result) {
 	api_not_allowed(true);
 }
 
-$interbreadcrumb[] = array ("url" => "exercice.php?gradebook=$gradebook", "name" => get_lang('Exercices'));
+$interbreadcrumb[] = array ("url" => "exercice.php", "name" => get_lang('Exercices'));
 $interbreadcrumb[] = array ("url" => "admin.php?exerciseId=$exercise_id","name" => $objExercise->name);
 
 //Add the JS needed to use the jqgrid
@@ -72,7 +72,7 @@ function refreshGrid() {
 
 $(function() {
     <?php
-        echo Display::grid_js('live_stats',  $url, $columns, $column_model, $extra_params, array(), $action_links,true);
+        echo Display::grid_js('live_stats',  $url, $columns, $column_model, $extra_params, array(), null, true);
     ?>
     refreshGrid();
 });

+ 5 - 2
main/exercice/overview.php

@@ -15,11 +15,13 @@ use \ChamiloSession as Session;
 $language_file = 'exercice';
 require_once 'exercise.class.php';
 require_once '../inc/global.inc.php';
+
 $current_course_tool  = TOOL_QUIZ;
 
 // Clear the exercise session just in case
-if (isset ($_SESSION['objExercise'])) {
-	Session::erase('objExercise');
+$objExercise = Session::read('objExercise');
+if (isset($objExercise)) {
+    Session::erase('objExercise');
 }
 
 $this_section = SECTION_COURSES;
@@ -99,6 +101,7 @@ if (isset($exercise_stat_info['exe_id'])) {
 
 //1. Check if this is a new attempt or a previous
 $label = get_lang('StartTest');
+
 if ($time_control && !empty($clock_expired_time) || !empty($attempt_list)) {
 	$label = get_lang('ContinueTest');
 }

+ 8 - 5
main/exercice/question_admin.inc.php

@@ -12,15 +12,18 @@
  */
 
 $course_id = api_get_course_int_id();
+
+$urlMainExercise = api_get_path(WEB_CODE_PATH).'exercice/';
+
 // INIT QUESTION
 if (isset($_GET['editQuestion'])) {
     $objQuestion = Question::read($_GET['editQuestion'], null, $objExercise);
     $action      = api_get_self()."?".api_get_cidreq(
-    )."&myid=1&modifyQuestion=".$modifyQuestion."&editQuestion=".$objQuestion->id."&exerciseId=$exerciseId";
+    )."&myid=1&modifyQuestion=".$modifyQuestion."&editQuestion=".$objQuestion->id."&exerciseId=$objExercise->id";
 } else {
     $objQuestion = Question::getInstance($_REQUEST['answerType'], $objExercise);
     $action      = api_get_self()."?".api_get_cidreq(
-    )."&modifyQuestion=".$modifyQuestion."&newQuestion=".$newQuestion."&exerciseId=$exerciseId";
+    )."&modifyQuestion=".$modifyQuestion."&newQuestion=".$newQuestion."&exerciseId=$objExercise->id";
 }
 
 /** @var Question $objQuestion */
@@ -129,13 +132,13 @@ if (is_object($objQuestion)) {
             // 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.'&'.api_get_cidreq().'&message=ItemUpdated"</script>';
+                    echo '<script type="text/javascript">window.location.href="'.$urlMainExercise.'admin.php?exerciseId='.$exerciseId.'&'.api_get_cidreq().'&message=ItemUpdated"</script>';
                 } else {
                     //New question
-                    echo '<script type="text/javascript">window.location.href="admin.php?exerciseId='.$exerciseId.'&'.api_get_cidreq().'&message=ItemAdded"</script>';
+                    echo '<script type="text/javascript">window.location.href="'.$urlMainExercise.'admin.php?exerciseId='.$exerciseId.'&'.api_get_cidreq().'&message=ItemAdded"</script>';
                 }
             } else {
-                echo '<script type="text/javascript">window.location.href="admin.php?exerciseId='.$exerciseId.'&hotspotadmin='.$objQuestion->id.'&'.api_get_cidreq().'"</script>';
+                echo '<script type="text/javascript">window.location.href="'.$urlMainExercise.'admin.php?exerciseId='.$exerciseId.'&hotspotadmin='.$objQuestion->id.'&'.api_get_cidreq().'"</script>';
             }
         } else {
             echo $message;

+ 2 - 2
main/exercice/showinframes.php

@@ -28,7 +28,7 @@ FileManager::my_delete($full_file_path.$user_id.'.t.html');
 $content = ReadFileCont($full_file_path.$user_id.'.t.html');
 
 if ($content == '') {
-    $url = api_get_path(WEB_PATH)."main/exercice/savescores.php?origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&time=".Security::remove_XSS($time)."&test=".$doc_url."&uid=".$user_id."&cid=".$cid."&score='+Score";
+    $url = api_get_path(WEB_CODE_PATH)."exercice/savescores.php?origin=$origin&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&time=".Security::remove_XSS($time)."&test=".$doc_url."&uid=".$user_id."&cid=".$cid."&score='+Score";
 
     $content = ReadFileCont($full_file_path);
     $mit = "function Finish(){";
@@ -107,4 +107,4 @@ $url = $document_web_path.$doc_url.$user_id.'.t.html?time='.Security::remove_XSS
 echo '<iframe style="overflow:hidden" id="hotpotatoe" width="100%" frameborder="0" src="'.$url.'"></iframe>';
 echo '</body></html>';
 Display::display_footer();
-exit;
+exit;

+ 3 - 3
main/exercice/stats.php

@@ -26,7 +26,7 @@ if (empty($session_id)) {
 }
 $count_students = count($students);
 
-$question_list = $objExercise->selectQuestionList();
+$question_list = $objExercise->getQuestionList();
 
 $data = array();
 //Question title 	# of students who tool it 	Lowest score 	Average 	Highest score 	Maximum score
@@ -100,7 +100,7 @@ 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_int_id(), api_get_session_id());
+		$exercise_stats = ExerciseLib::get_student_stats_by_question($question_id, $exercise_id, api_get_course_int_id(), api_get_session_id());
 
         $answer = new Answer($question_id);
 		$answer_count = $answer->selectNbrAnswers();
@@ -114,7 +114,7 @@ if (!empty($question_list)) {
             //$data[$id]['name'] .=$answer_count;
             //Overwriting values depending of the question
             switch ($question_obj->type) {
-                case FILL_IN_BLANKS :
+                case FILL_IN_BLANKS:
                     $answer_info_db = $answer_info;
                     $answer_info = substr($answer_info, 0, strpos($answer_info, '::'));
                     $correct_answer = $is_correct;

+ 2 - 2
main/exercice/testcategory.class.php

@@ -1038,10 +1038,10 @@ class Testcategory
     }
 
     /**
-     * @param $exercise_obj
+     * @param Exercise $exercise_obj
      * @return string
      */
-    public function return_category_form($exercise_obj)
+    public function return_category_form(Exercise $exercise_obj)
     {
         $categories = $this->getListOfCategoriesForTest($exercise_obj);
 

+ 2 - 3
main/exercice/upload_exercise.php

@@ -302,15 +302,14 @@ function lp_upload_quiz_action_handling()
             $_SESSION['oLP']->add_item($parent, $previous, TOOL_QUIZ, $quiz_id, ($quiz_title), '');
             // Redirect to home page for add more content
             header(
-                'location: ../newscorm/lp_controller.php?'.api_get_cidreq(
+                'Location: '.api_get_path(WEB_CODE_PATH).'newscorm/lp_controller.php?'.api_get_cidreq(
                 ).'&action=add_item&type=step&lp_id='.Security::remove_XSS(
                     $_GET['lp_id']
                 ).'&session_id='.api_get_session_id()
             );
             exit;
         } else {
-            //  header('location: exercice.php?' . api_get_cidreq());
-            echo '<script>window.location.href = "admin.php?'.api_get_cidReq(
+            echo '<script>window.location.href = "'.api_get_path(WEB_CODE_PATH).'exercice/admin.php?'.api_get_cidReq(
             ).'&exerciseId='.$quiz_id.'&session_id='.api_get_session_id().'"</script>';
         }
     }

+ 5 - 5
main/forum/editpost.php

@@ -28,11 +28,11 @@ $language_file = array('forum', 'group', 'gradebook');
 
 // Including the global initialization file.
 require_once '../inc/global.inc.php';
-require_once '../gradebook/lib/gradebook_functions.inc.php';
-require_once '../gradebook/lib/be/gradebookitem.class.php';
-require_once '../gradebook/lib/be/evaluation.class.php';
-require_once '../gradebook/lib/be/abstractlink.class.php';
-require_once '../gradebook/lib/gradebook_functions.inc.php';
+require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/gradebook_functions.inc.php';
+require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/be/gradebookitem.class.php';
+require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/be/evaluation.class.php';
+require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/be/abstractlink.class.php';
+require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/gradebook_functions.inc.php';
 
 // The section (tabs).
 $this_section = SECTION_COURSES;

+ 2 - 2
main/forum/newthread.php

@@ -30,7 +30,7 @@ $language_file = array('forum', 'document', 'gradebook');
 
 // Including the global initialization file.
 require_once '../inc/global.inc.php';
-require_once '../gradebook/lib/gradebook_functions.inc.php';
+require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/gradebook_functions.inc.php';
 
 // The section (tabs).
 $this_section = SECTION_COURSES;
@@ -171,4 +171,4 @@ if (!empty($values) && isset($values['SubmitPost'])) {
 
 if ($origin != 'learnpath') {
     Display :: display_footer();
-}
+}

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

@@ -287,7 +287,6 @@ abstract class AbstractLink implements GradebookItem {
 		} else {
 			$name_log=$arreval['course_code'];
 		}
-		//error_log($name_log);
 		$sql="INSERT INTO ".$tbl_grade_linkeval_log."(id_linkeval_log,name,description,created_at,weight,visible,type,user_id_log)
 			  VALUES('".Database::escape_string($arreval['id'])."','".Database::escape_string($name_log)."','".Database::escape_string($description_log)."','".Database::escape_string($current_date_server)."','".Database::escape_string($arreval['weight'])."','".Database::escape_string($arreval['visible'])."','Link',".api_get_user_id().")";
 

+ 1 - 1
main/gradebook/lib/fe/exportgradebook.php

@@ -205,7 +205,7 @@ function export_pdf_attendance($headers_table, $data_table, $headers_pdf, $foote
     } else {
         $mpdf->WriteHTML($html);
     }
-    $mpdf->Output(replace_dangerous_char($title_pdf.'.pdf'), 'D');
+    $mpdf->Output(api_replace_dangerous_char($title_pdf.'.pdf'), 'D');
     exit;
 }
 

+ 60 - 3
main/inc/Entity/Repository/UserRepository.php

@@ -3,14 +3,71 @@
 namespace Entity\Repository;
 
 use Doctrine\ORM\EntityRepository;
+use Symfony\Component\Security\Core\User\UserInterface;
+use Symfony\Component\Security\Core\User\UserProviderInterface;
+use Doctrine\ORM\NoResultException;
+use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
+use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
 
 /**
- * UserRepository
- *
+ * Class UserRepository
+ * @package Entity\Repository
  */
-class UserRepository extends EntityRepository
+class UserRepository extends EntityRepository implements UserProviderInterface
 {
 
+    /**
+     * @param string $username
+     * @return mixed
+     * @throws UsernameNotFoundException
+     */
+    public function loadUserByUsername($username)
+    {
+        $q = $this
+            ->createQueryBuilder('u')
+            ->where('u.username = :username OR u.email = :email')
+            ->setParameter('username', $username)
+            ->setParameter('email', $username)
+            ->getQuery();
+
+        try {
+            $user = $q->getSingleResult();
+            // api_format_user_from_obj($user);
+        } catch (NoResultException $e) {
+            throw new UsernameNotFoundException(
+                sprintf('Unable to find an active admin User identified by "%s".', $username),
+                0,
+                $e
+            );
+        }
+        return $user;
+    }
+
+    /**
+     * @param UserInterface $user
+     * @return \Entity\User
+     * @throws UnsupportedUserException
+     */
+    public function refreshUser(UserInterface $user)
+    {
+        return $user;
+
+        $class = get_class($user);
+        if (!$this->supportsClass($class)) {
+            throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', $class));
+        }
+        return $this->loadUserByUsername($user->getUsername());
+    }
+
+    /**
+     * @param string $class
+     * @return bool
+     */
+    public function supportsClass($class)
+    {
+        return $this->getEntityName() === $class || is_subclass_of($class, $this->getEntityName());
+    }
+
     public function getUsers($limit = null)
     {
         $qb = $this->createQueryBuilder('u')

+ 26 - 1
main/inc/Entity/Role.php

@@ -9,7 +9,7 @@ use Doctrine\ORM\Mapping as ORM;
  * @ORM\Table(name="roles")
  * @ORM\Entity()
  */
-class Role extends SymfonyRole
+class Role extends SymfonyRole implements \Serializable
 {
     /**
      * @ORM\Column(name="id", type="integer")
@@ -95,5 +95,30 @@ class Role extends SymfonyRole
         return $this;
     }
 
+     /**
+     * @see \Serializable::serialize()
+     */
+    public function serialize()
+    {
+        /*
+         * ! Don't serialize $users field !
+         */
+        return \serialize(array(
+            $this->id,
+            $this->role
+        ));
+    }
+
+    /**
+     * @see \Serializable::unserialize()
+     */
+    public function unserialize($serialized)
+    {
+        list(
+            $this->id,
+            $this->role
+        ) = \unserialize($serialized);
+    }
+
 
 }

+ 172 - 29
main/inc/Entity/User.php

@@ -5,14 +5,15 @@ namespace Entity;
 use Doctrine\ORM\Mapping as ORM;
 use Doctrine\Common\Collections\Criteria;
 use Doctrine\Common\Collections\ArrayCollection;
+use Symfony\Component\Security\Core\User\AdvancedUserInterface;
 
 /**
- * EntityUser
+ * User
  *
  * @ORM\Table(name="user")
  * @ORM\Entity(repositoryClass="Entity\Repository\UserRepository")
  */
-class User
+class User implements AdvancedUserInterface, \Serializable
 {
     /**
      * @var integer
@@ -215,12 +216,29 @@ class User
      **/
     private $items;
 
-
     /**
      * @ORM\OneToMany(targetEntity="UsergroupRelUser", mappedBy="user")
      **/
     private $classes;
 
+    /**
+     * @var ArrayCollection
+     * @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
+     * @ORM\JoinTable(
+     *          name="users_roles",
+     *          joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="user_id")},
+     *          inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id")}
+     *      )
+     */
+    private $roles;
+
+     /**
+     * @ORM\Column(type="string", length=255)
+     */
+    private $salt;
+
+    private $isActive;
+
     /**
      *
      */
@@ -229,6 +247,131 @@ class User
         $this->courses = new ArrayCollection();
         $this->items = new ArrayCollection();
         $this->classes = new ArrayCollection();
+        $this->roles = new ArrayCollection();
+        $this->salt = sha1(uniqid(null, true));
+        $this->isActive = true;
+    }
+
+    public function getIsActive()
+    {
+        return $this->active == 1;
+    }
+
+
+    /**
+     * @inheritDoc
+     */
+    public function isAccountNonExpired()
+    {
+        return true;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function isAccountNonLocked()
+    {
+        return true;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function isCredentialsNonExpired()
+    {
+        return true;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function isEnabled()
+    {
+        return $this->getActive() == 1;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function eraseCredentials()
+    {
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getRoles()
+    {
+        return $this->roles->toArray();
+    }
+
+    /**
+     * @see https://github.com/symfony/symfony/issues/3691
+     * @see \Serializable::serialize()
+     */
+    public function serialize()
+    {
+        /*
+         * ! Don't serialize $roles field !
+         */
+        return \serialize(array(
+            $this->userId,
+            $this->username,
+            $this->email,
+            $this->salt,
+            $this->password,
+            $this->isActive
+        ));
+    }
+
+    /**
+     * @see \Serializable::unserialize()
+     */
+    public function unserialize($serialized)
+    {
+        list (
+            $this->userId,
+            $this->username,
+            $this->email,
+            $this->salt,
+            $this->password,
+            $this->isActive
+        ) = \unserialize($serialized);
+    }
+
+    /**
+     *
+     * @return ArrayCollection
+     */
+    public function getRolesObj()
+    {
+        return $this->roles;
+    }
+
+
+
+    /**
+     * Set salt
+     *
+     * @param string $salt
+     *
+     * @return User
+     */
+    public function setSalt($salt)
+    {
+        $this->salt = $salt;
+
+        return $this;
+    }
+
+    /**
+     * Get salt
+     *
+     * @return string
+     */
+    public function getSalt()
+    {
+        return $this->salt;
     }
 
     /**
@@ -300,7 +443,7 @@ class User
      *
      * @param string $lastname
      *
-     * @return EntityUser
+     * @return User
      */
     public function setLastname($lastname)
     {
@@ -324,7 +467,7 @@ class User
      *
      * @param string $firstname
      *
-     * @return EntityUser
+     * @return User
      */
     public function setFirstname($firstname)
     {
@@ -347,7 +490,7 @@ class User
      * Set username
      *
      * @param string $username
-     * @return EntityUser
+     * @return User
      */
     public function setUsername($username)
     {
@@ -370,7 +513,7 @@ class User
      * Set password
      *
      * @param string $password
-     * @return EntityUser
+     * @return User
      */
     public function setPassword($password)
     {
@@ -393,7 +536,7 @@ class User
      * Set authSource
      *
      * @param string $authSource
-     * @return EntityUser
+     * @return User
      */
     public function setAuthSource($authSource)
     {
@@ -416,7 +559,7 @@ class User
      * Set email
      *
      * @param string $email
-     * @return EntityUser
+     * @return User
      */
     public function setEmail($email)
     {
@@ -439,7 +582,7 @@ class User
      * Set status
      *
      * @param boolean $status
-     * @return EntityUser
+     * @return User
      */
     public function setStatus($status)
     {
@@ -462,7 +605,7 @@ class User
      * Set officialCode
      *
      * @param string $officialCode
-     * @return EntityUser
+     * @return User
      */
     public function setOfficialCode($officialCode)
     {
@@ -485,7 +628,7 @@ class User
      * Set phone
      *
      * @param string $phone
-     * @return EntityUser
+     * @return User
      */
     public function setPhone($phone)
     {
@@ -508,7 +651,7 @@ class User
      * Set pictureUri
      *
      * @param string $pictureUri
-     * @return EntityUser
+     * @return User
      */
     public function setPictureUri($pictureUri)
     {
@@ -531,7 +674,7 @@ class User
      * Set creatorId
      *
      * @param integer $creatorId
-     * @return EntityUser
+     * @return User
      */
     public function setCreatorId($creatorId)
     {
@@ -554,7 +697,7 @@ class User
      * Set competences
      *
      * @param string $competences
-     * @return EntityUser
+     * @return User
      */
     public function setCompetences($competences)
     {
@@ -577,7 +720,7 @@ class User
      * Set diplomas
      *
      * @param string $diplomas
-     * @return EntityUser
+     * @return User
      */
     public function setDiplomas($diplomas)
     {
@@ -600,7 +743,7 @@ class User
      * Set openarea
      *
      * @param string $openarea
-     * @return EntityUser
+     * @return User
      */
     public function setOpenarea($openarea)
     {
@@ -623,7 +766,7 @@ class User
      * Set teach
      *
      * @param string $teach
-     * @return EntityUser
+     * @return User
      */
     public function setTeach($teach)
     {
@@ -646,7 +789,7 @@ class User
      * Set productions
      *
      * @param string $productions
-     * @return EntityUser
+     * @return User
      */
     public function setProductions($productions)
     {
@@ -669,7 +812,7 @@ class User
      * Set chatcallUserId
      *
      * @param integer $chatcallUserId
-     * @return EntityUser
+     * @return User
      */
     public function setChatcallUserId($chatcallUserId)
     {
@@ -692,7 +835,7 @@ class User
      * Set chatcallDate
      *
      * @param \DateTime $chatcallDate
-     * @return EntityUser
+     * @return User
      */
     public function setChatcallDate($chatcallDate)
     {
@@ -715,7 +858,7 @@ class User
      * Set chatcallText
      *
      * @param string $chatcallText
-     * @return EntityUser
+     * @return User
      */
     public function setChatcallText($chatcallText)
     {
@@ -738,7 +881,7 @@ class User
      * Set language
      *
      * @param string $language
-     * @return EntityUser
+     * @return User
      */
     public function setLanguage($language)
     {
@@ -761,7 +904,7 @@ class User
      * Set registrationDate
      *
      * @param \DateTime $registrationDate
-     * @return EntityUser
+     * @return User
      */
     public function setRegistrationDate($registrationDate)
     {
@@ -784,7 +927,7 @@ class User
      * Set expirationDate
      *
      * @param \DateTime $expirationDate
-     * @return EntityUser
+     * @return User
      */
     public function setExpirationDate($expirationDate)
     {
@@ -807,7 +950,7 @@ class User
      * Set active
      *
      * @param boolean $active
-     * @return EntityUser
+     * @return User
      */
     public function setActive($active)
     {
@@ -830,7 +973,7 @@ class User
      * Set openid
      *
      * @param string $openid
-     * @return EntityUser
+     * @return User
      */
     public function setOpenid($openid)
     {
@@ -853,7 +996,7 @@ class User
      * Set theme
      *
      * @param string $theme
-     * @return EntityUser
+     * @return User
      */
     public function setTheme($theme)
     {
@@ -876,7 +1019,7 @@ class User
      * Set hrDeptId
      *
      * @param integer $hrDeptId
-     * @return EntityUser
+     * @return User
      */
     public function setHrDeptId($hrDeptId)
     {

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

@@ -3,19 +3,15 @@
 /**
  * Responses to AJAX calls
  */
-$type = isset($_REQUEST['type']) && in_array($_REQUEST['type'], array('personal', 'course', 'admin')) ? $_REQUEST['type'] : 'personal';
+$type = isset($_GET['type']) && in_array($_GET['type'], array('personal', 'course', 'admin')) ? $_GET['type'] : 'personal';
 
 if ($type == 'personal') {
     $cidReset = true; // fixes #5162
 }
-
-require_once '../global.inc.php';
-
 require_once api_get_path(SYS_CODE_PATH).'calendar/agenda.inc.php';
 require_once api_get_path(SYS_CODE_PATH).'calendar/myagenda.inc.php';
-require_once api_get_path(SYS_CODE_PATH).'calendar/agenda.lib.php';
 
-$action = isset($_REQUEST['a']) ? $_REQUEST['a'] : null;
+$action = isset($_GET['a']) ? $_GET['a'] : null;
 
 if ($type == 'course') {
     api_protect_course_script(true);
@@ -81,7 +77,7 @@ switch ($action) {
             $uid = intval($user_id);
         }
         */
-        $events = $agenda->get_events($_REQUEST['start'], $_REQUEST['end'], api_get_course_int_id(), $group_id, $user_id);
+        $events = $agenda->get_events($_GET['start'], $_GET['end'], api_get_course_int_id(), $group_id, $user_id);
         echo $events;
         break;
     case 'get_user_agenda':

+ 20 - 22
main/inc/ajax/chat.ajax.php

@@ -6,9 +6,7 @@
 
 $_dont_save_user_course_access  = true;
 
-require_once '../global.inc.php';
-
-$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : null;
+$action = isset($_GET['action']) ? $_GET['action'] : null;
 
 if (api_is_anonymous()) {
 	exit;
@@ -18,8 +16,8 @@ if (api_get_setting('allow_global_chat') == 'false') {
 	exit;
 }
 
-$to_user_id = isset($_REQUEST['to']) ? $_REQUEST['to'] : null;
-$message	= isset($_REQUEST['message']) ? $_REQUEST['message'] : null;
+$to_user_id = isset($_GET['to']) ? $_GET['to'] : null;
+$message	= isset($_GET['message']) ? $_GET['message'] : null;
 
 if (!isset($_SESSION['chatHistory'])) {
 	$_SESSION['chatHistory'] = array();
@@ -31,29 +29,29 @@ if (!isset($_SESSION['openChatBoxes'])) {
 
 $chat = new Chat();
 if ($chat->is_chat_blocked_by_exercises()) {
-    //Desconnecting the user
+    // Disconnect the user
     $chat->set_user_status(0);
     exit;
 }
 
 switch ($action) {
-	case 'chatheartbeat':
-		$chat->heartbeat();
-		break;
-	case 'closechat':
-		$chat->close();
-		break;
-	case 'sendchat':
-		$chat->send(api_get_user_id(), $to_user_id, $message);
-		break;
-	case 'startchatsession':
-		$chat->start_session();
-		break;
+    case 'chatheartbeat':
+        $chat->heartbeat();
+        break;
+    case 'closechat':
+        $chat->close();
+        break;
+    case 'sendchat':
+        $chat->send(api_get_user_id(), $to_user_id, $message);
+        break;
+    case 'startchatsession':
+        $chat->start_session();
+        break;
     case 'set_status':
         $status = isset($_REQUEST['status']) ? intval($_REQUEST['status']) : 0;
-		$chat->set_user_status($status);
-		break;
-	default:
+        $chat->set_user_status($status);
+        break;
+    default:
         echo '';
 }
-exit;
+exit;

+ 20 - 7
main/inc/ajax/exercise.ajax.php

@@ -4,10 +4,10 @@
  * Responses to AJAX calls
  */
 
-require_once '../../exercice/exercise.class.php';
-require_once '../../exercice/question.class.php';
-require_once '../../exercice/answer.class.php';
-require_once '../global.inc.php';
+require_once api_get_path(SYS_CODE_PATH).'exercice/exercise.class.php';
+require_once api_get_path(SYS_CODE_PATH).'exercice/question.class.php';
+require_once api_get_path(SYS_CODE_PATH).'exercice/answer.class.php';
+
 // @todo: Is this really needed? see 33cd962f077ed8c2e4b696bdd18b54db00890ef2
 require_once api_get_path(LIBRARY_PATH).'transaction.lib.php';
 
@@ -516,8 +516,16 @@ switch ($action) {
 
                 $key = ExerciseLib::get_time_control_key($exercise_id, $exercise_stat_info['orig_lp_id'], $exercise_stat_info['orig_lp_item_id']);
 
-                if (isset($_SESSION['duration_time'][$key]) && !empty($_SESSION['duration_time'][$key])) {
-                    $duration = $now - $_SESSION['duration_time'][$key];
+                /*$durationTime = array(
+                    'duration_time' => array(
+                        $key => time()
+                    )
+                );*/
+
+                $durationTime = Session::read('duration_time');
+
+                if (isset($durationTime[$key]) && !empty($durationTime[$key])) {
+                    $duration = $now - $durationTime[$key];
 
                     if (!empty($exercise_stat_info['exe_duration'])) {
                         $duration += $exercise_stat_info['exe_duration'];
@@ -529,7 +537,12 @@ switch ($action) {
                     }
                 }
 
-                $_SESSION['duration_time'][$key] = time();
+                $durationTime = array(
+                    $key => time()
+                );
+
+                Session::write('duration_time', $durationTime);
+                // $_SESSION['duration_time'][$key] = time();
 
                 update_event_exercise(
                     $exe_id,

+ 0 - 178
main/inc/entity/access_url.class.php

@@ -1,178 +0,0 @@
-<?php
-
-namespace Entity;
-
-use Doctrine\ORM\Mapping as ORM;
-
-/**
- *
- * @license see /license.txt
- * @author autogenerated
- */
-class AccessUrl extends \Entity
-{
-    /**
-     * @return \Entity\Repository\AccessUrlRepository
-     */
-     public static function repository(){
-        return \Entity\Repository\AccessUrlRepository::instance();
-    }
-
-    /**
-     * @return \Entity\AccessUrl
-     */
-     public static function create(){
-        return new self();
-    }
-
-    /**
-     * @var integer $id
-     */
-    protected $id;
-
-    /**
-     * @var string $url
-     */
-    protected $url;
-
-    /**
-     * @var text $description
-     */
-    protected $description;
-
-    /**
-     * @var integer $active
-     */
-    protected $active;
-
-    /**
-     * @var integer $created_by
-     */
-    protected $created_by;
-
-    /**
-     * @var datetime $tms
-     */
-    protected $tms;
-
-
-    /**
-     * Get id
-     *
-     * @return integer 
-     */
-    public function get_id()
-    {
-        return $this->id;
-    }
-
-    /**
-     * Set url
-     *
-     * @param string $value
-     * @return AccessUrl
-     */
-    public function set_url($value)
-    {
-        $this->url = $value;
-        return $this;
-    }
-
-    /**
-     * Get url
-     *
-     * @return string 
-     */
-    public function get_url()
-    {
-        return $this->url;
-    }
-
-    /**
-     * Set description
-     *
-     * @param text $value
-     * @return AccessUrl
-     */
-    public function set_description($value)
-    {
-        $this->description = $value;
-        return $this;
-    }
-
-    /**
-     * Get description
-     *
-     * @return text 
-     */
-    public function get_description()
-    {
-        return $this->description;
-    }
-
-    /**
-     * Set active
-     *
-     * @param integer $value
-     * @return AccessUrl
-     */
-    public function set_active($value)
-    {
-        $this->active = $value;
-        return $this;
-    }
-
-    /**
-     * Get active
-     *
-     * @return integer 
-     */
-    public function get_active()
-    {
-        return $this->active;
-    }
-
-    /**
-     * Set created_by
-     *
-     * @param integer $value
-     * @return AccessUrl
-     */
-    public function set_created_by($value)
-    {
-        $this->created_by = $value;
-        return $this;
-    }
-
-    /**
-     * Get created_by
-     *
-     * @return integer 
-     */
-    public function get_created_by()
-    {
-        return $this->created_by;
-    }
-
-    /**
-     * Set tms
-     *
-     * @param datetime $value
-     * @return AccessUrl
-     */
-    public function set_tms($value)
-    {
-        $this->tms = $value;
-        return $this;
-    }
-
-    /**
-     * Get tms
-     *
-     * @return datetime 
-     */
-    public function get_tms()
-    {
-        return $this->tms;
-    }
-}

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