Browse Source

Merge pull request #1130 from aragonc/ofaj

fix menu array template BT#10657
Yannick Warnier 8 years ago
parent
commit
e13302fd02
46 changed files with 583 additions and 316 deletions
  1. 14 4
      app/Migrations/Schema/V110/Version110.php
  2. 2 0
      app/Migrations/Schema/V110/Version20150603181728.php
  3. 3 0
      app/Migrations/Schema/V111/Version111.php
  4. 19 11
      app/Resources/public/css/themes/rainbow/default.css
  5. BIN
      app/Resources/public/css/themes/rainbow/images/bg.png
  6. BIN
      app/Resources/public/css/themes/rainbow/images/scorm_current.png
  7. 30 8
      app/Resources/public/css/themes/rainbow/learnpath.css
  8. 2 2
      custompages/index-unlogged-dist.php
  9. 2 2
      documentation/changelog.html
  10. 2 2
      documentation/credits.html
  11. 2 2
      documentation/dependencies.html
  12. 2 2
      documentation/index.html
  13. 2 2
      documentation/installation_guide.html
  14. 2 2
      documentation/installation_guide_es_ES.html
  15. 2 2
      documentation/installation_guide_fr_FR.html
  16. 2 2
      documentation/license.html
  17. 2 2
      documentation/migration-checklist.html
  18. 5 5
      documentation/optimization.html
  19. 2 2
      documentation/readme.html
  20. 1 2
      main/create_course/add_course.php
  21. 5 8
      main/exercice/fill_blanks.class.php
  22. 26 12
      main/exercice/question.class.php
  23. 34 31
      main/forum/forumfunction.inc.php
  24. 6 1
      main/forum/newthread.php
  25. 39 27
      main/forum/viewthread_flat.inc.php
  26. 39 25
      main/forum/viewthread_nested.inc.php
  27. 143 0
      main/inc/lib/banner.lib.php
  28. 7 8
      main/inc/lib/course.lib.php
  29. 2 1
      main/inc/lib/message.lib.php
  30. 1 1
      main/inc/lib/template.lib.php
  31. 17 18
      main/inc/lib/tracking.lib.php
  32. 9 19
      main/inc/lib/userportal.lib.php
  33. 31 26
      main/newscorm/learnpath.class.php
  34. 1 1
      main/newscorm/lp_view.php
  35. 5 4
      main/template/default/auth/courses_categories.php
  36. 2 2
      main/template/default/layout/login_form.tpl
  37. 16 0
      main/template/default/learnpath/view.tpl
  38. 3 5
      main/template/rainbow/layout/layout_2_col.tpl
  39. 23 13
      main/template/rainbow/layout/menu.tpl
  40. 2 7
      main/template/rainbow/layout/show_header.tpl
  41. 16 0
      main/template/rainbow/learnpath/view.tpl
  42. 16 11
      main/webservices/cm_webservice_forum.php
  43. 3 2
      src/Chamilo/CoreBundle/Menu/NavBuilder.php
  44. 1 1
      src/Chamilo/PageBundle/Resources/views/latest.html.twig
  45. 17 39
      src/Chamilo/ThemeBundle/Resources/views/Layout/base-layout.html.twig
  46. 23 2
      tests/features/forum.feature

+ 14 - 4
app/Migrations/Schema/V110/Version110.php

@@ -34,6 +34,7 @@ class Version110 extends AbstractMigrationChamilo
     public function up(Schema $schema)
     {
         // Use $schema->createTable
+        $this->addSql('set sql_mode=""');
 
         $this->addSql("CREATE TABLE IF NOT EXISTS course_field_options (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, field_id INT NOT NULL, option_value TEXT, option_display_text VARCHAR(64), option_order INT, tms DATETIME)");
         $this->addSql("CREATE TABLE IF NOT EXISTS session_field_options (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, field_id INT NOT NULL, option_value TEXT, option_display_text VARCHAR(64), option_order INT, tms DATETIME)");
@@ -49,8 +50,17 @@ class Version110 extends AbstractMigrationChamilo
         $this->addSql("ALTER TABLE skill_rel_user MODIFY COLUMN acquired_skill_at datetime default NULL");
         $this->addSql("ALTER TABLE track_e_access MODIFY COLUMN access_date datetime DEFAULT NULL");
         $this->addSql("ALTER TABLE track_e_lastaccess MODIFY COLUMN access_date datetime DEFAULT NULL");
-        $this->addSql("ALTER TABLE skill_rel_user ADD COLUMN course_id INT NOT NULL DEFAULT 0 AFTER id");
-        $this->addSql("ALTER TABLE skill_rel_user ADD COLUMN session_id INT NOT NULL DEFAULT 0 AFTER course_id");
+
+        $table = $schema->getTable('skill_rel_user');
+
+        if (!$table->hasColumn('course_id')) {
+            $this->addSql("ALTER TABLE skill_rel_user ADD COLUMN course_id INT NOT NULL DEFAULT 0 AFTER id");
+        }
+
+        if (!$table->hasColumn('session_id')) {
+            $this->addSql("ALTER TABLE skill_rel_user ADD COLUMN session_id INT NOT NULL DEFAULT 0 AFTER course_id");
+        }
+
         $this->addSql("ALTER TABLE skill_rel_user ADD INDEX idx_select_cs (course_id, session_id)");
 
         // Delete info of session_rel_user if session does not exists;
@@ -113,9 +123,9 @@ class Version110 extends AbstractMigrationChamilo
         $this->addSql("ALTER TABLE track_e_online CHANGE COLUMN login_ip user_ip varchar(39) NOT NULL DEFAULT ''");
         $this->addSql("ALTER TABLE track_e_login CHANGE COLUMN login_ip user_ip varchar(39) NOT NULL DEFAULT ''");
 
-        $this->addSql("ALTER TABLE user MODIFY COLUMN user_id int unsigned DEFAULT null");
+        $this->addSql("ALTER TABLE user MODIFY COLUMN user_id int unsigned DEFAULT NULL");
         $this->addSql("ALTER TABLE user DROP PRIMARY KEY");
-        $this->addSql("ALTER TABLE user ADD COLUMN id INT DEFAULT null");
+        $this->addSql("ALTER TABLE user ADD COLUMN id INT DEFAULT NULL");
         $this->addSql("UPDATE user SET id = user_id");
         $this->addSql("ALTER TABLE user MODIFY COLUMN id INT NOT NULL PRIMARY KEY AUTO_INCREMENT AFTER user_id");
 

+ 2 - 0
app/Migrations/Schema/V110/Version20150603181728.php

@@ -66,6 +66,8 @@ class Version20150603181728 extends AbstractMigrationChamilo
         $this->addSql("DELETE FROM c_item_property WHERE c_id NOT IN (SELECT id FROM course)");
         $this->addSql("DELETE FROM c_item_property WHERE to_group_id NOT IN (SELECT id FROM c_group_info)");
 
+        $this->addSql('UPDATE c_item_property cip SET cip.to_group_id = (SELECT cgi.iid FROM c_group_info cgi WHERE cgi.c_id = cip.c_id AND cgi.id = cip.to_group_id)');
+
         $this->addSql('ALTER TABLE c_item_property ADD CONSTRAINT FK_1D84C18191D79BD3 FOREIGN KEY (c_id) REFERENCES course(id)');
         $this->addSql('ALTER TABLE c_item_property ADD CONSTRAINT FK_1D84C181330D47E9 FOREIGN KEY (to_group_id) REFERENCES c_group_info (iid)');
         $this->addSql('ALTER TABLE c_item_property ADD CONSTRAINT FK_1D84C18129F6EE60 FOREIGN KEY (to_user_id) REFERENCES user (id)');

+ 3 - 0
app/Migrations/Schema/V111/Version111.php

@@ -62,6 +62,9 @@ class Version111 extends AbstractMigrationChamilo
         }
 
         $this->addSql('CREATE TABLE access_url_rel_course_category (id INT AUTO_INCREMENT NOT NULL, access_url_id INT NOT NULL, course_category_id INT NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB');
+        $this->addSql("INSERT INTO access_url_rel_course_category (access_url_id, course_category_id) VALUES (1, 1) ");
+        $this->addSql("INSERT INTO access_url_rel_course_category (access_url_id, course_category_id) VALUES (1, 2) ");
+        $this->addSql("INSERT INTO access_url_rel_course_category (access_url_id, course_category_id) VALUES (1, 3) ");
 
         $this->addSql('ALTER TABLE notification CHANGE content content TEXT');
 

+ 19 - 11
app/Resources/public/css/themes/rainbow/default.css

@@ -39,6 +39,7 @@ body {
   margin: 0;
   font-family: 'Open Sans', sans-serif;
   line-height: 1.72222;
+  background: url('images/bg.png') center center repeat-x;
 }
 
 a {
@@ -55,27 +56,25 @@ a:focus {
 }
 /* Menu Option */
 .item-menu a{
-    padding-left: 30% !important;
-    padding-right: 30% !important;
     color: #fff !important;
     font-size: 15px;
 }
 .navbar-collapse{
     padding: 0;
 }
-.menu-one{
+.menu-1{
     background: #41A62A;
 }
-.menu-two{
+.menu-2{
     background: #97BF0D;
 }
-.menu-three{
+.menu-3{
     background: #F9B200;
 }
-.menu-four{
+.menu-4{
     background: #E53140;
 }
-.menu-five{
+.menu-5{
     background: #E2007A;
 }
 /* end Menu Option */
@@ -177,6 +176,8 @@ a:focus {
   line-height: 22px;
   padding-top: 12.5px;
   padding-bottom: 12.5px;
+  padding-left: 20px;
+  padding-right: 20px;
 }
 .navbar-collapse{
   overflow: hidden !important;
@@ -189,7 +190,7 @@ a:focus {
 .navbar-default .navbar-nav > .active > a:hover,
 .navbar-default .navbar-nav > .active > a:focus{
   color: #fff;
-  background:#000080;
+  background:#07578A;
 }
 .navbar-default .navbar-nav > li > a{
   color: #333333;
@@ -225,7 +226,14 @@ a:focus {
 .nav > li > a:hover, .nav > li > a:focus{
    background-color: transparent;
 }
-
+.btn-primary{
+    background-color: #E53140;
+    border-color: #E53140;
+}
+.btn-primary:hover{
+    background-color: #CE2D30;
+    border-color: #CE2D30;
+}
 .navbar-inverse li a{
   line-height: 30px;
   background: none !important;
@@ -284,7 +292,7 @@ a:focus {
   background-color: #ECF0F1;
 }
 .breadcrumb > .active{
-  color: #95a5a6;
+    color: #FF0;
 }
 .panel-default{
   border-color: #ECF0F1;
@@ -300,7 +308,7 @@ a:focus {
 }
 /* End Jquery UI */
 footer{
-  background-color:#009EE0;
+  background-color:#E53140;
 }
 footer{
   color: #ffffff;

BIN
app/Resources/public/css/themes/rainbow/images/bg.png


BIN
app/Resources/public/css/themes/rainbow/images/scorm_current.png


+ 30 - 8
app/Resources/public/css/themes/rainbow/learnpath.css

@@ -1,3 +1,32 @@
+#learning_path_breadcrumb_zone .breadcrumb{
+    background-color: #009EE0;
+}
+.expand .fa{
+    background-color: #E53140;
+}
+.icon-toolbar .fa:hover{
+    background-color: #E53140;
+    color: #FFF;
+}
+.progress-bar-warning{
+    background-color: #E53140;
+}
+.scorm_item_normal.scorm_highlight a{
+    color: #E53140 !important;
+}
+.scorm_item_normal.scorm_highlight.scorm_completed{
+    background: transparent url("images/scorm_current.png") no-repeat scroll left center !important
+}
+.scorm_item_section{
+    -webkit-border-top-left-radius: 5px;
+    -webkit-border-top-right-radius: 5px;
+    -moz-border-radius-topleft: 5px;
+    -moz-border-radius-topright: 5px;
+    border-top-left-radius: 5px;
+    border-top-right-radius: 5px;
+}
+
+
 div.text {
 	margin-left : 6;
 	margin-right : 6;
@@ -159,14 +188,7 @@ table.lp_form th {
 table.lp_overview th.exercise {
 	width:50px;
 }
-table.lp_form input, table.lp_form select, table.lp_form textarea {
-/*	background:#F8F8F8;
-	border:1px solid #999999;
-	font-family:Arial, Verdana, Helvetica, sans-serif;
-	font-size:12px;
-	padding:1px 2px;
-	width:300px;*/
-}
+
 table.lp_form td.radio input, table.lp_form td.exercise input {
 	width:auto;
 }

+ 2 - 2
custompages/index-unlogged-dist.php

@@ -101,12 +101,12 @@ $rootWeb = api_get_path('WEB_PATH');
 			<div id="links">
 
                 <?php if (api_get_setting('allow_registration') === 'true') { ?>
-                <a href="<?php echo api_get_path(WEB_PATH); ?>main/auth/inscription.php?language=<?php echo api_get_interface_language(); ?>">
+                <a href="<?php echo api_get_path(WEB_CODE_PATH); ?>auth/inscription.php?language=<?php echo api_get_interface_language(); ?>">
                     <?php echo custompages_get_lang('Registration')?>
                 </a><br />
                 <?php } ?>
 
-                <a href="<?php echo api_get_path(WEB_PATH); ?>main/auth/lostPassword.php?language=<?php echo api_get_interface_language(); ?>">
+                <a href="<?php echo api_get_path(WEB_CODE_PATH); ?>auth/lostPassword.php?language=<?php echo api_get_interface_language(); ?>">
                     <?php echo custompages_get_lang('LostPassword')?>
                 </a>
 			</div>

+ 2 - 2
documentation/changelog.html

@@ -5085,9 +5085,9 @@ a simple videoconferencing interface.</p>
 </ul>
   </div>
 <hr />
-    <a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
+    <a href="http://validator.w3.org/check?uri=referer"><img src="//www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
     <a href="http://jigsaw.w3.org/css-validator/">
-        <img src="http://jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
+        <img src="//jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
     </a>
 </body>
 </html>

+ 2 - 2
documentation/credits.html

@@ -765,8 +765,8 @@ To know more about the Chamilo Association and how to get involve, <a href="http
 </div>
 
 <hr />
-    <a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
+    <a href="http://validator.w3.org/check?uri=referer"><img src="//www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
     <a href="http://jigsaw.w3.org/css-validator/">
-        <img src="http://jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
+        <img src="//jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
     </a>
 </body></html>

+ 2 - 2
documentation/dependencies.html

@@ -137,9 +137,9 @@ ensure all components are installed by an expert in the field.<br />
   </ul>
 </div>
 <hr />
-    <a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
+    <a href="http://validator.w3.org/check?uri=referer"><img src="//www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
 	<a href="http://jigsaw.w3.org/css-validator/">
-		<img src="http://jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
+		<img src="//jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
 	</a>
 </body>
 </html>

+ 2 - 2
documentation/index.html

@@ -56,8 +56,8 @@
 </div>
 
 <hr />
-    <a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
+    <a href="http://validator.w3.org/check?uri=referer"><img src="//www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
 	<a href="http://jigsaw.w3.org/css-validator/">
-		<img src="http://jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
+		<img src="//jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
 	</a>
 </body></html>

+ 2 - 2
documentation/installation_guide.html

@@ -787,9 +787,9 @@ If you have issues with files taking a long time to download, make sure you reco
 </div>
 
 <hr />
-    <a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
+    <a href="http://validator.w3.org/check?uri=referer"><img src="//www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
     <a href="http://jigsaw.w3.org/css-validator/">
-        <img src="http://jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
+        <img src="//jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
     </a>
 </body>
 </html>

+ 2 - 2
documentation/installation_guide_es_ES.html

@@ -805,9 +805,9 @@ Apache2: La configuración para nuestro sitio de ejemplo my.chamilo10.net sería
 </div>
 
 <hr />
-    <a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
+    <a href="http://validator.w3.org/check?uri=referer"><img src="//www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
 	<a href="http://jigsaw.w3.org/css-validator/">
-		<img src="http://jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
+		<img src="//jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
 	</a>
 </body>
 </html>

+ 2 - 2
documentation/installation_guide_fr_FR.html

@@ -818,9 +818,9 @@ Ce sont uniquement les redirections à placer dans un bloc server{}, comme les a
 </div>
 
 <hr />
-<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
+<a href="http://validator.w3.org/check?uri=referer"><img src="//www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
 <a href="http://jigsaw.w3.org/css-validator/">
-    <img src="http://jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
+    <img src="//jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
 </a>
 </body>
 </html>

+ 2 - 2
documentation/license.html

@@ -733,10 +733,10 @@ Public License instead of this License.  But first, please read
 </div
 <hr/>
     <a href="http://validator.w3.org/check?uri=referer"><img
-        src="http://www.w3.org/Icons/valid-xhtml10-blue"
+        src="//www.w3.org/Icons/valid-xhtml10-blue"
         alt="Valid XHTML 1.0 Transitional" height="31" width="88" style="float: right; margin: 1em;" /></a>
 	<a href="http://jigsaw.w3.org/css-validator/">
-		<img src="http://jigsaw.w3.org/css-validator/images/vcss-blue"  style="float: right; margin: 1em;"
+		<img src="//jigsaw.w3.org/css-validator/images/vcss-blue"  style="float: right; margin: 1em;"
         alt="Valid CSS" />
 	</a>
 </body>

+ 2 - 2
documentation/migration-checklist.html

@@ -55,9 +55,9 @@
 
 <hr />
 Don't have time or resources to optimize your Chamilo installation yourself? Hire an <a href="http://www.chamilo.org/en/providers">official Chamilo provider</a> and get it sorted out professionally by specialists.
-    <a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
+    <a href="http://validator.w3.org/check?uri=referer"><img src="//www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
 	<a href="http://jigsaw.w3.org/css-validator/">
-		<img src="http://jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
+		<img src="//jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
 	</a>
 <hr />
 <h2>Authors</h2>

+ 5 - 5
documentation/optimization.html

@@ -406,9 +406,9 @@ Header append Vary User-Agent env=!dont-vary
 </pre>
 <hr />
 Don't have time or resources to optimize your Chamilo installation yourself? Hire an <a href="http://www.chamilo.org/en/providers">official Chamilo provider</a> and get it sorted out professionally by specialists.
-    <a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
+    <a href="http://validator.w3.org/check?uri=referer"><img src="//www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
 	<a href="http://jigsaw.w3.org/css-validator/">
-		<img src="http://jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
+		<img src="//jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
 	</a>
 <hr />
 
@@ -604,10 +604,10 @@ This should have an immediate effect on the load average on your server.
 </ul>
 <hr />
 Don't have time or resources to optimize your Chamilo installation
-    yourself? Hire an <a href="http://www.chamilo.org/en/providers">official Chamilo provider</a> and get it sorted out professionally by specialists.
-    <a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
+    yourself? Hire an <a href="//www.chamilo.org/en/providers">official Chamilo provider</a> and get it sorted out professionally by specialists.
+    <a href="http://validator.w3.org/check?uri=referer"><img src="//www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
 	<a href="http://jigsaw.w3.org/css-validator/">
-		<img src="http://jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
+		<img src="//jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
 	</a>
 </div>
 </body>

+ 2 - 2
documentation/readme.html

@@ -140,9 +140,9 @@ Mail: <a href="mailto:info@chamilo.org">info@chamilo.org</a>
 </div>
 
 <hr />
-    <a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
+    <a href="http://validator.w3.org/check?uri=referer"><img src="//www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
 	<a href="http://jigsaw.w3.org/css-validator/">
-		<img src="http://jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
+		<img src="//jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
 	</a>
 
 </body>

+ 1 - 2
main/create_course/add_course.php

@@ -183,8 +183,7 @@ if ($course_validation_feature) {
     // if it is activated.
     if (empty($terms_and_conditions_url)) {
         if (api_get_setting('allow_terms_conditions') == 'true') {
-            $terms_and_conditions_url = api_get_path(WEB_CODE_PATH);
-            $terms_and_conditions_url .= 'auth/inscription.php?legal';
+            $terms_and_conditions_url = api_get_path(WEB_CODE_PATH).'auth/inscription.php?legal';
         }
     }
 

+ 5 - 8
main/exercice/fill_blanks.class.php

@@ -118,7 +118,8 @@ class FillBlanks extends Question
                         // get input size
                         var lainputsize = 200;
                         if ($("#samplesize\\\["+i+"\\\]").width()) {
-                            lainputsize = $("#samplesize\\\["+i+"\\\]").width();
+                        // this is a weird patch to avoid to reduce the size of input blank when you are writing in the ckeditor.
+                            lainputsize = $("#samplesize\\\["+i+"\\\]").width() + 9;
                         }
 
                         if (document.getElementById("weighting["+i+"]")) {
@@ -149,15 +150,11 @@ class FillBlanks extends Question
         if (isset($listAnswersInfo) && count($listAnswersInfo["tabweighting"]) > 0) {
 
             foreach ($listAnswersInfo["tabweighting"] as $i => $weighting) {
-                if (!empty($i)) {
-                    echo 'document.getElementById("weighting['.$i.']").value = "'.$weighting.'";';
-                }
+                echo 'document.getElementById("weighting['.$i.']").value = "'.$weighting.'";';
             }
             foreach ($listAnswersInfo["tabinputsize"] as $i => $sizeOfInput) {
-                if (!empty($i)) {
-                    echo 'document.getElementById("sizeofinput['.$i.']").value = "'.$sizeOfInput.'";';
-                    echo '$("#samplesize\\\['.$i.'\\\]").width('.$sizeOfInput.');';
-                }
+                echo 'document.getElementById("sizeofinput['.$i.']").value = "'.$sizeOfInput.'";';
+                echo '$("#samplesize\\\['.$i.'\\\]").width('.$sizeOfInput.');';
             }
         }
 

+ 26 - 12
main/exercice/question.class.php

@@ -1190,7 +1190,7 @@ abstract class Question
      * @author Olivier Brouckaert
      * @param integer $deleteFromEx - exercise ID if the question is only removed from one exercise
      */
-    function delete($deleteFromEx = 0)
+    public function delete($deleteFromEx = 0)
     {
         $course_id = api_get_course_int_id();
 
@@ -1199,7 +1199,7 @@ abstract class Question
         $TBL_REPONSES = Database::get_course_table(TABLE_QUIZ_ANSWER);
         $TBL_QUIZ_QUESTION_REL_CATEGORY = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
 
-        $id = $this->id;
+        $id = intval($this->id);
 
         // if the question must be removed from all exercises
         if (!$deleteFromEx) {
@@ -1223,27 +1223,33 @@ abstract class Question
             }
 
             $sql = "DELETE FROM $TBL_EXERCISE_QUESTION
-                    WHERE c_id = $course_id AND question_id = " . intval($id) . "";
+                    WHERE c_id = $course_id AND question_id = " . $id;
             Database::query($sql);
 
             $sql = "DELETE FROM $TBL_QUESTIONS
-                    WHERE c_id = $course_id AND id = " . intval($id) . "";
+                    WHERE c_id = $course_id AND id = " . $id;
             Database::query($sql);
 
             $sql = "DELETE FROM $TBL_REPONSES
-                    WHERE c_id = $course_id AND question_id = " . intval($id) . "";
+                    WHERE c_id = $course_id AND question_id = " . $id;
             Database::query($sql);
 
             // remove the category of this question in the question_rel_category table
             $sql = "DELETE FROM $TBL_QUIZ_QUESTION_REL_CATEGORY
-                    WHERE c_id = $course_id AND question_id = " . intval($id) . " AND c_id=" . api_get_course_int_id();
+                    WHERE 
+                        c_id = $course_id AND 
+                        question_id = " . $id;
             Database::query($sql);
 
-            api_item_property_update($this->course, TOOL_QUIZ, $id, 'QuizQuestionDeleted', api_get_user_id());
+            api_item_property_update(
+                $this->course,
+                TOOL_QUIZ,
+                $id,
+                'QuizQuestionDeleted',
+                api_get_user_id()
+            );
             $this->removePicture();
 
-            // resets the object
-            $this->Question();
         } else {
             // just removes the exercise from the list
             $this->removeFromList($deleteFromEx);
@@ -1251,7 +1257,14 @@ abstract class Question
                 // disassociate question with this exercise
                 $this->search_engine_edit($deleteFromEx, FALSE, TRUE);
             }
-            api_item_property_update($this->course, TOOL_QUIZ, $id, 'QuizQuestionDeleted', api_get_user_id());
+
+            api_item_property_update(
+                $this->course,
+                TOOL_QUIZ,
+                $id,
+                'QuizQuestionDeleted',
+                api_get_user_id()
+            );
         }
     }
 
@@ -1259,10 +1272,10 @@ abstract class Question
      * Duplicates the question
      *
      * @author Olivier Brouckaert
-     * @param  array   Course info of the destination course
+     * @param  array   $course_info Course info of the destination course
      * @return int     ID of the new question
      */
-    public function duplicate($course_info = null)
+    public function duplicate($course_info = [])
     {
         if (empty($course_info)) {
             $course_info = $this->course;
@@ -1348,6 +1361,7 @@ abstract class Question
     public function get_question_type_name()
     {
         $key = self::$questionTypes[$this->type];
+        
         return get_lang($key[1]);
     }
 

+ 34 - 31
main/forum/forumfunction.inc.php

@@ -891,32 +891,36 @@ function deleteForumCategoryThread($content, $id)
  */
 function delete_post($post_id)
 {
-    $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
     $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
     $post_id = intval($post_id);
     $course_id = api_get_course_int_id();
+    $em = Database::getManager();
 
-    // Get parent_post_id of deleted post.
-    $tab_post_info = get_post_information($post_id);
+    $post = $em
+        ->getRepository('ChamiloCourseBundle:CForumPost')
+        ->findOneBy(['cId' => $course_id, 'postId' => $post_id]);
 
-    if ($tab_post_info) {
-        $post_parent_id_of_deleted_post = intval($tab_post_info['post_parent_id']);
-        $thread_id_of_deleted_post = $tab_post_info['thread_id'];
-        $forum_if_of_deleted_post = $tab_post_info['forum_id'];
-        $sql = "UPDATE $table_posts
-                SET post_parent_id=$post_parent_id_of_deleted_post
+    if ($post) {
+        $em
+            ->createQuery('
+                UPDATE ChamiloCourseBundle:CForumPost p
+                SET p.postParentId = :parent_of_deleted_post
                 WHERE
-                    c_id = $course_id AND
-                    post_parent_id=$post_id AND
-                    thread_id=$thread_id_of_deleted_post AND
-                    forum_id=$forum_if_of_deleted_post";
-
-        Database::query($sql);
-
-        // Note: This has to be a recursive function that deletes all of the posts in this block.
-        $sql = "DELETE FROM $table_posts
-                WHERE c_id = $course_id AND post_id = ".intval($post_id)."";
-        Database::query($sql);
+                    p.cId = :course AND
+                    p.postParentId = :post AND
+                    p.threadId = :thread_of_deleted_post AND
+                    p.forumId = :forum_of_deleted_post
+            ')
+            ->execute([
+                'parent_of_deleted_post' => $post->getPostParentId(),
+                'course' => $course_id,
+                'post' => $post->getPostId(),
+                'thread_of_deleted_post' => $post->getThreadId(),
+                'forum_of_deleted_post' => $post->getForumId()
+            ]);
+
+        $em->remove($post);
+        $em->flush();
 
         // Delete attachment file about this post id.
         delete_attachment($post_id);
@@ -1884,7 +1888,7 @@ function getThreadInfo($threadId, $cId)
  *
  * @return array containing all the information about the posts of a given thread
  */
-function getPosts($forumInfo, $threadId, $orderDirection = 'ASC', $recursive = false, $postId = 0, $depth = -1)
+function getPosts($forumInfo, $threadId, $orderDirection = 'ASC', $recursive = false, $postId = null, $depth = -1)
 {
     $list = [];
 
@@ -1918,7 +1922,6 @@ function getPosts($forumInfo, $threadId, $orderDirection = 'ASC', $recursive = f
         ->addCriteria($criteria)
         ->addOrderBy('p.postId', $orderDirection);
 
-
     $posts = $qb->getQuery()->getResult();
 
     $depth++;
@@ -2526,7 +2529,7 @@ function store_thread($current_forum, $values, $courseInfo = array(), $showMessa
             'poster_name' => isset($values['poster_name']) ? $values['poster_name'] : '',
             'post_date' => $post_date,
             'post_notification' => isset($values['post_notification']) ? (int) $values['post_notification'] : 0,
-            'post_parent_id' => 0,
+            'post_parent_id' => null,
             'visible' => $visible,
             'post_id' => 0
         ];
@@ -2801,6 +2804,7 @@ function show_add_post_form($current_forum, $forum_setting, $action = '', $id =
         'post_text',
         get_lang('Text'),
         true,
+        false,
         api_is_allowed_to_edit(null, true) ? array(
             'ToolbarSet' => 'Forum',
             'Width' => '100%',
@@ -2967,8 +2971,7 @@ function show_add_post_form($current_forum, $forum_setting, $action = '', $id =
             }
             Security::clear_token();
 
-            // Add new thread in table forum_thread.
-            store_thread($current_forum, $values);
+            return $values;
         }
     } else {
         $token = Security::get_token();
@@ -3415,7 +3418,7 @@ function show_edit_post_form(
     $form->addElement('hidden', 'thread_id', $current_thread['thread_id']);
     $form->addElement('hidden', 'id_attach', $id_attach);
 
-    if ($current_post['post_parent_id'] == 0) {
+    if (empty($current_post['post_parent_id'])) {
         $form->addElement('hidden', 'is_first_post_of_thread', '1');
     }
 
@@ -3531,7 +3534,7 @@ function show_edit_post_form(
 
     if ($forum_setting['allow_sticky'] &&
         api_is_allowed_to_edit(null, true) &&
-        $current_post['post_parent_id'] == 0
+        empty($current_post['post_parent_id'])
     ) {
         // The sticky checkbox only appears when it is the first post of a thread.
         $form->addElement('checkbox', 'thread_sticky', '', get_lang('StickyPost'));
@@ -4321,12 +4324,12 @@ function store_move_post($values)
         );
 
         // Moving the post to the newly created thread.
-        $sql = "UPDATE $table_posts SET thread_id='".intval($new_thread_id)."', post_parent_id='0'
+        $sql = "UPDATE $table_posts SET thread_id='".intval($new_thread_id)."', post_parent_id = NULL
                 WHERE c_id = $course_id AND post_id='".intval($values['post_id'])."'";
         Database::query($sql);
 
         // Resetting the parent_id of the thread to 0 for all those who had this moved post as parent.
-        $sql = "UPDATE $table_posts SET post_parent_id='0'
+        $sql = "UPDATE $table_posts SET post_parent_id = NULL
                 WHERE c_id = $course_id AND post_parent_id='".intval($values['post_id'])."'";
         Database::query($sql);
 
@@ -4385,12 +4388,12 @@ function store_move_post($values)
         Database::query($sql);
 
         // moving to the chosen thread
-        $sql = "UPDATE $table_posts SET thread_id='".intval($_POST['thread'])."', post_parent_id='0'
+        $sql = "UPDATE $table_posts SET thread_id='".intval($_POST['thread'])."', post_parent_id = NULL
                 WHERE c_id = $course_id AND post_id='".intval($values['post_id'])."'";
         Database::query($sql);
 
         // resetting the parent_id of the thread to 0 for all those who had this moved post as parent
-        $sql = "UPDATE $table_posts SET post_parent_id='0'
+        $sql = "UPDATE $table_posts SET post_parent_id = NULL
                 WHERE c_id = $course_id AND post_parent_id='".intval($values['post_id'])."'";
         Database::query($sql);
 

+ 6 - 1
main/forum/newthread.php

@@ -168,7 +168,7 @@ echo '</div>';
 // Set forum attachment data into $_SESSION
 getAttachedFiles($current_forum['forum_id'], 0, 0);
 
-show_add_post_form(
+$values = show_add_post_form(
     $current_forum,
     $forum_setting,
     'newthread',
@@ -176,6 +176,11 @@ show_add_post_form(
     isset($_SESSION['formelements']) ? $_SESSION['formelements'] : null
 );
 
+if (!empty($values) && isset($values['SubmitPost'])) {
+    // Add new thread in table forum_thread.
+    store_thread($current_forum, $values);
+}
+
 if (isset($origin) && $origin == 'learnpath') {
     Display::display_reduced_footer();
 } else {

+ 39 - 27
main/forum/viewthread_flat.inc.php

@@ -62,27 +62,30 @@ if (isset($current_thread['thread_id'])) {
             ) {
                 if ($_user['user_id'] || ($current_forum['allow_anonymous'] == 1 && !$_user['user_id'])) {
                     if (!api_is_anonymous() && api_is_allowed_to_session_edit(false, true)) {
-
-                        $buttonReply = Display::tag(
-                            'a',
-                            '<em class="fa fa-reply"></em> ' . get_lang('ReplyToMessage'),
-                            array(
-                                'href' => 'reply.php?' . api_get_cidreq()
-                                    . "&forum=$clean_forum_id&thread=$clean_thread_id&post="
-                                    . "{$row['post_id']}&action=replymessage&origin=$origin",
-                                'class' => 'btn btn-primary'
-                            )
+                        $buttonReply = Display::toolbarButton(
+                            get_lang('ReplyToMessage'),
+                            'reply.php?' . api_get_cidreq() . '&' . http_build_query([
+                                'forum' => $clean_forum_id,
+                                'thread' => $clean_thread_id,
+                                'post' => $row['post_id'],
+                                'action' => 'replymessage'
+                            ]),
+                            'reply',
+                            'primary',
+                            ['id' => "reply-to-post-{$row['post_id']}"]
                         );
 
-                        $buttonQuote = Display::tag(
-                            'a',
-                            '<em class="fa fa-quote-left"></em> ' . get_lang('QuoteMessage'),
-                            array(
-                                'href' => 'reply.php?' . api_get_cidreq()
-                                    . "&forum=$clean_forum_id&thread=$clean_thread_id"
-                                    . "&post={$row['post_id']}&action=quote&origin=$origin",
-                                'class' => 'btn btn-success'
-                            )
+                        $buttonQuote = Display::toolbarButton(
+                            get_lang('QuoteMessage'),
+                            'reply.php?' . api_get_cidreq() . '&' . http_build_query([
+                                'forum' => $clean_forum_id,
+                                'thread' => $clean_thread_id,
+                                'post' => $row['post_id'],
+                                'action' => 'quote'
+                            ]),
+                            'quote-left',
+                            'success',
+                            ['id' => "quote-post-{$row['post_id']}"]
                         );
                     }
                 }
@@ -188,14 +191,23 @@ if (isset($current_thread['thread_id'])) {
                 ) {
 
                     if ($locked == false) {
-                        $iconEdit .= "<a href=\"" . api_get_self() . "?" . api_get_cidreq() . "&forum="
-                            . $clean_forum_id . "&thread=" . $clean_thread_id
-                            . "&action=delete&content=post&id=" . $row['post_id'] . "&origin="
-                            . $origin . "\" onclick=\"javascript:if(!confirm('"
-                            . addslashes(api_htmlentities(get_lang('DeletePost'), ENT_QUOTES))
-                            . "')) return false;\">"
-                            . Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL)
-                            . "</a>";
+                        $deleteUrl = api_get_self() . '?' . api_get_cidreq() . '&' . http_build_query([
+                            'forum' => $clean_forum_id,
+                            'thread' => $clean_thread_id,
+                            'action' => 'delete',
+                            'content' => 'post',
+                            'id' => $row['post_id']
+                        ]);
+                        $iconEdit .= Display::url(
+                            Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL),
+                            $deleteUrl,
+                            [
+                                'onclick' => "javascript:if(!confirm('"
+                                    . addslashes(api_htmlentities(get_lang('DeletePost'), ENT_QUOTES))
+                                    . "')) return false;",
+                                'id' => "delete-post-{$row['post_id']}"
+                            ]
+                        );
                     }
                 }
                 if (

+ 39 - 25
main/forum/viewthread_nested.inc.php

@@ -138,12 +138,23 @@ foreach ($rows as $post) {
         !(api_is_course_coach() && $current_forum['session_id'] != $sessionId)
     ) {
         if ($locked == false) {
-            $iconEdit .="<a href=\"" . api_get_self() . "?" . api_get_cidreq()
-                . "&forum=$clean_forum_id&thread=$clean_thread_id&action=delete&content=post&id={$post['post_id']}"
-                . "\" onclick=\"javascript:if(!confirm('"
-                . addslashes(api_htmlentities(get_lang('DeletePost'), ENT_QUOTES)) . "')) return false;\">"
-                . Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL)
-                . "</a>";
+            $deleteUrl = api_get_self() . '?' . api_get_cidreq() . '&' . http_build_query([
+                    'forum' => $clean_forum_id,
+                    'thread' => $clean_thread_id,
+                    'action' => 'delete',
+                    'content' => 'post',
+                    'id' => $post['post_id']
+                ]);
+            $iconEdit .= Display::url(
+                Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL),
+                $deleteUrl,
+                [
+                    'onclick' => "javascript:if(!confirm('"
+                        . addslashes(api_htmlentities(get_lang('DeletePost'), ENT_QUOTES))
+                        . "')) return false;",
+                    'id' => "delete-post-{$post['post_id']}"
+                ]
+            );
         }
     }
 
@@ -206,27 +217,30 @@ foreach ($rows as $post) {
     ) {
         if ($userId || ($current_forum['allow_anonymous'] == 1 && !$userId)) {
             if (!api_is_anonymous() && api_is_allowed_to_session_edit(false, true)) {
-
-                $buttonReply = Display::tag(
-                    'a',
-                    '<em class="fa fa-reply"></em> ' . get_lang('ReplyToMessage'),
-                    array(
-                        'href' => 'reply.php?' . api_get_cidreq()
-                            . "&forum=$clean_forum_id'&thread=$clean_thread_id"
-                            . "&post={$post['post_id']}&action=replymessage&origin=$origin",
-                        'class' => 'btn btn-primary'
-                    )
+                $buttonReply = Display::toolbarButton(
+                    get_lang('ReplyToMessage'),
+                    'reply.php?' . api_get_cidreq() . '&' . http_build_query([
+                        'forum' => $clean_forum_id,
+                        'thread' => $clean_thread_id,
+                        'post' => $post['post_id'],
+                        'action' => 'replymessage'
+                    ]),
+                    'reply',
+                    'primary',
+                    ['id' => "reply-to-post-{$post['post_id']}"]
                 );
 
-                $buttonQuote = Display::tag(
-                    'a',
-                    '<em class="fa fa-quote-left"></em> ' . get_lang('QuoteMessage'),
-                    array(
-                        'href' => 'reply.php?' . api_get_cidreq()
-                            . "&forum=$clean_forum_id&thread=$clean_thread_id"
-                            . "&post={$post['post_id']}&action=quote&origin=$origin",
-                        'class' => 'btn btn-success'
-                    )
+                $buttonQuote = Display::toolbarButton(
+                    get_lang('QuoteMessage'),
+                    'reply.php?' . api_get_cidreq() . '&' . http_build_query([
+                        'forum' => $clean_forum_id,
+                        'thread' => $clean_thread_id,
+                        'post' => $post['post_id'],
+                        'action' => 'quote'
+                    ]),
+                    'quote-left',
+                    'success',
+                    ['id' => "quote-post-{$post['post_id']}"]
                 );
             }
         }

+ 143 - 0
main/inc/lib/banner.lib.php

@@ -508,6 +508,149 @@ function return_menu()
     return $menu;
 }
 
+/**
+ * Returns an array of elements to print as the main menu
+ * @return array Array of arrays with ['possible_tabs'] as the main element
+ */
+function returnMenuArray()
+{
+    $mainNavigation = return_navigation_array();
+    unset($mainNavigation['navigation']);
+    //$navigation = $navigation['navigation'];
+    // Get active language
+    $lang = api_get_setting('platformLanguage');
+    if (!empty($_SESSION['user_language_choice'])) {
+        $lang = $_SESSION['user_language_choice'];
+    } elseif (!empty($_SESSION['_user']['language'])) {
+        $lang = $_SESSION['_user']['language'];
+    }
+    // Preparing home folder for multiple urls
+    if (api_get_multiple_access_url()) {
+        $access_url_id = api_get_current_access_url_id();
+        if ($access_url_id != -1) {
+            // If not a dead URL
+            $urlInfo = api_get_access_url($access_url_id);
+            $url = api_remove_trailing_slash(preg_replace('/https?:\/\//i', '', $urlInfo['url']));
+            $cleanUrl = api_replace_dangerous_char($url);
+            $cleanUrl = str_replace('/', '-', $cleanUrl);
+            $cleanUrl .= '/';
+            $homepath  = api_get_path(SYS_APP_PATH).'home/'.$cleanUrl; //homep for Home Path
+            //we create the new dir for the new sites
+            if (!is_dir($homepath)) {
+                mkdir($homepath, api_get_permissions_for_new_directories());
+            }
+        }
+    } else {
+        $homepath = api_get_path(SYS_APP_PATH).'home/';
+    }
+    $ext = '.html';
+    $menuTabs = 'home_tabs';
+    $menuTabsLoggedIn = 'home_tabs_logged_in';
+    $pageContent = '';
+    // Get the extra page content, containing the links to add to the tabs
+    if (is_file($homepath.$menuTabs.'_'.$lang.$ext) && is_readable($homepath.$menuTabs.'_'.$lang.$ext)) {
+        $pageContent = @(string) file_get_contents($homepath . $menuTabs . '_' . $lang . $ext);
+    } elseif (is_file($homepath.$menuTabs.$lang.$ext) && is_readable($homepath.$menuTabs.$lang.$ext)) {
+        $pageContent = @(string) file_get_contents($homepath . $menuTabs . $lang . $ext);
+    } else {
+        //$errorMsg = get_lang('HomePageFilesNotReadable');
+    }
+    // Sanitize page content
+    $pageContent = api_to_system_encoding($pageContent, api_detect_encoding(strip_tags($pageContent)));
+    $open = str_replace('{rel_path}',api_get_path(REL_PATH), $pageContent);
+    $open = api_to_system_encoding($open, api_detect_encoding(strip_tags($open)));
+    // Get the extra page content, containing the links to add to the tabs
+    //  that are only for users already logged in
+    $openMenuTabsLoggedIn = '';
+    if (api_get_user_id() && !api_is_anonymous()) {
+        if (is_file($homepath . $menuTabsLoggedIn . '_' . $lang . $ext) && is_readable($homepath . $menuTabsLoggedIn . '_' . $lang . $ext)) {
+            $pageContent = @(string) file_get_contents($homepath . $menuTabsLoggedIn . '_' . $lang . $ext);
+            $pageContent = str_replace('::private', '', $pageContent);
+        } elseif (is_file($homepath . $menuTabsLoggedIn . $lang . $ext) && is_readable($homepath . $menuTabsLoggedIn . $lang . $ext)) {
+            $pageContent = @(string) file_get_contents($homepath . $menuTabsLoggedIn . $lang . $ext);
+            $pageContent = str_replace('::private', '', $pageContent);
+        } else {
+            //$errorMsg = get_lang('HomePageFilesNotReadable');
+        }
+        
+        $pageContent = api_to_system_encoding($pageContent, api_detect_encoding(strip_tags($pageContent)));
+        $openMenuTabsLoggedIn = str_replace('{rel_path}',api_get_path(REL_PATH), $pageContent);
+        $openMenuTabsLoggedIn = api_to_system_encoding($openMenuTabsLoggedIn, api_detect_encoding(strip_tags($openMenuTabsLoggedIn)));
+    }
+    if (!empty($open) OR !empty($openMenuTabsLoggedIn)) {
+        if (strpos($open.$openMenuTabsLoggedIn, 'show_menu') === false) {
+            if (api_is_anonymous()) {
+                $mainNavigation['possible_tabs'][SECTION_CAMPUS]  = null;
+            }
+        } else {
+            if (api_get_user_id() && !api_is_anonymous()) {
+                $list = split("\n", $openMenuTabsLoggedIn);
+                foreach ($list as $link) {
+                    $matches = array();
+                    $match = preg_match('$href="([^"]*)" target="([^"]*)">([^<]*)</a>$', $link, $matches);
+                    if ($match) {
+                        $mainNavigation['possible_tabs'][$matches[3]] = array(
+                            'url' => $matches[1],
+                            'target' => $matches[2],
+                            'title' => $matches[3],
+                            'key' => 'extra-page-' . str_replace(' ', '-', strtolower($matches[3]))
+                        );
+                    }
+                }
+               
+            } else {
+                
+                $list = split("\n", $open);
+                foreach ($list as $link) {               
+                    $matches = array();
+                    $match = preg_match('$href="([^"]*)" target="([^"]*)">([^<]*)</a>$', $link, $matches);
+                    if ($match) {
+                        $mainNavigation['possible_tabs'][$matches[3]] = array(
+                            'url' => $matches[1],
+                            'target' => $matches[2],
+                            'title' => $matches[3],
+                            'key' => 'extra-page-' . str_replace(' ', '-', strtolower($matches[3]))
+                        );
+                    }
+                }
+            }
+        }
+    }
+    
+    if (count($mainNavigation['possible_tabs']) > 0) {
+        //$pre_lis = '';
+        $activeSection = '';
+        foreach ($mainNavigation['possible_tabs'] as $section => $navigation_info) {
+            $key = (!empty($navigation_info['key'])?'tab-'.$navigation_info['key']:'');
+            if (isset($GLOBALS['this_section'])) {
+                $tempSection = $section;
+                if ($section == 'social') {
+                    $tempSection = 'social-network';
+                }
+                if ($tempSection == $GLOBALS['this_section']) {
+                    $activeSection = $section;
+                }
+                // If we're on the index page and a specific extra link has been
+                // loaded
+                if ($GLOBALS['this_section'] == SECTION_CAMPUS) {
+                    if (!empty($_GET['include'])) {
+                        $name = str_replace(' ', '-', strtolower($navigation_info['title'])) . '_' . $lang . $ext;
+                        if ($_GET['include'] == $name) {
+                            $activeSection = $section;
+                        }
+                    }
+                }
+            } else {
+                $current = '';
+            }
+            $mainNavigation['possible_tabs'][$section]['current'] = '';
+        }
+        $mainNavigation['possible_tabs'][$activeSection]['current'] = 'active';
+        
+    }
+    return $mainNavigation;
+}
+
 function return_breadcrumb($interbreadcrumb, $language_file, $nameTools)
 {
     $session_id = api_get_session_id();

+ 7 - 8
main/inc/lib/course.lib.php

@@ -3236,7 +3236,7 @@ class CourseManager
         $medium->resize(85);
         $medium->send_image($course_medium_image, -1, 'png');
         $normal = new Image($source_file);
-        $normal->resize(300);
+        $normal->resize(400);
         $normal->send_image($course_image, -1, 'png');
 
         $result = $medium && $normal;
@@ -3358,7 +3358,7 @@ class CourseManager
             $with_special_courses = ' course.code IN ("' . implode('","', $special_course_list) . '")';
         }
         
-        $courseList = array();
+        $courseList = [];
         if (!empty($with_special_courses)) {
             $sql = "SELECT
                         course.id,
@@ -3385,7 +3385,7 @@ class CourseManager
                         continue;
                     }
 
-                    $params = array();
+                    $params = [];
                     // Get notifications.
                     $course_info['id_session'] = null;
                     $course_info['status'] = $course['status'];
@@ -3402,13 +3402,13 @@ class CourseManager
                         if ($load_dirs) {
                             $params['document'] = '<a id="document_preview_' . $course_info['real_id'] . '_0" class="document_preview btn btn-default btn-sm" href="javascript:void(0);">'
                                . Display::returnFontAwesomeIcon('folder-open') . '</a>';
-                            $params['document'] .= Display::div('', array('id' => 'document_result_' . $course_info['real_id'] . '_0', 'class' => 'document_preview_container'));
+                            $params['document'] .= Display::div('', ['id' => 'document_result_' . $course_info['real_id'] . '_0', 'class' => 'document_preview_container']);
                         }
                     }else{
                         if ($course_info['visibility'] != COURSE_VISIBILITY_CLOSED && $load_dirs) {
                             $params['document'] = '<a id="document_preview_' . $course_info['real_id'] . '_0" class="document_preview btn btn-default btn-sm" href="javascript:void(0);">'
                                . Display::returnFontAwesomeIcon('folder-open') . '</a>';
-                            $params['document'] .= Display::div('', array('id' => 'document_result_' . $course_info['real_id'] . '_0', 'class' => 'document_preview_container'));
+                            $params['document'] .= Display::div('', ['id' => 'document_result_' . $course_info['real_id'] . '_0', 'class' => 'document_preview_container']);
                         }
                     }
                     
@@ -3426,9 +3426,8 @@ class CourseManager
                     if (api_get_setting('display_teacher_in_courselist') === 'true') {
                         $params['teachers'] = CourseManager::getTeachersFromCourseByCode($course['code']);
                     }
-                    
-                    $iconName = basename($course_info['course_image']);
-                    if ($showCustomIcon === 'true' && $iconName != 'course.png') {
+
+                    if ($showCustomIcon === 'true') {
                         $params['thumbnails'] = $course_info['course_image'];
                         $params['image'] = $course_info['course_image_large'];
                     }

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

@@ -406,7 +406,8 @@ class MessageManager
                     $new_user_list,
                     $subject,
                     $content,
-                    $group_info
+                    $group_info,
+                    $file_attachments
                 );
             }
 

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

@@ -966,7 +966,7 @@ class Template
         $this->assign('portal_name', $portal_name);
 
         //Menu
-        $menu = return_menu();
+        $menu = returnMenuArray();
         $this->assign('menu', $menu);
 
         // Setting notifications

+ 17 - 18
main/inc/lib/tracking.lib.php

@@ -2266,16 +2266,12 @@ class Tracking
                 $groupBy";*/
 
         $sql = "
-            SELECT
-                    lp_id,
-                    view_count,
-                    progress
-            FROM $lpViewTable lp_view
+            SELECT lp_id, view_count, progress FROM $lpViewTable lp_view
             WHERE
-              $conditionToString
-            $groupBy
+                $conditionToString
+                $groupBy
             ORDER BY view_count DESC
-            ";
+        ";
 
         $result = Database::query($sql);
 
@@ -2787,8 +2783,8 @@ class Tracking
 
             // Check the real number of LPs corresponding to the filter in the
             // database (and if no list was given, get them all)
-
-            $res_row_lp = Database::query("SELECT DISTINCT(id) FROM $lp_table WHERE c_id = $course_id $condition_lp");
+            $sql = "SELECT DISTINCT(id) FROM $lp_table WHERE c_id = $course_id $condition_lp";
+            $res_row_lp = Database::query($sql);
             $count_row_lp = Database::num_rows($res_row_lp);
 
             // calculates time
@@ -2796,15 +2792,18 @@ class Tracking
                 while ($row_lp = Database::fetch_array($res_row_lp)) {
                     $lp_id = intval($row_lp['id']);
                     $sql = 'SELECT SUM(total_time)
-                        FROM '.$t_lpiv.' AS item_view
-                        INNER JOIN '.$t_lpv.' AS view
-                            ON item_view.lp_view_id = view.id
+                            FROM '.$t_lpiv.' AS item_view
+                            INNER JOIN '.$t_lpv.' AS view
+                            ON (
+                                item_view.lp_view_id = view.id AND 
+                                item_view.c_id = view.c_id
+                            )
                             WHERE
-                            item_view.c_id 		= '.$course_id.' AND
-                            view.c_id 			= '.$course_id.' AND
-                            view.lp_id 			= '.$lp_id.'
-                            AND view.user_id 	= '.$student_id.' AND
-                            session_id 			= '.$session_id;
+                                item_view.c_id = '.$course_id.' AND
+                                view.c_id = '.$course_id.' AND
+                                view.lp_id = '.$lp_id.' AND 
+                                view.user_id = '.$student_id.' AND
+                                session_id = '.$session_id;
 
                     $rs = Database::query($sql);
                     if (Database :: num_rows($rs) > 0) {

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

@@ -208,8 +208,6 @@ class IndexManager
                     $html .= '<li><a href="' . api_get_path(WEB_CODE_PATH) . 'dashboard/index.php">'.get_lang('Dashboard').'</a></li>';
                 }
             }
-
-
             $html .= '</ul>';
         }
 
@@ -934,8 +932,6 @@ class IndexManager
         $show_create_link = false;
         $show_course_link = false;
 
-        $userInfo = api_get_user_info();
-
         if ((api_get_setting('allow_users_to_create_courses') == 'false' &&
             !api_is_platform_admin()) || api_is_student()
         ) {
@@ -1000,14 +996,6 @@ class IndexManager
             }
         }
 
-        $my_account_content .= '<li class="add-course"><a href="' . api_get_path(WEB_PATH) . 'search.php">'.
-            Display::return_icon('new-course.png',  get_lang('Diagnosis')) . get_lang('Diagnosis').'</a></li>';
-
-        if ($userInfo['status'] == DRH) {
-            $my_account_content .= '<li class="add-course"><a href="' . api_get_path(WEB_PATH) . 'load_search.php">' .
-                Display::return_icon('new-course.png', get_lang('ManageDiagnosis')) . get_lang('Diagnosis') . '</a></li>';
-        }
-
         $my_account_content .= '</ul>';
 
         if (!empty($my_account_content)) {
@@ -1062,7 +1050,7 @@ class IndexManager
                 $user_id,
                 $this->load_directories_preview
             );
-           
+
             // Display courses.
             $courses = CourseManager::returnCourses(
                 $user_id,
@@ -1070,14 +1058,16 @@ class IndexManager
             );
             $this->tpl->assign('special_courses', $specialCourses);
             $this->tpl->assign('courses', $courses);
-            if ($_configuration['view_grid_courses']==true) {
+            if (isset($_configuration['view_grid_courses']) && $_configuration['view_grid_courses']) {
                 $listCourse = $this->tpl->fetch(
-                $this->tpl->get_template('user_portal/grid_courses.tpl'));
+                $this->tpl->get_template('/user_portal/grid_courses.tpl'));
             } else {
                 $listCourse = $this->tpl->fetch(
-                $this->tpl->get_template('user_portal/classic_courses.tpl'));
-            }          
-            $courseCount = $specialCourses['course_count'] + $courses['course_count'];
+                $this->tpl->get_template('/user_portal/classic_courses.tpl'));
+            }
+            if (!empty($specialCourses['course_count']) && !empty($courses['course_count'])) {
+                $courseCount = intval($specialCourses['course_count']) + intval($courses['course_count']);
+            }
         }
 
         $sessions_with_category = '';
@@ -1377,7 +1367,7 @@ class IndexManager
         }
 
         return [
-            'html' => $sessions_with_category.$sessions_with_no_category.$listCourse.$special_courses,
+            'html' => $sessions_with_category.$sessions_with_no_category.$listCourse,
             'session_count' => $sessionCount,
             'course_count' => $courseCount
         ];

+ 31 - 26
main/newscorm/learnpath.class.php

@@ -1595,7 +1595,8 @@ class learnpath
             error_log('New LP - In learnpath::get_brother_chapters()', 0);
         }
 
-        if (empty($id)|| $id != strval(intval($id))) {
+        if (empty($id) || $id != strval(intval($id))) {
+
             return array ();
         }
 
@@ -1606,21 +1607,24 @@ class learnpath
         if (Database :: num_rows($res_parent) > 0) {
             $row_parent = Database :: fetch_array($res_parent);
             $parent = $row_parent['parent_item_id'];
-            $sql_bros = "SELECT * FROM $lp_item
-                        WHERE
-                            c_id = ".$course_id." AND
-                            parent_item_id = $parent AND
-                            id = $id AND
-                            item_type='dokeos_chapter'
-                        ORDER BY display_order";
-            $res_bros = Database::query($sql_bros);
-            $list = array ();
+            $sql = "SELECT * FROM $lp_item
+                    WHERE
+                        c_id = ".$course_id." AND
+                        parent_item_id = $parent AND
+                        id = $id AND
+                        item_type='dokeos_chapter'
+                    ORDER BY display_order";
+            $res_bros = Database::query($sql);
+
+            $list = array();
             while ($row_bro = Database :: fetch_array($res_bros)) {
                 $list[] = $row_bro;
             }
+
             return $list;
         }
-        return array ();
+
+        return array();
     }
 
     /**
@@ -1959,7 +1963,7 @@ class learnpath
      * Gets the navigation bar for the learnpath display screen
      * @return	string	The HTML string to use as a navigation bar
      */
-    public function get_navigation_bar($idBar = null, $display=null) {
+    public function get_navigation_bar($idBar = null, $display = null) {
         if ($this->debug > 0) {
             error_log('New LP - In learnpath::get_navigation_bar()', 0);
         }
@@ -3295,6 +3299,7 @@ class learnpath
                 $html .= '</div>';
             }
         }
+
         return $html;
 
     }
@@ -6355,18 +6360,18 @@ class learnpath
             $res = Database::query($sql);
             $row = Database::fetch_array($res);
             switch ($row['item_type']) {
-                case 'dokeos_chapter' :
-                case 'dir' :
-                case 'asset' :
-                case 'sco' :
-                    if (isset ($_GET['view']) && $_GET['view'] == 'build') {
+                case 'dokeos_chapter':
+                case 'dir':
+                case 'asset':
+                case 'sco':
+                    if (isset($_GET['view']) && $_GET['view'] == 'build') {
                         $return .= $this->display_manipulate($item_id, $row['item_type']);
                         $return .= $this->display_item_form($row['item_type'], get_lang('EditCurrentChapter') . ' :', 'edit', $item_id, $row);
                     } else {
                         $return .= $this->display_item_small_form($row['item_type'], get_lang('EditCurrentChapter') . ' :', $row);
                     }
                     break;
-                case TOOL_DOCUMENT :
+                case TOOL_DOCUMENT:
                     $tbl_doc = Database :: get_course_table(TABLE_DOCUMENT);
                     $sql = "SELECT lp.*, doc.path as dir
                             FROM " . $tbl_lp_item . " as lp
@@ -6381,7 +6386,7 @@ class learnpath
                     $return .= $this->display_manipulate($item_id, $row['item_type']);
                     $return .= $this->display_document_form('edit', $item_id, $row_step);
                     break;
-                case TOOL_LINK :
+                case TOOL_LINK:
                     $link_id = (string) $row['path'];
                     if (ctype_digit($link_id)) {
                         $tbl_link = Database :: get_course_table(TABLE_LINK);
@@ -6396,7 +6401,7 @@ class learnpath
                     $return .= $this->display_manipulate($item_id, $row['item_type']);
                     $return .= $this->display_link_form('edit', $item_id, $row);
                     break;
-                case TOOL_LP_FINAL_ITEM :
+                case TOOL_LP_FINAL_ITEM:
                     $_SESSION['finalItem'] = true;
                     $tbl_doc = Database :: get_course_table(TABLE_DOCUMENT);
                     $sql = "SELECT lp.*, doc.path as dir
@@ -6412,7 +6417,7 @@ class learnpath
                     $return .= $this->display_manipulate($item_id, $row['item_type']);
                     $return .= $this->display_document_form('edit', $item_id, $row_step);
                     break;
-                case 'dokeos_module' :
+                case 'dokeos_module':
                     if (isset ($_GET['view']) && $_GET['view'] == 'build') {
                         $return .= $this->display_manipulate($item_id, $row['item_type']);
                         $return .= $this->display_item_form($row['item_type'], get_lang('EditCurrentModule') . ' :', 'edit', $item_id, $row);
@@ -6420,23 +6425,23 @@ class learnpath
                         $return .= $this->display_item_small_form($row['item_type'], get_lang('EditCurrentModule') . ' :', $row);
                     }
                     break;
-                case TOOL_QUIZ :
+                case TOOL_QUIZ:
                     $return .= $this->display_manipulate($item_id, $row['item_type']);
                     $return .= $this->display_quiz_form('edit', $item_id, $row);
                     break;
-                case TOOL_HOTPOTATOES :
+                case TOOL_HOTPOTATOES:
                     $return .= $this->display_manipulate($item_id, $row['item_type']);
                     $return .= $this->display_hotpotatoes_form('edit', $item_id, $row);
                     break;
-                case TOOL_STUDENTPUBLICATION :
+                case TOOL_STUDENTPUBLICATION:
                     $return .= $this->display_manipulate($item_id, $row['item_type']);
                     $return .= $this->display_student_publication_form('edit', $item_id, $row);
                     break;
-                case TOOL_FORUM :
+                case TOOL_FORUM:
                     $return .= $this->display_manipulate($item_id, $row['item_type']);
                     $return .= $this->display_forum_form('edit', $item_id, $row);
                     break;
-                case TOOL_THREAD :
+                case TOOL_THREAD:
                     $return .= $this->display_manipulate($item_id, $row['item_type']);
                     $return .= $this->display_thread_form('edit', $item_id, $row);
                     break;

+ 1 - 1
main/newscorm/lp_view.php

@@ -272,7 +272,7 @@ if (
         $time_start_date = api_strtotime($row_dates['start_date'], 'UTC');
         $time_exe_date = api_strtotime($row_dates['exe_date'], 'UTC');
 
-        $mytime = ((int) $time_exe_date - (int) $time_start_date);
+        $mytime = (int) $time_exe_date - (int) $time_start_date;
         $score = (float) $row_dates['exe_result'];
         $max_score = (float) $row_dates['exe_weighting'];
 

+ 5 - 4
main/template/default/auth/courses_categories.php

@@ -190,7 +190,6 @@ if ($showCourses && $action != 'display_sessions') {
     if (!empty($search_term)) {
         echo "<p><strong>".get_lang('SearchResultsFor')." ".Security::remove_XSS($_POST['search_term'])."</strong><br />";
     }
-    $listCategory = CourseManager::getCategoriesList();
     
     $ajax_url = api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=add_course_vote';
     $user_id = api_get_user_id();
@@ -222,7 +221,7 @@ if ($showCourses && $action != 'display_sessions') {
             $html .= '<div class="col-xs-6 col-sm-6 col-md-3"><div class="items">';
 
             // display thumbnail
-            $html .= returnThumbnail($course, $listCategory[$course['category']]);
+            $html .= returnThumbnail($course);
 
             // display course title and button bloc
             $html .= '<div class="description">';
@@ -289,10 +288,9 @@ echo $cataloguePagination;
 /**
  * Display the course catalog image of a course
  * @param array $course
- * @param string $categoryTitle
  * @return string HTML string
  */
-function returnThumbnail($course, $categoryTitle=null)
+function returnThumbnail($course)
 {
     $html = '';
     $title = cut($course['title'], 70);
@@ -308,7 +306,10 @@ function returnThumbnail($course, $categoryTitle=null)
     
     $html .= '<div class="image">';
     $html .= '<img class="img-responsive" src="'.$course_medium_image.'" alt="'.api_htmlentities($title).'"/>';
+    $categoryTitle = $course['category'];
     if (!empty($categoryTitle)) {
+        $listCategory = CourseManager::getCategoriesList();
+        $categoryTitle = $listCategory[$categoryTitle];
         $html .= '<span class="category">'. $categoryTitle.'</span>';
         $html .= '<div class="cribbon"></div>';
     }

+ 2 - 2
main/template/default/layout/login_form.tpl

@@ -16,11 +16,11 @@
         {% if "allow_lostpassword" | get_setting == 'true' or "allow_registration" | get_setting == 'true' %}
             <ul class="nav nav-pills nav-stacked">
                 {% if "allow_registration" | get_setting != 'false' %}
-                    <li><a href="main/auth/inscription.php"> {{ 'SignUp' | get_lang }} </a></li>
+                    <li><a href="{{ _p.web_main }}auth/inscription.php"> {{ 'SignUp' | get_lang }} </a></li>
                 {% endif %}
 
                 {% if "allow_lostpassword" | get_setting == 'true' %}
-                    <li><a href="main/auth/lostPassword.php"> {{ 'LostPassword' | get_lang }} </a></li>
+                    <li><a href="{{ _p.web_main }}auth/lostPassword.php"> {{ 'LostPassword' | get_lang }} </a></li>
                 {% endif %}
             </ul>
         {% endif %}

+ 16 - 0
main/template/default/learnpath/view.tpl

@@ -269,6 +269,22 @@
                     {% endif %}
                 })();
             {% endif %}
+
+            $('iframe#content_id')
+                .on('load', function () {
+                    $.frameReady(function () {
+                    }, 'top.content_name', {
+                        load: [
+                            {type: 'script', id: '_fr1', src: '{{ _p.web }}web/assets/jquery/dist/jquery.min.js'},
+                            {type: 'script', id: '_fr7', src: '{{ _p.web }}web/assets/MathJax/MathJax.js?config=AM_HTMLorMML'},
+                            {type: 'script', id: '_fr4', src: '{{ _p.web }}web/assets/jquery-ui/jquery-ui.min.js'},
+                            {type: 'stylesheet', id: '_fr5', src: '{{ _p.web }}web/assets/jquery-ui/themes/smoothness/jquery-ui.min.css'},
+                            {type: 'stylesheet', id: '_fr6', src: '{{ _p.web }}web/assets/jquery-ui/themes/smoothness/theme.css'},
+                            {type: 'script', id: '_fr2', src: '{{ _p.web_lib }}javascript/jquery.highlight.js'},
+                            {type: 'script', id: '_fr3', src: '{{ _p.web_main }}glossary/glossary.js.php'}
+                        ]
+                    });
+                });
         });
 
         $(window).on('resize', function () {

+ 3 - 5
main/template/rainbow/layout/layout_2_col.tpl

@@ -41,7 +41,7 @@
                             <li><i class="fa fa-user fa-4x icon-color" aria-hidden="true"></i></li>
                             <li>
                                 <h2 class="number">450+</h2>
-                                <p class="text">Les utilisateurs enregistrés</p>
+                                <p class="text">{{ "RegisteredUsers"|get_lang }}</p>
                             </li>
                         </ul>
                     </div>
@@ -50,7 +50,7 @@
                             <li><i class="fa fa-book fa-4x icon-color" aria-hidden="true"></i></li>
                             <li>
                                 <h2 class="number">30</h2>
-                                <p class="text">Les cours ouverts</p>
+                                <p class="text">{{ "OpenCourses"|get_lang }}</p>
                             </li>
                         </ul>
                     </div>
@@ -59,7 +59,7 @@
                             <li><i class="fa fa-signal fa-4x icon-color" aria-hidden="true"></i></li>
                             <li>
                                 <h2 class="number">300+</h2>
-                                <p class="text">Les diplomés</p>
+                                <p class="text">{{ "Certificates"|get_lang }}</p>
                             </li>
                         </ul>
                     </div>
@@ -128,8 +128,6 @@
                 {{ course_category_block }}
             </section>
         {% endif %}
-
-
     </div>
 </div>
 </div>

+ 23 - 13
main/template/rainbow/layout/menu.tpl

@@ -9,15 +9,25 @@
                 <span class="icon-bar"></span>
             </button>
         </div>
+        
         <!-- Collect the nav links, forms, and other content for toggling -->
         <div class="collapse navbar-collapse" id="menuone">
             <ul class="nav navbar-nav">
-                <li class="item-menu menu-one"><a href="{{ _p.web }}">Accueli</a></li>
-
-
-                <li class="item-menu menu-two dropdown">
-                    <a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="true">
-                        FAQ
+                {% if _u.logged == 1 %}
+                    {% for items in menu.possible_tabs %}     
+                        {% if items.key != 'profile' and items.key != 'dashboard' and items.key != 'my-space' and items.key != 'admin' %}
+                        {% set counter = counter + 1 %}
+                            <li class="item-menu menu-{{ counter }} {{ items.key }} {{ items.current }}"><a href="{{ items.url }}">{{ items.title }}</a></li>
+                        {% endif %}
+                    {% endfor %}
+                {% endif %}
+                {% if _u.logged == 0 %}
+                    <li class="item-menu menu-1"><a href="{{ _p.web }}">{{ "CampusHomepage"|get_lang }}</a></li>
+                {% endif %}
+                    <li class="item-menu menu-2"><a href="{{ _p.web }}web/app_dev.php/faq">{{ "FAQ"|get_lang }}</a></li>
+                <!-- <li class="item-menu menu-2 dropdown">
+                    <a href="{{ _p.web }}web/app_dev.php/faq" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="true">
+                        {{ "FAQ"|get_lang }}
                         <b class="caret"></b>
                     </a>
                     <ul class="dropdown-menu menu_level_1" role="menu">
@@ -28,12 +38,13 @@
                             </a>
                          </li>
                     {% endfor %}
-                    </ul>
-                </li>
-
-                <li class="item-menu menu-three"><a href="#">Inscription</a></li>
-                <li class="item-menu menu-four"><a href="#">Démo</a></li>
-                <li class="item-menu menu-five"><a href="#">Contact</a></li>
+                    </ul> 
+                </li> -->
+                {% if _u.logged == 0 %}
+                    <li class="item-menu menu-3"><a href="{{ _p.web }}main/auth/inscription.php">{{ "Subscription"|get_lang }}</a></li>
+                    <li class="item-menu menu-4"><a href="#">{{ "Demo"|get_lang }}</a></li>
+                    <li class="item-menu menu-5"><a href="#">{{ "Contact"|get_lang }}</a></li>
+                {% endif %}
             </ul>
            {% if _u.logged == 1 %}
            <ul class="nav navbar-nav navbar-right">
@@ -50,7 +61,6 @@
                             {{ profile_link }}
                             {{ message_link }}
                             {{ certificate_link }}
-                            {{ menu }}
                         </li>
                     </ul>
                 </li>

+ 2 - 7
main/template/rainbow/layout/show_header.tpl

@@ -1,17 +1,12 @@
 {% include template ~ "/layout/main_header.tpl" %}
-{#
-    show_header and show_footer templates are only called when using the
-    Display::display_header and Display::display_footer
-    for backward compatibility we suppose that the default layout is one column
-    which means using a div with class span12
-#}
+
 {% if show_header == true %}
     {% if plugin_content_top is not null %}
         <div id="plugin_content_top" class="col-md-12">
             {{ plugin_content_top }}
         </div>
     {% endif %}
-    <div class="col-md-12">
+    <div class="container">
         {% include template ~ "/layout/page_body.tpl" %}
         <section id="main_content">
 {% endif %}

+ 16 - 0
main/template/rainbow/learnpath/view.tpl

@@ -269,6 +269,22 @@
                     {% endif %}
                 })();
             {% endif %}
+
+            $('iframe#content_id')
+                .on('load', function () {
+                    $.frameReady(function () {
+                    }, 'top.content_name', {
+                        load: [
+                            {type: 'script', id: '_fr1', src: '{{ _p.web }}web/assets/jquery/dist/jquery.min.js'},
+                            {type: 'script', id: '_fr7', src: '{{ _p.web }}web/assets/MathJax/MathJax.js?config=AM_HTMLorMML'},
+                            {type: 'script', id: '_fr4', src: '{{ _p.web }}web/assets/jquery-ui/jquery-ui.min.js'},
+                            {type: 'stylesheet', id: '_fr5', src: '{{ _p.web }}web/assets/jquery-ui/themes/smoothness/jquery-ui.min.css'},
+                            {type: 'stylesheet', id: '_fr6', src: '{{ _p.web }}web/assets/jquery-ui/themes/smoothness/theme.css'},
+                            {type: 'script', id: '_fr2', src: '{{ _p.web_lib }}javascript/jquery.highlight.js'},
+                            {type: 'script', id: '_fr3', src: '{{ _p.web_main }}glossary/glossary.js.php'}
+                        ]
+                    });
+                });
         });
 
         $(window).on('resize', function () {

+ 16 - 11
main/webservices/cm_webservice_forum.php

@@ -234,6 +234,7 @@ class WSCMForum extends WSCM
     {
         if($this->verifyUserPass($username, $password) == "valid")
         {
+            $em = Database::getManager();
             $course_db = CourseManager::get_course_information($course_code);
 
             $user_id = UserManager::get_user_id_from_username($username);
@@ -251,19 +252,23 @@ class WSCMForum extends WSCM
             $title = htmlentities($title);
             $content = htmlentities($content);
 
-            $sql="INSERT INTO $table_posts (post_title, post_text, thread_id, forum_id, poster_id, post_date, post_notification, post_parent_id, visible)
-                            VALUES ('".Database::escape_string($title)."',
-                                            '".Database::escape_string(isset($content) ? (api_html_entity_decode($content)) : null)."',
-                                            '".Database::escape_string($thread_id)."',
-                                            '".Database::escape_string($forum_id)."',
-                                            '".Database::escape_string($user_id)."',
-                                            '".Database::escape_string($post_date)."',
-                                            '".Database::escape_string(isset($post_notification)?$post_notification:null)."',
-                                            '".Database::escape_string(isset($my_post)?$my_post:null)."',
-                                            '".Database::escape_string($visible)."')";
+            $postDate = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
 
+            $post = new \Chamilo\CourseBundle\Entity\CForumPost();
+            $post
+                ->setPostTitle($title)
+                ->setPostText(isset($content) ? (api_html_entity_decode($content)) : null)
+                ->setThreadId($thread_id)
+                ->setForumId($forum_id)
+                ->setPosterId($user_id)
+                ->setPostDate($postDate)
+                ->setPostNotification(isset($post_notification) ? $post_notification : null)
+                ->setPostParentId(isset($my_post) ? $my_post : null)
+                ->setVisible($visible);
+
+            $em->persist($post);
+            $em->flush();
 
-            $result=Database::query($sql);
             return "Post enviado!";
 //return $sql;
 

+ 3 - 2
src/Chamilo/CoreBundle/Menu/NavBuilder.php

@@ -121,7 +121,7 @@ class NavBuilder extends ContainerAware
                         'route' => 'main',
                         'routeParameters' => array(
                             'name' => 'social/home.php',
-                        ),
+                        )
                     )
                 );
             }
@@ -151,6 +151,7 @@ class NavBuilder extends ContainerAware
         }
 
         // Getting site information
+
         $site = $this->container->get('sonata.page.site.selector');
         $host = $site->getRequestContext()->getHost();
         $siteManager = $this->container->get('sonata.page.manager.site');
@@ -259,7 +260,7 @@ class NavBuilder extends ContainerAware
                         'uid' => $user->getId(),
                     ),
                     'query' => '1',
-                    'icon' => 'fa fa-sign-out',
+                    'icon' => 'fa fa-sign-out'
                 )
             );
 

+ 1 - 1
src/Chamilo/PageBundle/Resources/views/latest.html.twig

@@ -1,5 +1,5 @@
 <div class="container section-notice">
-    <h2 class="section-title">Nouveau</h2>
+    <h2 class="section-title">{{ "LatestPublications"|get_lang }}</h2>
     <div class="row">
         {% for page in pages %}
             <div class="col-md-4">

+ 17 - 39
src/Chamilo/ThemeBundle/Resources/views/Layout/base-layout.html.twig

@@ -46,13 +46,14 @@
     {#{% endstylesheets %}#}
 
     {# Chamilo theme #}
-    {% set theme = 'chamilo' %}
+    {% set theme = 'rainbow' %}
+    
 
     {% set bug_notification_link = '' %}
     {% set help_content = '' %}
     {% set header_extra_content = '' %}
 
-    {% set template = 'default' %}
+    {% set template = 'rainbow' %}
     {% set notification_menu = '' %}
     {% set accessibility = '' %}
     {% set containerClass = '' %}
@@ -140,40 +141,17 @@
                 </div>
             {% endif %}
             <div class="row">
-                <div class="col-lg-3">
-                    <div class="logo">
-                        {#<a href="{{ url('index') }}">#}
-                        <img src="{{ asset('css/themes/'~ theme ~'/images/header-logo.png') }}"/>
-                        {#</a>#}
-                    </div>
-                </div>
-                <div class="col-lg-9">
-                    <div class="col-sm-4">
-                        {% if plugin_header_left is not null %}
-                            <div id="plugin_header_left">
-                                {{ plugin_header_left }}
-                            </div>
-                        {% endif %}
-                    </div>
-                    <div class="col-sm-4">
-                        {% if plugin_header_center is not null %}
-                            <div id="plugin_header_center">
-                                {{ plugin_header_center }}
-                            </div>
-                        {% endif %}
-                    </div>
-                    <div class="col-sm-4">
-                        {% if plugin_header_right is not null %}
-                            <div id="plugin_header_right">
-                                {{ plugin_header_right }}
-                            </div>
-                        {% endif %}
-                        <div class="section-notifications">
-                            <ul id="notifications" class="nav nav-pills pull-right">
-                                {{ notification_menu }}
-                            </ul>
+                <div class="col-xs-6 col-md-4"></div>
+                <div class="col-xs-6 col-md-4">
+                    {% if plugin_header_center is not null %}
+                        <div id="plugin_header_center">
+                            {{ plugin_header_center }}
                         </div>
-                        {{ accessibility }}
+                    {% endif %}
+                </div>
+                <div class="col-xs-6 col-md-4">
+                    <div class="logo pull-right">
+                        <img src="{{ asset('css/themes/'~ theme ~'/images/header-logo.png') }}"/>
                     </div>
                 </div>
             </div>
@@ -182,14 +160,14 @@
         <section id="menu-bar">
             {# menu #}
             {% block menu %}
-                <nav class="navbar navbar-default">
-                    <div class="container">
+                <div class="container">
+                    <nav class="navbar navbar-default">
                         <div class="collapse navbar-collapse">
                         {{ mopa_bootstrap_menu('ChamiloCoreBundle:NavBuilder:leftMenu', {'automenu': 'navbar', 'stacked' : false}) }}
                         {{ mopa_bootstrap_menu('ChamiloCoreBundle:NavBuilder:rightMenu', {'automenu': 'navbar', 'pull-right' : true} ) }}
                         </div>
-                    </div>
-                </nav>
+                    </nav>
+                </div>
                 {#{% include "@template_style/layout/menu.html.twig" %}#}
             {% endblock %}
         </section>

+ 23 - 2
tests/features/forum.feature

@@ -23,9 +23,30 @@ Feature: Forum tool
     Then I should see "The forum has been added"
 
   Scenario: Create a forum thread
-    Given I am on "/main/forum/newthread.php?forum=5"
+    Given I am on "/main/forum/newthread.php?forum=1"
     When I fill in the following:
       | post_title | Thread One                                     |
       | post_text  | This is a the first thread in a forum for test |
     And I press "SubmitPost"
-    Then I should see "The new thread has been added"
+    Then I should see "The new thread has been added"
+
+  Scenario: Reply to forum message
+    Given I am on "/main/forum/viewthread.php?forum=1&thread=1"
+    When I follow "reply-to-1"
+    And I fill in the following:
+      | post_text | This is a reply to the first message for test |
+    And I press "SubmitPost"
+    Then I should see "The reply has been added"
+
+  Scenario: Delete a forum message
+    Given I am on "/main/forum/viewthread.php?forum=1&thread=1"
+    When I follow "delete-post-2"
+    Then I should see "Post has been deleted"
+
+# This test is commented because to quote a message is necessary load HTML code inside of textarea.
+# And this breaks the page for Behat
+#  Scenario: Quote a forum message
+#    Given I am on "/main/forum/viewthread.php?forum=1&thread=1"
+#    When I follow "quote-1"
+#    And I press "SubmitPost"
+#    Then I should see "The reply has been added"