Julio 8 gadi atpakaļ
vecāks
revīzija
9354c1a030
100 mainītis faili ar 1641 papildinājumiem un 1128 dzēšanām
  1. 36 0
      app/Migrations/Schema/V111/Version20160705190000.php
  2. 36 0
      app/Migrations/Schema/V111/Version20160705192000.php
  3. 36 0
      app/Migrations/Schema/V111/Version20160706145000.php
  4. 19 0
      app/Resources/public/css/base.css
  5. 1 2
      app/config/mail.conf.dist.php
  6. 1 0
      documentation/installation_guide.html
  7. 65 0
      main/admin/email_tester.php
  8. 38 27
      main/admin/index.php
  9. 20 1
      main/admin/skill_create.php
  10. 19 1
      main/admin/skill_edit.php
  11. 23 0
      main/admin/skill_list.php
  12. 1 1
      main/auth/courses.php
  13. 1 1
      main/chat/chat.php
  14. 2 2
      main/course_progress/index.php
  15. 2 7
      main/course_progress/thematic.php
  16. 36 2
      main/course_progress/thematic_advance.php
  17. 7 54
      main/course_progress/thematic_controller.php
  18. 3 3
      main/document/record_audio.php
  19. 281 269
      main/exercise/export/scorm/scorm_classes.php
  20. BIN
      main/img/icons/32/dropbox.png
  21. BIN
      main/img/icons/32/folder_document.png
  22. BIN
      main/img/icons/32/glossary.png
  23. BIN
      main/img/icons/32/link.png
  24. BIN
      main/img/icons/32/links.png
  25. BIN
      main/img/icons/32/members.png
  26. BIN
      main/img/icons/32/notebook.png
  27. BIN
      main/img/icons/32/valves.png
  28. BIN
      main/img/icons/32/works.png
  29. 2 2
      main/inc/ajax/model.ajax.php
  30. 1 1
      main/inc/ajax/work.ajax.php
  31. 1 1
      main/inc/lib/agenda.lib.php
  32. 11 7
      main/inc/lib/course.lib.php
  33. 5 4
      main/inc/lib/course_home.lib.php
  34. 1 1
      main/inc/lib/exercise.lib.php
  35. 40 2
      main/inc/lib/extra_field.lib.php
  36. 1 0
      main/inc/lib/extra_field_value.lib.php
  37. 2 2
      main/inc/lib/login.lib.php
  38. 231 165
      main/inc/lib/message.lib.php
  39. 9 3
      main/inc/lib/sessionmanager.lib.php
  40. 1 0
      main/inc/lib/statistics.lib.php
  41. 10 5
      main/inc/lib/template.lib.php
  42. 3 3
      main/inc/lib/usermanager.lib.php
  43. 2 2
      main/inc/lib/userportal.lib.php
  44. 4 0
      main/install/data.sql
  45. 0 1
      main/lang/arabic/trad4all.inc.php
  46. 0 1
      main/lang/asturian/trad4all.inc.php
  47. 0 1
      main/lang/basque/trad4all.inc.php
  48. 107 1
      main/lang/brazilian/trad4all.inc.php
  49. 0 1
      main/lang/bulgarian/trad4all.inc.php
  50. 0 1
      main/lang/catalan/trad4all.inc.php
  51. 0 1
      main/lang/croatian/trad4all.inc.php
  52. 0 1
      main/lang/danish/trad4all.inc.php
  53. 0 1
      main/lang/dutch/trad4all.inc.php
  54. 115 112
      main/lang/english/trad4all.inc.php
  55. 0 1
      main/lang/finnish/trad4all.inc.php
  56. 6 2
      main/lang/french/trad4all.inc.php
  57. 0 1
      main/lang/galician/trad4all.inc.php
  58. 0 1
      main/lang/german/trad4all.inc.php
  59. 0 1
      main/lang/greek/trad4all.inc.php
  60. 0 1
      main/lang/hungarian/trad4all.inc.php
  61. 0 1
      main/lang/indonesian/trad4all.inc.php
  62. 0 1
      main/lang/italian/trad4all.inc.php
  63. 0 1
      main/lang/japanese/trad4all.inc.php
  64. 0 1
      main/lang/latvian/trad4all.inc.php
  65. 0 1
      main/lang/lithuanian/trad4all.inc.php
  66. 0 1
      main/lang/macedonian/trad4all.inc.php
  67. 0 1
      main/lang/polish/trad4all.inc.php
  68. 0 1
      main/lang/portuguese/trad4all.inc.php
  69. 0 1
      main/lang/quechua_cusco/trad4all.inc.php
  70. 0 1
      main/lang/romanian/trad4all.inc.php
  71. 0 1
      main/lang/russian/trad4all.inc.php
  72. 0 1
      main/lang/simpl_chinese/trad4all.inc.php
  73. 0 1
      main/lang/slovak/trad4all.inc.php
  74. 41 1
      main/lang/slovenian/trad4all.inc.php
  75. 6 3
      main/lang/spanish/trad4all.inc.php
  76. 0 1
      main/lang/spanish_latin/trad4all.inc.php
  77. 0 1
      main/lang/tagalog/trad4all.inc.php
  78. 0 1
      main/lang/trad_chinese/trad4all.inc.php
  79. 16 18
      main/lp/learnpath.class.php
  80. 11 1
      main/lp/learnpathItem.class.php
  81. 13 0
      main/lp/lp_add.php
  82. 7 4
      main/lp/lp_controller.php
  83. 222 293
      main/lp/packaging/assets/api_wrapper.js
  84. 4 0
      main/lp/packaging/assets/bootstrap/bootstrap.min.css
  85. 1 0
      main/lp/packaging/assets/jquery/jquery.min.js
  86. 10 1
      main/mySpace/session.php
  87. 1 7
      main/mySpace/works_in_session_report.php
  88. 19 0
      main/template/default/admin/email_tester.tpl
  89. 13 12
      main/template/default/admin/teacher_time_report.tpl
  90. 1 1
      main/template/default/auth/session_catalog.tpl
  91. 1 1
      main/template/default/document/record_audio.tpl
  92. 1 2
      main/template/default/layout/course_navigation.tpl
  93. 1 1
      main/template/default/layout/head.tpl
  94. 15 0
      main/template/default/layout/page_footer.tpl
  95. 24 1
      main/template/default/skill/list.tpl
  96. 24 21
      main/template/default/social/avatar_block.tpl
  97. 2 16
      main/work/upload.php
  98. 14 22
      main/work/work_list.php
  99. 14 11
      plugin/share_buttons/index.php
  100. 1 0
      src/Chamilo/CoreBundle/Entity/ExtraField.php

+ 36 - 0
app/Migrations/Schema/V111/Version20160705190000.php

@@ -0,0 +1,36 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V111;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\Types\Type;
+
+/**
+ * Class Version20160705190000
+ * Add accumulate scorm time to c_lp table
+ * @package Application\Migrations\Schema\V111
+ */
+class Version20160705190000 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     * @throws \Doctrine\DBAL\DBALException
+     * @throws \Doctrine\DBAL\Schema\SchemaException
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql("ALTER TABLE c_lp ADD COLUMN accumulate_scorm_time VARCHAR(5)");
+    }
+
+    /**
+     * @param Schema $schema
+     * @throws \Doctrine\DBAL\DBALException
+     * @throws \Doctrine\DBAL\Schema\SchemaException
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql("ALTER TABLE c_lp DROP COLUMN accumulate_scorm_time");
+    }
+}

+ 36 - 0
app/Migrations/Schema/V111/Version20160705192000.php

@@ -0,0 +1,36 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V111;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\Types\Type;
+
+/**
+ * Class Version20160705192000
+ * Add accumulate scorm time to c_lp table
+ * @package Application\Migrations\Schema\V111
+ */
+class Version20160705192000 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     * @throws \Doctrine\DBAL\DBALException
+     * @throws \Doctrine\DBAL\Schema\SchemaException
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql("UPDATE c_lp SET accumulate_scorm_time = (SELECT selected_value FROM settings_current WHERE variable = 'scorm_cumulative_session_time'");
+    }
+
+    /**
+     * @param Schema $schema
+     * @throws \Doctrine\DBAL\DBALException
+     * @throws \Doctrine\DBAL\Schema\SchemaException
+     */
+    public function down(Schema $schema)
+    {
+
+    }
+}

+ 36 - 0
app/Migrations/Schema/V111/Version20160706145000.php

@@ -0,0 +1,36 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V111;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\Types\Type;
+
+/**
+ * Class Version20160706145000
+ * Add tag extra field for skills
+ * @package Application\Migrations\Schema\V111
+ */
+class Version20160706145000 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     * @throws \Doctrine\DBAL\DBALException
+     * @throws \Doctrine\DBAL\Schema\SchemaException
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql("INSERT INTO extra_field (extra_field_type, field_type, variable, display_text, visible, changeable, created_at) VALUES (8, 10, 'tags', 'Tags', 1, 1, NOW())");
+    }
+
+    /**
+     * @param Schema $schema
+     * @throws \Doctrine\DBAL\DBALException
+     * @throws \Doctrine\DBAL\Schema\SchemaException
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql("DELETE FROM extra_field WHERE extra_field_type = 8 AND field_type = 10 AND variable = 'tags'");
+    }
+}

+ 19 - 0
app/Resources/public/css/base.css

@@ -5681,6 +5681,25 @@ footer{
   background: #ffffff;
   width: 100%;
 }
+#toolshortcuts_horizontal{
+    padding-top: 15px;
+    padding-bottom: 15px;
+    margin-bottom: 10px;
+    text-align: center;
+}
+#toolshortcuts_horizontal .items-icon{
+    padding: 0px;
+    display: inline-block;
+}
+#toolshortcuts_horizontal .items-icon img{
+    padding:5px;
+    border-radius:5px;
+    -webkit-box-shadow: 0 1px 3px #C8C8C8;
+    -opera-box-shadow: 0 1px 3px #C8C8C8;
+    -moz-box-shadow: 0 1px 3px #C8C8C8;
+    box-shadow: 0 1px 3px #C8C8C8;
+    border: 1px solid #e6e6e6;
+}
 /* CSS NEW TOP ******************************************************************************/
 /* CSS Responsive */
 @media (min-width: 1025px) and (max-width: 1200px) {

+ 1 - 2
app/config/mail.conf.dist.php

@@ -1,5 +1,4 @@
 <?php
-
 /**
  *	This file holds the configuration settings
  *	for phpmailer Class.
@@ -11,7 +10,7 @@ $platform_email['SMTP_FROM_EMAIL'] = (isset($administrator['email']) ? $administ
 $platform_email['SMTP_FROM_NAME'] = (isset($administrator['name']) ? $administrator['name'] : 'Admin');
 $platform_email['SMTP_HOST'] = 'localhost';
 $platform_email['SMTP_PORT'] = 25;
-$platform_email['SMTP_MAILER'] = IS_WINDOWS_OS ? 'smtp' : 'mail'; // mail, sendmail or smtp
+$platform_email['SMTP_MAILER'] = 'sendmail'; // mail, sendmail or smtp
 $platform_email['SMTP_AUTH'] = 0;
 $platform_email['SMTP_USER'] = '';
 $platform_email['SMTP_PASS'] = '';

+ 1 - 0
documentation/installation_guide.html

@@ -336,6 +336,7 @@ Please note that if you (unluckily) upgraded from any of the 1.9 versions to 1.1
   <li> make sure "AllowOverride All" is present in your Apache configuration, as interpreting the .htaccess files is very important for Chamilo to work (note that the Order-Allow directive has been replaced by "Require all granted" in Apache 2.4)</li>
   <li> point your browser on your portal URL + main/install/</li>
   <li> click&nbsp;<span style="font-style: italic;">Install</span>, then choose <span style="font-style: italic;">Upgrade from 1.9.*</span></li>
+  <li> once your portal is upgraded, clean your app/cache/twig directory: delete all the contents *in* this directory (do NOT remove the directory itself, only its contents!). It will all be re-generated. You can also delete the contents of this directory through the "Archive directory cleanup" option in the "System" box of the Administration page.</li>
 </ul>
 
 <br />

+ 65 - 0
main/admin/email_tester.php

@@ -0,0 +1,65 @@
+<?php
+/* For licensing terms, see /license.txt */
+/**
+ * Index page of the admin tools
+ * @package chamilo.admin
+ */
+// Resetting the course id.
+$cidReset = true;
+
+// Including some necessary chamilo files.
+require_once '../inc/global.inc.php';
+
+api_protect_admin_script();
+
+// Setting the section (for the tabs).
+$this_section = SECTION_PLATFORM_ADMIN;
+$toolName = get_lang('EMailTester');
+
+$form = new FormValidator('email_tester');
+$form->addText('smtp_host', get_lang('Host'), false, ['cols-size' => [3, 8, 1]]);
+$form->addText('smtp_port', get_lang('Port'), false, ['cols-size' => [3, 8, 1]]);
+$form->addText('destination', get_lang('Destination'), true, ['cols-size' => [3, 8, 1]]);
+$form->addText('subject', get_lang('Subject'), true, ['cols-size' => [3, 8, 1]]);
+$form->addHtmlEditor('content', get_lang('Message'), true, false, ['ToolbarSet' => 'Minimal', 'cols-size' => [3, 8, 1]]);
+$form->addButtonSend(get_lang('SendMessage'), 'submit', false, ['cols-size' => [3, 8, 1]]);
+$form->setDefaults([
+    'smtp_host' => $platform_email['SMTP_HOST'],
+    'smtp_port' => $platform_email['SMTP_PORT']
+]);
+$form->freeze(['smtp_host', 'smtp_port']);
+
+$errorsInfo = MessageManager::failedSentMailErrors();
+
+if ($form->validate()) {
+    $values = $form->exportValues();
+
+    $user = api_get_user_entity(api_get_user_id());
+
+    $mailIsSent = api_mail_html(
+        get_lang('UserTestingEMailConf'),
+        $values['destination'],
+        $values['subject'],
+        $values['content'],
+        $user->getCompleteName(),
+        $user->getEmail()
+    );
+
+    Display::addFlash(
+        Display::return_message(get_lang('MailingTestSent'), 'warning')
+    );
+
+    header('Location: ' . api_get_self());
+    exit;
+}
+
+$view = new Template($toolName);
+$view->assign('form', $form->returnForm());
+$view->assign('errors', $errorsInfo);
+
+$template = $view->get_template('admin/email_tester.tpl');
+$content = $view->fetch($template);
+
+$view->assign('header', $toolName);
+$view->assign('content', $content);
+$view->display_one_col_template();

+ 38 - 27
main/admin/index.php

@@ -78,7 +78,7 @@ if (!empty($hook)) {
 }
 
 /* Users */
-$blocks['users']['icon'] = Display::return_icon('members.gif', get_lang('Users'), array(), ICON_SIZE_MEDIUM, false);
+$blocks['users']['icon'] = Display::return_icon('members.png', get_lang('Users'), array(), ICON_SIZE_MEDIUM, false);
 $blocks['users']['label'] = api_ucfirst(get_lang('Users'));
 $blocks['users']['class'] = 'block-admin-users';
 
@@ -350,11 +350,9 @@ if (api_is_platform_admin()) {
 
     $items[] = array('url' => 'archive_cleanup.php', 'label' => get_lang('ArchiveDirCleanup'));
     $items[] = array('url' => 'resource_sequence.php', 'label' => get_lang('ResourcesSequencing'));
+    $items[] = ['url' => 'email_tester.php', 'label' => get_lang('EMailTester')];
 
-    if (isset($_configuration['db_manager_enabled']) &&
-        $_configuration['db_manager_enabled'] == true &&
-        api_is_global_platform_admin()
-    ) {
+    if (api_get_configuration_value('db_manager_enabled') == true && api_is_global_platform_admin()) {
         $host = $_configuration['db_host'];
         $username = $_configuration['db_user'];
         $databaseName = $_configuration['main_database'];
@@ -405,34 +403,47 @@ if (api_is_platform_admin()) {
     /* Plugins */
     global $_plugins;
     if (isset($_plugins['menu_administrator']) && count($_plugins['menu_administrator']) > 0) {
-        $blocks['plugins']['icon'] = Display::return_icon(
-            'plugins.png',
-             get_lang('Plugins'),
-             array(),
-             ICON_SIZE_MEDIUM,
-             false
-        );
-        $blocks['plugins']['label'] = api_ucfirst(get_lang('Plugins'));
-        $blocks['plugins']['class'] = 'block-admin-platform';
-        $blocks['plugins']['editable'] = true;
+        $menuAdministratorItems = [];
 
-        $plugin_obj = new AppPlugin();
-        $items = array();
-        foreach ($_plugins['menu_administrator'] as $plugin_name) {
-            $plugin_info = $plugin_obj->getPluginInfo($plugin_name);
-            $items[] = array(
-                'url' => api_get_path(WEB_CODE_PATH) . '../plugin/'.$plugin_name.'/start.php',
-                'label' => $plugin_info['title']
-            );
+        foreach ($_plugins['menu_administrator'] as $pluginName) {
+            if (!file_exists(api_get_path(SYS_PLUGIN_PATH) . $pluginName . '/start.php')) {
+                continue;
+            }
+
+            $menuAdministratorItems[] = $pluginName;
         }
 
-        $blocks['plugins']['items'] = $items;
-        $blocks['plugins']['extra'] = null;
+        if ($menuAdministratorItems) {
+            $blocks['plugins']['icon'] = Display::return_icon(
+                'plugins.png',
+                get_lang('Plugins'),
+                array(),
+                ICON_SIZE_MEDIUM,
+                false
+            );
+            $blocks['plugins']['label'] = api_ucfirst(get_lang('Plugins'));
+            $blocks['plugins']['class'] = 'block-admin-platform';
+            $blocks['plugins']['editable'] = true;
+
+            $plugin_obj = new AppPlugin();
+            $items = array();
+
+            foreach ($menuAdministratorItems as $plugin_name) {
+                $plugin_info = $plugin_obj->getPluginInfo($plugin_name);
+                $items[] = array(
+                    'url' => api_get_path(WEB_PLUGIN_PATH) . $plugin_name . '/start.php',
+                    'label' => $plugin_info['title']
+                );
+            }
+
+            $blocks['plugins']['items'] = $items;
+            $blocks['plugins']['extra'] = null;
+        }
     }
 
     /* Chamilo.org */
 
-    $blocks['chamilo']['icon'] = Display::return_icon('logo.png', 'Chamilo.org', array(), ICON_SIZE_MEDIUM, false);
+    $blocks['chamilo']['icon'] = Display::return_icon('platform.png', 'Chamilo.org', array(), ICON_SIZE_MEDIUM, false);
     $blocks['chamilo']['label'] = 'Chamilo.org';
     $blocks['chamilo']['class'] = 'block-admin-chamilo';
 
@@ -456,7 +467,7 @@ if (api_is_platform_admin()) {
     $blocks['chamilo']['search_form'] = null;
 
     // Version check
-    $blocks['version_check']['icon'] = Display::return_icon('logo.png', 'Chamilo.org', array(), ICON_SIZE_MEDIUM, false);
+    $blocks['version_check']['icon'] = Display::return_icon('platform.png', 'Chamilo.org', array(), ICON_SIZE_MEDIUM, false);
     $blocks['version_check']['label'] = get_lang('VersionCheck');
     $blocks['version_check']['extra'] = '<div class="admin-block-version"></div>';
     $blocks['version_check']['search_form'] = null;

+ 20 - 1
main/admin/skill_create.php

@@ -70,13 +70,32 @@ $createForm->addSelect(
     ['id' => 'gradebook_id', 'multiple' => 'multiple', 'size' => 10]
 );
 $createForm->addTextarea('description', get_lang('Description'), ['id' => 'description', 'rows' => 7]);
+// EXTRA FIELDS
+$extraField = new ExtraField('skill');
+$returnParams = $extraField->addElements($createForm);
+$jquery_ready_content = $returnParams['jquery_ready_content'];
+
+// the $jquery_ready_content variable collects all functions that will be load in the $(document).ready javascript function
+if (!empty($jquery_ready_content)) {
+    $htmlHeadXtra[] = '<script>
+    $(document).ready(function(){
+        ' . $jquery_ready_content . '
+    });
+    </script>';
+}
+
 $createForm->addButtonSave(get_lang('Save'));
 $createForm->addHidden('id', null);
 
 $createForm->setDefaults($formDefaultValues);
 
 if ($createForm->validate()) {
-    $created = $objSkill->add($createForm->getSubmitValues());
+    $skillValues = $createForm->getSubmitValues();
+    $created = $objSkill->add($skillValues);
+
+    $skillValues['item_id'] = $created;
+    $extraFieldValue = new ExtraFieldValue('skill');
+    $extraFieldValue->saveFieldValues($skillValues);
 
     if ($created) {
         Session::write(

+ 19 - 1
main/admin/skill_edit.php

@@ -74,13 +74,31 @@ $editForm->addSelect(
     ['id' => 'gradebook_id', 'multiple' => 'multiple', 'size' => 10]
 );
 $editForm->addTextarea('description', get_lang('Description'), ['id' => 'description', 'rows' => 7]);
+// EXTRA FIELDS
+$extraField = new ExtraField('skill');
+$returnParams = $extraField->addElements($editForm, $skillId);
+$jquery_ready_content = $returnParams['jquery_ready_content'];
+
+// the $jquery_ready_content variable collects all functions that will be load in the $(document).ready javascript function
+if (!empty($jquery_ready_content)) {
+    $htmlHeadXtra[] = '<script>
+    $(document).ready(function(){
+        ' . $jquery_ready_content . '
+    });
+    </script>';
+}
+
 $editForm->addButtonSave(get_lang('Save'));
 $editForm->addHidden('id', null);
 
 $editForm->setDefaults($skillDefaultInfo);
 
 if ($editForm->validate()) {
-    $updated = $objSkill->edit($editForm->getSubmitValues());
+    $skillValues = $editForm->getSubmitValues();
+    $updated = $objSkill->edit($skillValues);
+
+    $extraFieldValue = new ExtraFieldValue('skill');
+    $extraFieldValue->saveFieldValues($skillValues);
 
     if ($updated) {
         Session::write(

+ 23 - 0
main/admin/skill_list.php

@@ -140,13 +140,36 @@ switch ($action) {
             ['title' => get_lang('BadgesManagement')]
         );
 
+        $extraField = new ExtraField('skill');
+        $arrayVals = $extraField->get_handler_field_info_by_tags('tags');
+        $tags = [];
+        foreach ($arrayVals['options'] as $value) {
+            $tags[] = $value;
+        }
+
         /* View */
         $skill = new Skill();
         $skillList = $skill->get_all();
 
+        $extraFieldSearchTagId = isset($_REQUEST['tag_id']) ? $_REQUEST['tag_id'] : 0;
+
+        if ($extraFieldSearchTagId) {
+            $skills = [];
+
+            $skillsFiltered = $extraField->getAllSkillPerTag($arrayVals['id'], $extraFieldSearchTagId);
+            foreach ($skillList as $index => $value) {
+                if (array_search($index, $skillsFiltered)) {
+                    $skills[$index] = $value;
+                }
+            }
+            $skillList = $skills;
+        }
+
         $tpl = new Template(get_lang('ManageSkills'));
         $tpl->assign('message', $message);
         $tpl->assign('skills', $skillList);
+        $tpl->assign('current_tag_id', $extraFieldSearchTagId);
+        $tpl->assign('tags', $tags);
 
         $content = $tpl->fetch('default/skill/list.tpl');
 

+ 1 - 1
main/auth/courses.php

@@ -216,7 +216,7 @@ switch ($action) {
         if (!$user_can_view_page) {
             api_not_allowed(true);
         }
-        
+
         $courses_controller->courses_categories(
             $action,
             $categoryCode,

+ 1 - 1
main/chat/chat.php

@@ -55,4 +55,4 @@ $template = $view->get_template('chat/chat.tpl');
 $content = $view->fetch($template);
 
 $view->assign('content', $content);
-$view->display_one_col_template();
+$view->display_no_layout_template();

+ 2 - 2
main/course_progress/index.php

@@ -50,8 +50,8 @@ $actions = array(
 );
 
 $action  = 'thematic_details';
-if (isset($_GET['action']) && in_array($_GET['action'],$actions)) {
-    $action = $_GET['action'];
+if (isset($_REQUEST['action']) && in_array($_REQUEST['action'], $actions)) {
+    $action = $_REQUEST['action'];
 }
 
 if (isset($_POST['action']) && $_POST['action'] == 'thematic_delete_select') {

+ 2 - 7
main/course_progress/thematic.php

@@ -190,13 +190,8 @@ if ($action == 'thematic_list') {
                             'index.php?' . api_get_cidreq() . '&' . http_build_query([
                                 'action' => 'thematic_advance_edit',
                                 'thematic_id' => $thematic['id'],
-                                'thematic_advance_id' => $thematic_advance['id'],
-                                'display' => 'no_header'
-                            ]),
-                            [
-                                'class' => 'ajax',
-                                'data-title' => get_lang('EditThematicAdvance')
-                            ]
+                                'thematic_advance_id' => $thematic_advance['id']
+                            ])
                         );
                         $edit_link  .= '<a onclick="javascript:if(!confirm(\''.get_lang('AreYouSureToDelete').'\')) return false;" href="index.php?'.api_get_cidreq().'&action=thematic_advance_delete&thematic_id='.$thematic['id'].'&thematic_advance_id='.$thematic_advance['id'].'">'.
                             Display::return_icon('delete.png',get_lang('Delete'),'',ICON_SIZE_SMALL).'</a></center>';

+ 36 - 2
main/course_progress/thematic_advance.php

@@ -22,8 +22,7 @@ if ($action === 'thematic_advance_add' || $action === 'thematic_advance_edit') {
     $form = new FormValidator(
         'thematic_advance',
         'POST',
-        'index.php?action=thematic_advance_list&thematic_id='.$thematic_id.'&'.api_get_cidreq(
-        )
+        api_get_self() . '?' . api_get_cidreq()
     );
     $form->addElement('header', $header_form);
     //$form->addElement('hidden', 'thematic_advance_token',$token);
@@ -186,6 +185,41 @@ if ($action === 'thematic_advance_add' || $action === 'thematic_advance_edit') {
         }
     }
     $form->setDefaults($default);
+
+    if ($form->validate()) {
+        $values = $form->exportValues();
+
+        $thematic = new Thematic();
+        $thematic->set_thematic_advance_attributes(
+            isset($values['thematic_advance_id']) ? $values['thematic_advance_id']: null,
+            $values['thematic_id'],
+            $values['start_date_type'] == 1 && isset($values['attendance_select']) ? $values['attendance_select'] : 0,
+            $values['content'],
+            $values['start_date_type'] == 2 ? $values['custom_start_date'] : $values['start_date_by_attendance'],
+            $values['duration_in_hours']
+        );
+
+        $affected_rows = $thematic->thematic_advance_save();
+
+        if ($affected_rows) {
+            // get last done thematic advance before move thematic list
+            $last_done_thematic_advance = $thematic->get_last_done_thematic_advance();
+            // update done advances with de current thematic list
+            if (!empty($last_done_thematic_advance)) {
+                $thematic->update_done_thematic_advances($last_done_thematic_advance);
+            }
+        }
+
+        $redirectUrlParams = 'course_progress/index.php?' .  api_get_cidreq() . '&' .
+            http_build_query([
+                'action' => 'thematic_advance_list',
+                'thematic_id' => $values['thematic_id']
+            ]);
+
+        header('Location: ' . api_get_path(WEB_CODE_PATH) . $redirectUrlParams);
+        exit;
+    }
+
     $form->display();
 
 } else if ($action == 'thematic_advance_list') {

+ 7 - 54
main/course_progress/thematic_controller.php

@@ -425,60 +425,13 @@ class ThematicController
                     exit;
                 }
 
-                if ((isset($_REQUEST['start_date_type']) && $_REQUEST['start_date_type'] == 1 && empty($_REQUEST['start_date_by_attendance'])) ||
-                    (!empty($_REQUEST['duration_in_hours']) && !is_numeric($_REQUEST['duration_in_hours']))
-                ) {
-                    if ($_REQUEST['start_date_type'] == 1 && empty($_REQUEST['start_date_by_attendance'])) {
-                        $start_date_error = true;
-                        $data['start_date_error'] = $start_date_error;
-                    }
-
-                    if (!empty($_REQUEST['duration_in_hours']) && !is_numeric($_REQUEST['duration_in_hours'])) {
-                        $duration_error = true;
-                        $data['duration_error'] = $duration_error;
-                    }
-
-                    $data['action'] = $_REQUEST['action'];
-                    $data['thematic_id'] = $_REQUEST['thematic_id'];
-                    $data['attendance_select'] = $attendance_select;
-                    if (isset($_REQUEST['thematic_advance_id'])) {
-                        $data['thematic_advance_id'] = $_REQUEST['thematic_advance_id'];
-                        $thematic_advance_data = $thematic->get_thematic_advance_list($_REQUEST['thematic_advance_id']);
-                        $data['thematic_advance_data'] = $thematic_advance_data;
-                    }
-                } else {
-                    if (api_is_allowed_to_edit(null, true)) {
-                        $thematic_advance_id = isset($_REQUEST['thematic_advance_id']) ? $_REQUEST['thematic_advance_id'] : null;
-                        $thematic_id = $_REQUEST['thematic_id'];
-                        $content = isset($_REQUEST['content']) ? $_REQUEST['content'] : null;
-                        $duration = isset($_REQUEST['duration_in_hours']) ? $_REQUEST['duration_in_hours'] : null;
-                        if (isset($_REQUEST['start_date_type']) && $_REQUEST['start_date_type'] == 2) {
-                            $start_date = $_REQUEST['custom_start_date'];
-                            $attendance_id = 0;
-                        } else {
-                            $start_date = isset($_REQUEST['start_date_by_attendance']) ? $_REQUEST['start_date_by_attendance'] : null;
-                            $attendance_id = isset($_REQUEST['attendance_select']) ? $_REQUEST['attendance_select'] : null;
-                        }
-                        $thematic->set_thematic_advance_attributes(
-                            $thematic_advance_id,
-                            $thematic_id,
-                            $attendance_id,
-                            $content,
-                            $start_date,
-                            $duration
-                        );
-
-                        $affected_rows = $thematic->thematic_advance_save();
-
-                        if ($affected_rows) {
-                            // get last done thematic advance before move thematic list
-                            $last_done_thematic_advance = $thematic->get_last_done_thematic_advance();
-                            // update done advances with de current thematic list
-                            if (!empty($last_done_thematic_advance)) {
-                                $thematic->update_done_thematic_advances($last_done_thematic_advance);
-                            }
-                        }
-                    }
+                $data['action'] = $_REQUEST['action'];
+                $data['thematic_id'] = $_REQUEST['thematic_id'];
+                $data['attendance_select'] = $attendance_select;
+                if (isset($_REQUEST['thematic_advance_id'])) {
+                    $data['thematic_advance_id'] = $_REQUEST['thematic_advance_id'];
+                    $thematic_advance_data = $thematic->get_thematic_advance_list($_REQUEST['thematic_advance_id']);
+                    $data['thematic_advance_data'] = $thematic_advance_data;
                 }
                 break;
             default:

+ 3 - 3
main/document/record_audio.php

@@ -29,9 +29,9 @@ $document_id = $document_data['id'];
 $dir = $document_data['path'];
 
 //make some vars
-$wamidir=$dir;
-if($wamidir=="/"){
-	$wamidir="";
+$wamidir = $dir;
+if ($wamidir == "/") {
+	$wamidir = "";
 }
 $wamiurlplay = api_get_path(WEB_COURSE_PATH).api_get_course_path().'/document'.$wamidir."/";
 $groupId = api_get_group_id();

+ 281 - 269
main/exercise/export/scorm/scorm_classes.php

@@ -21,9 +21,9 @@ class ScormQuestion extends Question
 	/**
 	 * Returns the HTML + JS flow corresponding to one question
 	 *
-	 * @param int The question ID
-	 * @param bool standalone (ie including XML tag, DTD declaration, etc)
-	 * @param int  The JavaScript ID for this question.
+	 * @param int $questionId The question ID
+	 * @param bool $standalone (ie including XML tag, DTD declaration, etc)
+	 * @param int  $js_id The JavaScript ID for this question.
 	 * Due to the nature of interactions, we must have a natural sequence for
 	 * questions in the generated JavaScript.
 	 * @param integer $js_id
@@ -44,7 +44,7 @@ class ScormQuestion extends Question
 		$question->position=$qst->position;
 		$question->picture=$qst->picture;
 		$assessmentItem = new ScormAssessmentItem($question, $standalone);
-		//echo "<pre>".print_r($scorm,1)."</pre>";exit;
+
 		return $assessmentItem->export();
 	}
 
@@ -147,37 +147,46 @@ class ScormQuestion extends Question
 	 */
 	function getQuestionHTML()
 	{
-		$title			= $this->selectTitle();
-		$description	= $this->selectDescription();
+        $title = $this->selectTitle();
+        $description = $this->selectDescription();
 		$cols = 2;
-		$s='<tr>' .
-			'<td colspan="'.$cols.'" id="question_'.$this->id.'_title" valign="middle" style="background-color:#d6d6d6;">' . "\n" .
-			$title.
-			'</td>' . "\n" .
-			'</tr>' . "\n" .
-			'<tr>' . "\n" .
-			'<td valign="top" colspan="'.$cols.'">' . "\n" .
-			'<i>'.$description.'</i>' . "\n" .
-			'</td>' . "\n" .
-			'</tr>' . "\n";
+		$s = '<tr>
+			<td colspan="'.$cols.'" id="question_'.$this->id.'_title" valign="middle" style="background-color:#d6d6d6;">
+			'.$title.'
+			</td>
+			</tr>
+			<tr>
+			<td valign="top" colspan="'.$cols.'">
+			<i>'.$description.'</i>
+			</td>
+			</tr>';
 		return $s;
 	}
 
 	/**
 	 * Return the JavaScript code bound to the question
 	 */
-	function getQuestionJS()
+	public function getQuestionJS()
 	{
-		//$id = $this->id;
-		$w = $this->selectWeighting();
-		$s = 'questions.push('.$this->js_id.');'."\n";
-		if($this->type == FREE_ANSWER or $this->type == HOT_SPOT)
-		{ //put the max score to 0 to avoid discounting the points of
-			//non-exported quiz types in the SCORM
-			$w=0;
-		}
-		$s .= 'questions_score_max['.$this->js_id.'] = '.$w.";\n";
-		return $s;
+		$weight = $this->selectWeighting();
+		$js = 'questions.push('.$this->js_id.');'."\n";
+
+        switch ($this->type) {
+            case ORAL_EXPRESSION:
+                /*$script = file_get_contents(api_get_path(LIBRARY_PATH) . 'javascript/rtc/RecordRTC.js');
+                $script .= file_get_contents(api_get_path(LIBRARY_PATH) . 'wami-recorder/recorder.js');
+                $script .= file_get_contents(api_get_path(LIBRARY_PATH) . 'wami-recorder/gui.js');
+                $js .= $script;*/
+                break;
+           case HOT_SPOT:
+                //put the max score to 0 to avoid discounting the points of
+                //non-exported quiz types in the SCORM
+                $weight = 0;
+                break;
+        }
+        $js .= 'questions_score_max['.$this->js_id.'] = '.$weight.";";
+
+		return $js;
 	}
 }
 
@@ -193,104 +202,102 @@ class ScormAnswerMultipleChoice extends Answer
 	 */
 	function export()
 	{
-		$html = '';
-		$js   = '';
-		$html = '<tr><td colspan="2"><table width="100%">' . "\n";
+		$js = '';
+		$html = '<tr><td colspan="2"><table width="100%">';
 		$type = $this->getQuestionType();
-		$jstmpw = 'questions_answers_ponderation['.$this->questionJSId.'] = new Array();'."\n";
-		$jstmpw .= 'questions_answers_ponderation['.$this->questionJSId.'][0] = 0;'."\n";
+		$jstmpw = 'questions_answers_ponderation['.$this->questionJSId.'] = new Array();';
+		$jstmpw .= 'questions_answers_ponderation['.$this->questionJSId.'][0] = 0;';
+
+        $jstmpw .= 'questions_answers_correct['.$this->questionJSId.'] = new Array();';
 
 		//not sure if we are going to export also the MULTIPLE_ANSWER_COMBINATION to SCORM
 		//if ($type == MCMA  || $type == MULTIPLE_ANSWER_COMBINATION ) {
-		if ($type == MCMA ) {
-			//$questionTypeLang = get_lang('MultipleChoiceMultipleAnswers');
-			$id = 1;
+		if ($type == MCMA) {
+            $id = 1;
 			$jstmp = '';
 			$jstmpc = '';
-			foreach( $this->answer as $i => $answer )
-			{
+            foreach ($this->answer as $i => $answer) {
 				$identifier = 'question_'.$this->questionJSId.'_multiple_'.$i;
 				$html .=
-					'<tr>' . "\n"
-					.	'<td align="center" width="5%">' . "\n"
-					.	'<input name="'.$identifier.'" id="'.$identifier.'" value="'.$i.'" type="checkbox" />' . "\n"
-					.	'</td>' . "\n"
-					.	'<td width="95%">' . "\n"
-					.	'<label for="'.$identifier.'">' . $this->answer[$i] . '</label>' . "\n"
-					.	'</td>' . "\n"
-					.	'</tr>' . "\n\n";
+					'<tr>
+					<td align="center" width="5%">
+					<input name="'.$identifier.'" id="'.$identifier.'" value="'.$i.'" type="checkbox" />
+					</td>
+					<td width="95%">
+					<label for="'.$identifier.'">' . Security::remove_XSS($this->answer[$i]) . '</label>
+					</td>
+					</tr>';
+
 				$jstmp .= $i.',';
-				if($this->correct[$i])
-				{
-					$jstmpc .= $i.',';
-				}
-				$jstmpw .= 'questions_answers_ponderation['.$this->questionJSId.']['.$i.'] = '.$this->weighting[$i].";\n";
+                if ($this->correct[$i]) {
+                    $jstmpc .= $i.',';
+                }
+				$jstmpw .= 'questions_answers_ponderation['.$this->questionJSId.']['.$i.'] = '.$this->weighting[$i].";";
+                $jstmpw .= 'questions_answers_correct['.$this->questionJSId.']['.$i.'] = '.$this->correct[$i].';';
 				$id++;
 			}
 			$js .= 'questions_answers['.$this->questionJSId.'] = new Array('.substr($jstmp,0,-1).');'."\n";
-			$js .= 'questions_answers_correct['.$this->questionJSId.'] = new Array('.substr($jstmpc,0,-1).');'."\n";
-			if ($type == MCMA) {
-				$js .= 'questions_types['.$this->questionJSId.'] = \'mcma\';'."\n";
-			} else {
-				$js .= 'questions_types['.$this->questionJSId.'] = \'exact\';'."\n";
-			}
+            $js .= 'questions_types['.$this->questionJSId.'] = \'mcma\';'."\n";
 			$js .= $jstmpw;
 		} elseif ($type == MULTIPLE_ANSWER_COMBINATION) {
-			//To this items we show the ThisItemIsNotExportable
-			$qId = $this->questionJSId;
-			$js = '';
-			$html = '<tr><td colspan="2"><table width="100%">' . "\n";
-			// some javascript must be added for that kind of questions
-			$html .= '<tr>' . "\n"
-				.	'<td>' . "\n"
-				. '<textarea name="question_'.$qId.'_free" id="question_'.$qId.'_exact" rows="20" cols="100"></textarea>' . "\n"
-				.	'</td>' . "\n"
-				.	'</tr>' . "\n";
-			$html .= '</table></td></tr>' . "\n";
-			// currently the exact answers cannot be displayed, so ignore the textarea
-			$html = '<tr><td colspan="2">'.get_lang('ThisItemIsNotExportable').'</td></tr>';
-			$js .= 'questions_answers['.$this->questionJSId.'] = new Array();'."\n";
-			$js .= 'questions_answers_correct['.$this->questionJSId.'] = new Array();'."\n";
-			$js .= 'questions_types['.$this->questionJSId.'] = \'exact\';'."\n";
-			$jstmpw = 'questions_answers_ponderation['.$this->questionJSId.'] = new Array();'."\n";
-			$jstmpw .= 'questions_answers_ponderation['.$this->questionJSId.'][0] = 0;'."\n";
-			$jstmpw .= 'questions_answers_ponderation['.$this->questionJSId.'][1] = 0;'.";\n";
-			$js .= $jstmpw;
-			return array($js,$html);
+	    	$js = '';
+            $id = 1;
+            $jstmp = '';
+            $jstmpc = '';
+            foreach ($this->answer as $i => $answer) {
+                $identifier = 'question_'.$this->questionJSId.'_exact_'.$i;
+                $html .=
+                    '<tr>
+					<td align="center" width="5%">
+					<input name="'.$identifier.'" id="'.$identifier.'" value="'.$i.'" type="checkbox" />
+					</td>
+					<td width="95%">
+					<label for="'.$identifier.'">' . Security::remove_XSS($this->answer[$i]) . '</label>
+					</td>
+					</tr>';
+
+                $jstmp .= $i.',';
+                if ($this->correct[$i]) {
+                    $jstmpc .= $i.',';
+                }
+                $jstmpw .= 'questions_answers_ponderation['.$this->questionJSId.']['.$i.'] = '.$this->weighting[$i].";";
+                $jstmpw .= 'questions_answers_correct['.$this->questionJSId.']['.$i.'] = '.$this->correct[$i].";";
+                $id++;
+            }
+            $js .= 'questions_answers['.$this->questionJSId.'] = new Array('.substr($jstmp,0,-1).');';
+            $js .= 'questions_types['.$this->questionJSId.'] = "exact";';
+            $js .= $jstmpw;
 		} else {
-			//$questionTypeLang = get_lang('MultipleChoiceUniqueAnswer');
 			$id = 1;
 			$jstmp = '';
 			$jstmpc = '';
-			foreach( $this->answer as $i => $answer )
-			{
-				$identifier = 'question_'.$this->questionJSId.'_unique_'.$i;
+            foreach ($this->answer as $i => $answer) {
+                $identifier = 'question_'.$this->questionJSId.'_unique_'.$i;
 				$identifier_name = 'question_'.$this->questionJSId.'_unique_answer';
 				$html .=
-					'<tr>' . "\n"
-					.	'<td align="center" width="5%">' . "\n"
-					.	'<input name="'.$identifier_name.'" id="'.$identifier.'" value="'.$i.'" type="radio"/>' . "\n"
-					.	'</td>' . "\n"
-					.	'<td width="95%">' . "\n"
-					.	'<label for="'.$identifier.'">' . $this->answer[$i] . '</label>' . "\n"
-					.	'</td>' . "\n"
-					.	'</tr>' . "\n\n";
+					'<tr>
+					<td align="center" width="5%">
+					<input name="'.$identifier_name.'" id="'.$identifier.'" value="'.$i.'" type="checkbox"/>
+					</td>
+					<td width="95%">
+					<label for="'.$identifier.'">' . Security::remove_XSS($this->answer[$i]) . '</label>
+					</td>
+					</tr>';
 				$jstmp .= $i.',';
-				if($this->correct[$i])
-				{
-					$jstmpc .= $i;
-				}
-				$jstmpw .= 'questions_answers_ponderation['.$this->questionJSId.']['.$i.'] = '.$this->weighting[$i].";\n";
+                if ($this->correct[$i]) {
+                    $jstmpc .= $i;
+                }
+				$jstmpw .= 'questions_answers_ponderation['.$this->questionJSId.']['.$i.'] = '.$this->weighting[$i].";";
+                $jstmpw .= 'questions_answers_correct['.$this->questionJSId.']['.$i.'] = '.$this->correct[$i].';';
 				$id++;
 			}
-			$js .= 'questions_answers['.$this->questionJSId.'] = new Array('.substr($jstmp,0,-1).');'."\n";
-			$js .= 'questions_answers_correct['.$this->questionJSId.'] = '.$jstmpc.';'."\n";
-			$js .= 'questions_types['.$this->questionJSId.'] = \'mcua\';'."\n";
+			$js .= 'questions_answers['.$this->questionJSId.'] = new Array('.substr($jstmp,0,-1).');';
+			$js .= 'questions_types['.$this->questionJSId.'] = \'mcua\';';
 			$js .= $jstmpw;
 		}
-		$html .= '</table></td></tr>' . "\n";
+		$html .= '</table></td></tr>';
 
-		return array($js,$html);
+		return array($js, $html);
 	}
 }
 
@@ -314,29 +321,26 @@ class ScormAnswerTrueFalse extends Answer
 		$identifier_true  = $identifier.'_true';
 		$identifier_false = $identifier.'_false';
 		$html .=
-			'<tr>' . "\n"
-			.	'<td align="center" width="5%">' . "\n"
-			.	'<input name="'.$identifier_true.'" id="'.$identifier_true.'" value="'.$this->trueGrade.'" type="radio" '
-			.		'/>' . "\n"
-			.	'</td>' . "\n"
-			.	'<td width="95%">' . "\n"
-			.	'<label for="'.$identifier_true.'">' . get_lang('True') . '</label>' . "\n"
-			.	'</td>' . "\n"
-			.	'</tr>' . "\n\n";
+			'<tr>
+				<td align="center" width="5%">
+				<input name="'.$identifier_true.'" id="'.$identifier_true.'" value="'.$this->trueGrade.'" type="radio" />
+				</td>
+				<td width="95%">
+				<label for="'.$identifier_true.'">' . get_lang('True') . '</label>
+				</td>
+				</tr>';
 		$html .=
-			'<tr>' . "\n"
-			.	'<td align="center" width="5%">' . "\n"
-			.	'<input name="'.$identifier_false.'" id="'.$identifier_false.'" value="'.$this->falseGrade.'" type="radio" '
-			.		'/>' . "\n"
-			.	'</td>' . "\n"
-			.	'<td width="95%">' . "\n"
-			.	'<label for="'.$identifier_false.'">' . get_lang('False') . '</label>' . "\n"
-			.	'</td>' . "\n"
-			.	'</tr>' . "\n\n";
-		$html .= '</table></td></tr>' . "\n";
+			'<tr>
+			<td align="center" width="5%">
+			<input name="'.$identifier_false.'" id="'.$identifier_false.'" value="'.$this->falseGrade.'" type="radio" />
+			</td>
+			<td width="95%">
+			<label for="'.$identifier_false.'">' . get_lang('False') . '</label>
+			</td>
+			</tr></table></td></tr>';
 		$js .= 'questions_answers['.$this->questionJSId.'] = new Array(\'true\',\'false\');'."\n";
 		$js .= 'questions_types['.$this->questionJSId.'] = \'tf\';'."\n";
-		if ($this->response == 'TRUE') {
+		if ($this->response === 'TRUE') {
 			$js .= 'questions_answers_correct['.$this->questionJSId.'] = new Array(\'true\');'."\n";
 		} else {
 			$js .= 'questions_answers_correct['.$this->questionJSId.'] = new Array(\'false\');'."\n";
@@ -346,7 +350,7 @@ class ScormAnswerTrueFalse extends Answer
 		$jstmpw .= 'questions_answers_ponderation['.$this->questionJSId.'][1] = '.$this->weighting[1].";\n";
 		$js .= $jstmpw;
 
-		return array($js,$html);
+		return array($js, $html);
 	}
 }
 
@@ -366,7 +370,7 @@ class ScormAnswerFillInBlanks extends Answer
 	{
 		global $charset;
 		$js = '';
-		$html = '<tr><td colspan="2"><table width="100%">' . "\n";
+		$html = '<tr><td colspan="2"><table width="100%">';
 		// get all enclosed answers
 		$blankList = array();
 		// build replacement
@@ -388,29 +392,33 @@ class ScormAnswerFillInBlanks extends Answer
 		$jstmpw .= 'questions_answers_ponderation['.$this->questionJSId.'][0] = 0;'."\n";
 		$startlocations=api_strpos($answer,'[');
 		$endlocations=api_strpos($answer,']');
-		while($startlocations !== false && $endlocations !== false) {
+		while ($startlocations !== false && $endlocations !== false) {
 			$texstring = api_substr($answer,$startlocations,($endlocations-$startlocations)+1);
-			$answer = api_substr_replace($answer,'<input type="text" name="question_'.$this->questionJSId.'_fib_'.$i.'" id="question_'.$this->questionJSId.'_fib_'.$i.'" size="10" value="" />',$startlocations,($endlocations-$startlocations)+1);
-			$jstmp .= $i.',';
-			$jstmpc .= "'".api_htmlentities(api_substr($texstring,1,-1),ENT_QUOTES,$charset)."',";
-			$my_weight=explode('@',$weights[$i-1]);
-			if (count($my_weight)==2) {
-				$weight_db=$my_weight[0];
-			} else {
-				$weight_db=$my_weight[0];
-			}
+			$answer = api_substr_replace(
+                $answer,
+                '<input type="text" name="question_'.$this->questionJSId.'_fib_'.$i.'" id="question_'.$this->questionJSId.'_fib_'.$i.'" size="10" value="" />',
+                $startlocations,
+                ($endlocations-$startlocations)+1
+            );
+            $jstmp .= $i.',';
+            $jstmpc .= "'".api_htmlentities(api_substr($texstring, 1, -1), ENT_QUOTES, $charset)."',";
+            $my_weight = explode('@', $weights[$i - 1]);
+            if (count($my_weight) == 2) {
+                $weight_db = $my_weight[0];
+            } else {
+                $weight_db = $my_weight[0];
+            }
 			$jstmpw .= 'questions_answers_ponderation['.$this->questionJSId.']['.$i.'] = '.$weight_db.";\n";
 			$i++;
 			$startlocations = api_strpos($answer, '[');
 			$endlocations = api_strpos($answer, ']');
 		}
 
-		$html .= 	'<tr>' . "\n"
-			.	'<td>' . "\n"
-			.	$answer  . "\n"
-			.	'</td>' . "\n"
-			.	'</tr>' . "\n";
-		$html .= '</table></td></tr>' . "\n";
+		$html .= '<tr>
+			<td>
+			'.$answer.'
+			</td>
+			</tr></table></td></tr>';
 		$js .= 'questions_answers['.$this->questionJSId.'] = new Array('.api_substr($jstmp,0,-1).');'."\n";
 		$js .= 'questions_answers_correct['.$this->questionJSId.'] = new Array('.api_substr($jstmpc,0,-1).');'."\n";
 		$js .= 'questions_types['.$this->questionJSId.'] = \'fib\';'."\n";
@@ -433,7 +441,7 @@ class ScormAnswerMatching extends Answer
 	function export()
 	{
 		$js = '';
-		$html = '<tr><td colspan="2"><table width="100%">' . "\n";
+		$html = '<tr><td colspan="2"><table width="100%">';
 		// prepare list of right proposition to allow
 		// - easiest display
 		// - easiest randomisation if needed one day
@@ -466,30 +474,32 @@ class ScormAnswerMatching extends Answer
 				$Select[$answerId]['Reponse'] = $answer;
 				$cpt1++;
 			} else {
-				$s.='<tr>'."\n";
-				$s.='<td width="40%" valign="top">'."\n".'<b>'.$cpt2.'</b>.&nbsp;'.$answer."\n</td>\n";
+				$s.='<tr>';
+				$s.='<td width="40%" valign="top"><b>'.$cpt2.'</b>.&nbsp;'.$answer."</td>";
 				$s.='<td width="20%" align="center">&nbsp;&nbsp;<select name="'.$identifier.$cpt2.'" id="'.$identifier.$cpt2.'">';
 				$s.=' <option value="0">--</option>';
 				// fills the list-box
-				foreach($Select as $key=>$val)
-				{
-					$s.='<option value="'.$key.'">'.$val['Lettre'].'</option>';
-				}  // end foreach()
+                foreach ($Select as $key => $val) {
+                    $s .= '<option value="'.$key.'">'.$val['Lettre'].'</option>';
+                }  // end foreach()
 
-				$s.='</select>&nbsp;&nbsp;</td>'."\n";
+				$s.='</select>&nbsp;&nbsp;</td>';
 				$s.='<td width="40%" valign="top">';
-				if(isset($Select[$cpt2])) $s.='<b>'.$Select[$cpt2]['Lettre'].'.</b> '.$Select[$cpt2]['Reponse'];
-				else $s.='&nbsp;';
-				$s.="</td>\n</tr>\n";
+                if (isset($Select[$cpt2])) {
+                    $s .= '<b>'.$Select[$cpt2]['Lettre'].'.</b> '.$Select[$cpt2]['Reponse'];
+                } else {
+                    $s .= '&nbsp;';
+                }
+				$s.="</td></tr>";
 
 				$jstmpc .= '['.$answerCorrect.','.$cpt2.'],';
 
-				$my_weight=explode('@',$weight);
-				if (count($my_weight)==2) {
-					$weight=$my_weight[0];
-				} else {
-					$weight=$my_weight[0];
-				}
+                $my_weight = explode('@', $weight);
+                if (count($my_weight) == 2) {
+                    $weight = $my_weight[0];
+                } else {
+                    $weight = $my_weight[0];
+                }
 				$jstmpw .= 'questions_answers_ponderation['.$qId.']['.$cpt2.'] = '.$weight.";\n";
 				$cpt2++;
 
@@ -497,14 +507,11 @@ class ScormAnswerMatching extends Answer
 				if ($answerId == $nbrAnswers) {
 					// if there remain answers to be shown on the right side
 					while (isset($Select[$cpt2])) {
-						//$s.='<tr>'."\n";
-						//$s.='<td colspan="2">'."\n";
-						//$s.='<table border="0" cellpadding="0" cellspacing="0" width="100%">'."\n";
-						$s.='<tr>'."\n";
-						$s.='<td width="60%" colspan="2">&nbsp;</td>'."\n";
-						$s.='<td width="40%" valign="top">';
-						$s.='<b>'.$Select[$cpt2]['Lettre'].'.</b> '.$Select[$cpt2]['Reponse'];
-						$s.="</td>\n</tr>\n";
+						$s.= '<tr>';
+						$s.= '<td width="60%" colspan="2">&nbsp;</td>';
+						$s.= '<td width="40%" valign="top">';
+						$s.= '<b>'.$Select[$cpt2]['Lettre'].'.</b> '.$Select[$cpt2]['Reponse'];
+						$s.= "</td></tr>";
 						$cpt2++;
 					}	// end while()
 				}  // end if()
@@ -517,7 +524,7 @@ class ScormAnswerMatching extends Answer
 		$html .= $s;
 		$html .= '</table></td></tr>' . "\n";
 
-		return array($js,$html);
+		return array($js, $html);
 	}
 }
 
@@ -536,26 +543,35 @@ class ScormAnswerFree extends Answer
 	 */
 	function export()
 	{
-		//$qId = $this->questionJSId;
 		$js = '';
-		/*$html = '<tr><td colspan="2"><table width="100%">' . "\n";
-        // some javascript must be added for that kind of questions
-        $html .= '<tr><td>
-                <textarea name="question_'.$qId.'_free" id="question_'.$qId.'_free" rows="20" cols="100"></textarea>
-                </td>
-                </tr>';
-        $html .= '</table></td></tr>';*/
+        $identifier = 'question_'.$this->questionJSId.'_free';
 		// currently the free answers cannot be displayed, so ignore the textarea
-		$html = '<tr><td colspan="2">'.get_lang('ThisItemIsNotExportable').'</td></tr>';
-		$js .= 'questions_answers['.$this->questionJSId.'] = new Array();'."\n";
-		$js .= 'questions_answers_correct['.$this->questionJSId.'] = new Array();'."\n";
-		$js .= 'questions_types['.$this->questionJSId.'] = \'free\';'."\n";
-		$jstmpw = 'questions_answers_ponderation['.$this->questionJSId.'] = new Array();'."\n";
-		$jstmpw .= 'questions_answers_ponderation['.$this->questionJSId.'][0] = 0;'."\n";
-		$jstmpw .= 'questions_answers_ponderation['.$this->questionJSId.'][1] = 0;'.";\n";
+		$html = '<tr><td colspan="2">';
+        $type = $this->getQuestionType();
+
+        if ($type == ORAL_EXPRESSION) {
+            /*
+            $template = new Template('');
+            $template->assign('directory', '/tmp/');
+            $template->assign('user_id', api_get_user_id());
+
+            $layout = $template->get_template('document/record_audio.tpl');
+            $html .= $template->fetch($layout);*/
+
+			$html = '<tr><td colspan="2">'.get_lang('ThisItemIsNotExportable').'</td></tr>';
+
+            return array($js, $html);
+        }
+
+        $html .= '<textarea minlength="20" name="'.$identifier.'" id="'.$identifier.'" ></textarea>';
+        $html .= '</td></tr>';
+		$js .= 'questions_answers['.$this->questionJSId.'] = new Array();';
+		$js .= 'questions_answers_correct['.$this->questionJSId.'] = "";';
+		$js .= 'questions_types['.$this->questionJSId.'] = \'free\';';
+		$jstmpw = 'questions_answers_ponderation['.$this->questionJSId.'] = "0";';
 		$js .= $jstmpw;
 
-		return array($js,$html);
+		return array($js, $html);
 	}
 }
 /**
@@ -571,11 +587,11 @@ class ScormAnswerHotspot extends Answer
 	function get_js_header()
 	{
 		if ($this->standalone) {
-			$header = '<script type="text/javascript" language="javascript">';
+			$header = '<script>';
 			$header .= file_get_contents('../inc/lib/javascript/hotspot/js/hotspot.js');
 			$header .= '</script>';
 			//because this header closes so many times the <script> tag, we have to reopen our own
-			$header .= '<script type="text/javascript" language="javascript">'."\n";
+			$header .= '<script>';
 			$header .= 'questions_answers['.$this->questionJSId.'] = new Array();'."\n";
 			$header .= 'questions_answers_correct['.$this->questionJSId.'] = new Array();'."\n";
 			$header .= 'questions_types['.$this->questionJSId.'] = \'hotspot\';'."\n";
@@ -606,7 +622,7 @@ class ScormAnswerHotspot extends Answer
 	function export()
 	{
 		$js = $this->get_js_header();
-		$html = '<tr><td colspan="2"><table width="100%">' . "\n";
+		$html = '<tr><td colspan="2"><table width="100%">';
 		// some javascript must be added for that kind of questions
 		$html .= '';
 
@@ -614,11 +630,10 @@ class ScormAnswerHotspot extends Answer
 		$nbrAnswers=$this->selectNbrAnswers();
 
 		$answer_list = '<div style="padding: 10px; margin-left: -8px; border: 1px solid #4271b5; height: 448px; width: 200px;"><b>'.get_lang('HotspotZones').'</b><ol>';
-		for($answerId=1;$answerId <= $nbrAnswers;$answerId++)
-		{
-			$answer_list .= '<li>'.$this->selectAnswer($answerId).'</li>';
-		}
-		$answer_list .= '</ol></div>';
+        for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) {
+            $answer_list .= '<li>'.$this->selectAnswer($answerId).'</li>';
+        }
+        $answer_list .= '</ol></div>';
 		$canClick = true;
 		$relPath = api_get_path(REL_PATH);
 		$html .= <<<HTML
@@ -641,15 +656,15 @@ class ScormAnswerHotspot extends Answer
                 </td>
             <tr>
 HTML;
-		$html .= '</table></td></tr>' . "\n";
+		$html .= '</table></td></tr>';
 
 		// currently the free answers cannot be displayed, so ignore the textarea
 		$html = '<tr><td colspan="2">'.get_lang('ThisItemIsNotExportable').'</td></tr>';
-		return array($js,$html);
+
+		return array($js, $html);
 	}
 }
 
-
 /**
  * A SCORM item. It corresponds to a single question.
  * This class allows export from Dokeos SCORM 1.2 format of a single question.
@@ -688,13 +703,13 @@ class ScormAssessmentItem
 	 */
 	function start_page()
 	{
-		global $charset;
-		$head = "";
-		if( $this->standalone)
-		{
-			$head = '<?xml version="1.0" encoding="'.$charset.'" standalone="no"?>' . "\n";
-			$head .= '<html>'."\n";
-		}
+        $head = '';
+        if ($this->standalone) {
+            $charset = 'UTF-8';
+            $head = '<?xml version="1.0" encoding="'.$charset.'" standalone="no"?>';
+            $head .= '<html>';
+        }
+
 		return $head;
 	}
 
@@ -702,7 +717,8 @@ class ScormAssessmentItem
 	 * End the XML flow, closing the </item> tag.
 	 *
 	 */
-	function end_page() {
+	function end_page()
+    {
 		if ($this->standalone) {
 			return '</html>';
 		}
@@ -716,7 +732,7 @@ class ScormAssessmentItem
 	function start_header()
 	{
 		if ($this->standalone) {
-			return '<head>'."\n";
+			return '<head>';
 		}
 
 		return '';
@@ -729,15 +745,16 @@ class ScormAssessmentItem
 	{
 		$css = '';
 		if ($this->standalone) {
-			$css = '<style type="text/css" media="screen, projection">'."\n";
+			$css = '<style type="text/css" media="screen, projection">';
 			$css .= '/*<![CDATA[*/'."\n";
 			$css .= '/*]]>*/'."\n";
 			$css .= '</style>'."\n";
-			$css .= '<style type="text/css" media="print">'."\n";
+			$css .= '<style type="text/css" media="print">';
 			$css .= '/*<![CDATA[*/'."\n";
 			$css .= '/*]]>*/'."\n";
-			$css .= '</style>'."\n";
+			$css .= '</style>';
 		}
+
 		return $css;
 	}
 
@@ -747,7 +764,7 @@ class ScormAssessmentItem
 	function end_header()
 	{
 		if ($this->standalone) {
-			return '</head>'."\n";
+			return '</head>';
 		}
 
 		return '';
@@ -758,21 +775,22 @@ class ScormAssessmentItem
 	 */
 	function start_js()
 	{
+        $js = '<script type="text/javascript" src="assets/api_wrapper.js"></script>';
 		if ($this->standalone) {
-			return '<script type="text/javascript" language="javascript">'."\n";
+			return '<script>';
 		}
-		return '';
+		return $js;
 	}
+
 	/**
 	 * Common JS functions
 	 */
 	function common_js()
 	{
-		$js = file_get_contents('../lp/js/api_wrapper.js');
-		$js .= 'var questions = new Array();' . "\n";
-		$js .= 'var questions_answers = new Array();' . "\n";
-		$js .= 'var questions_answers_correct = new Array();' . "\n";
-		$js .= 'var questions_types = new Array();' . "\n";
+		$js .= 'var questions = new Array();';
+		$js .= 'var questions_answers = new Array();';
+		$js .= 'var questions_answers_correct = new Array();';
+		$js .= 'var questions_types = new Array();';
 		$js .= "\n" .
 			'/**
              * Assigns any event handler to any element
@@ -810,10 +828,10 @@ class ScormAssessmentItem
             }'."\n\n";
 
 		$js .= '';
-		//$js .= 'addEvent(window,\'load\',loadPage,false);'."\n";
-		//$js .= 'addEvent(window,\'unload\',unloadPage,false);'."\n";
 		$js .= 'addEvent(window,\'load\',addListeners,false);'."\n";
-		if($this->standalone){return $js. "\n";}
+        if ($this->standalone) {
+            return $js."\n";
+        }
 		return '';
 	}
 
@@ -823,8 +841,11 @@ class ScormAssessmentItem
 	 */
 	function end_js()
 	{
-		if($this->standalone){return '</script>'. "\n";}
-		return '';
+        if ($this->standalone) {
+            return '</script>';
+        }
+
+        return '';
 	}
 
 	/**
@@ -834,7 +855,7 @@ class ScormAssessmentItem
 	function start_body()
 	{
 		if ($this->standalone) {
-			return '<body>'."\n".'<form id="dokeos_scorm_form" method="post" action="">'."\n";
+			return '<body><form id="dokeos_scorm_form" method="post" action="">';
 		}
 
 		return '';
@@ -847,7 +868,7 @@ class ScormAssessmentItem
 	function end_body()
 	{
 		if ($this->standalone) {
-			return '<br /><input type="button" id="dokeos_scorm_submit" name="dokeos_scorm_submit" value="OK" /></form>'."\n".'</body>'."\n";
+			return '<br /><input class="btn" type="button" id="dokeos_scorm_submit" name="dokeos_scorm_submit" value="OK" /></form></body>';
 		}
 
 		return '';
@@ -863,9 +884,7 @@ class ScormAssessmentItem
 	 */
 	function export()
 	{
-		$js = $html = '';
-		list($js,$html) = $this->question->export();
-		//list($js,$html) = $this->question->answer->export();
+		list($js, $html) = $this->question->export();
 		if ($this->standalone) {
 			$res = $this->start_page()
 				. $this->start_header()
@@ -876,16 +895,12 @@ class ScormAssessmentItem
 				. $this->end_js()
 				. $this->end_header()
 				. $this->start_body()
-				//         .$this->answer->imsExportResponsesDeclaration($this->questionIdent)
-				//         . $this->start_item_body()
-				//           . $this->answer->scormExportResponses($this->questionIdent, $this->question->question, $this->question->description, $this->question->picture)
-				//			.$question
-				. $html
+                . $html
 				. $this->end_body()
 				. $this->end_page();
 			return $res;
 		} else {
-			return array($js,$html);
+			return array($js, $html);
 		}
 	}
 }
@@ -926,13 +941,12 @@ class ScormSection
 		return $xml;
 	}
 
-
 	/**
 	 * Constructor.
 	 * @param Exercise $exe The Exercise instance to export
 	 * @author Amand Tihon <amand@alrj.org>
 	 */
-	function ScormSection($exe)
+	public function __construct($exe)
 	{
 		$this->exercise = $exe;
 	}
@@ -945,9 +959,9 @@ class ScormSection
 	 */
 	function start_page()
 	{
-		global $charset;
-		$head = $foot = "";
-		$head = '<?xml version="1.0" encoding="'.$charset.'" standalone="no"?>' . "\n".'<html>'."\n";
+        $charset = 'UTF-8';
+		$head = '<?xml version="1.0" encoding="'.$charset.'" standalone="no"?><html>';
+
 		return $head;
 	}
 
@@ -965,51 +979,41 @@ class ScormSection
 	 */
 	function start_header()
 	{
-		return '<head>'. "\n";
+		return '<head>';
 	}
 
 	/**
 	 * Print CSS inclusion
 	 */
-	function css()
+	private function css()
 	{
-		$css = '<style type="text/css" media="screen, projection">'."\n";
-		$css .= '/*<![CDATA[*/'."\n";
-		$css .= '/*]]>*/'."\n";
-		$css .= '</style>'."\n";
-		$css .= '<style type="text/css" media="print">'."\n";
-		$css .= '/*<![CDATA[*/'."\n";
-		$css .= '/*]]>*/'."\n";
-		$css .= '</style>'."\n";
-
-		return $css;
+		return '';
 	}
 
 	/**
 	 * End document header
 	 */
-	function end_header()
+    private function end_header()
 	{
-		return '</head>'. "\n";
+		return '</head>';
 	}
 
 	/**
 	 * Start the itemBody
 	 *
 	 */
-	function start_js()
+    private function start_js()
 	{
-		return '<script type="text/javascript" language="javascript">'. "\n";
+		return '<script>';
 	}
 
 	/**
 	 * Common JS functions
 	 */
-	function common_js()
+	public function common_js()
 	{
-		$js = "\n";
-		$js .= file_get_contents('../inc/lib/javascript/hotspot/js/hotspot.js');
-		$js .= file_get_contents('../lp/js/api_wrapper.js');
+		$js = file_get_contents('../inc/lib/javascript/hotspot/js/hotspot.js');
+
 		$js .= 'var questions = new Array();' . "\n";
 		$js .= 'var questions_answers = new Array();' . "\n";
 		$js .= 'var questions_answers_correct = new Array();' . "\n";
@@ -1058,8 +1062,6 @@ class ScormSection
             '."\n";
 
 		$js .= '';
-		//$js .= 'addEvent(window,\'load\',loadPage,false);'."\n";
-		//$js .= 'addEvent(window,\'unload\',unloadPage,false);'."\n";
 		$js .= 'addEvent(window,\'load\',addListeners,false);'."\n";
 		return $js. "\n";
 	}
@@ -1068,8 +1070,9 @@ class ScormSection
 	 * End the itemBody part.
 	 *
 	 */
-	function end_js() {
-		return '</script>'. "\n";
+	function end_js()
+    {
+		return '</script>';
 	}
 
 	/**
@@ -1078,10 +1081,10 @@ class ScormSection
 	 */
 	function start_body()
 	{
-		return '<body>'. "\n".
-		'<h1>'.$this->exercise->selectTitle().'</h1><p>'.$this->exercise->selectDescription()."</p>\n".
-		'<form id="dokeos_scorm_form" method="post" action="">'."\n".
-		'<table width="100%">'."\n";
+		return '<body>'.
+		'<h1>'.$this->exercise->selectTitle().'</h1><p>'.$this->exercise->selectDescription()."</p>".
+		'<form id="dokeos_scorm_form" method="post" action="">'.
+		'<table width="100%">';
 	}
 
 	/**
@@ -1090,7 +1093,7 @@ class ScormSection
 	 */
 	function end_body()
 	{
-		return '</table><br /><input type="button" id="dokeos_scorm_submit" name="dokeos_scorm_submit" value="OK" /></form>'."\n".'</body>'. "\n";
+		return '</table><br /><input class="btn btn-primary" type="button" id="dokeos_scorm_submit" name="dokeos_scorm_submit" value="OK" /></form></body>';
 	}
 
 	/**
@@ -1111,28 +1114,36 @@ class ScormSection
 				. '<!DOCTYPE questestinterop SYSTEM "ims_qtiasiv2p1.dtd">' . "\n";
 		}
 
-		list($js,$html) = $this->export_questions();
-		//list($js,$html) = $this->question->answer->export();
+		list($js, $html) = $this->export_questions();
 		$res = $this->start_page()
 			. $this->start_header()
 			. $this->css()
+            . $this->globalAssets()
 			. $this->start_js()
 			. $this->common_js()
 			. $js
 			. $this->end_js()
 			. $this->end_header()
 			. $this->start_body()
-			//         .$this->answer->imsExportResponsesDeclaration($this->questionIdent)
-			//         . $this->start_item_body()
-			//           . $this->answer->scormExportResponses($this->questionIdent, $this->question->question, $this->question->description, $this->question->picture)
-			//			.$question
-			.$html
+			. $html
 			. $this->end_body()
 			. $this->end_page();
 
 		return $res;
 	}
 
+    /**
+     * @return string
+     */
+    private function globalAssets()
+    {
+        $assets = '<script type="text/javascript" src="assets/jquery/jquery.min.js"></script>';
+        $assets .= '<script type="text/javascript" src="assets/api_wrapper.js"></script>';
+        $assets .= '<link href="assets/bootstrap/bootstrap.min.css" rel="stylesheet" media="screen" type="text/css" />';
+
+        return $assets;
+    }
+
 	/**
 	 * Export the questions, as a succession of <items>
 	 * @author Amand Tihon <amand@alrj.org>
@@ -1142,11 +1153,12 @@ class ScormSection
 		$js = $html = "";
 		$js_id = 0;
 		foreach ($this->exercise->selectQuestionList() as $q) {
-			list($jstmp,$htmltmp)= ScormQuestion::export_question($q, false, $js_id);
+			list($jstmp, $htmltmp)= ScormQuestion::export_question($q, false, $js_id);
 			$js .= $jstmp."\n";
 			$html .= $htmltmp."\n";
 			++$js_id;
 		}
-		return array($js,$html);
+
+		return array($js, $html);
 	}
 }

BIN
main/img/icons/32/dropbox.png


BIN
main/img/icons/32/folder_document.png


BIN
main/img/icons/32/glossary.png


BIN
main/img/icons/32/link.png


BIN
main/img/icons/32/links.png


BIN
main/img/icons/32/members.png


BIN
main/img/icons/32/notebook.png


BIN
main/img/icons/32/valves.png


BIN
main/img/icons/32/works.png


+ 2 - 2
main/inc/ajax/model.ajax.php

@@ -1077,8 +1077,8 @@ switch ($action) {
 
                 $detailButtons = [];
                 $detailButtons[] = Display::url(
-                    Display::return_icon('works.png', get_lang('Works')),
-                    api_get_path(WEB_CODE_PATH) . 'mySpace/works_in_session_report.php'
+                    Display::return_icon('works.png', get_lang('WorksReport')),
+                    api_get_path(WEB_CODE_PATH) . 'mySpace/works_in_session_report.php?session=' . $session['id']
                 );
                 $detailButtons[] = Display::url(
                     Display::return_icon('2rightarrow.png'),

+ 1 - 1
main/inc/ajax/work.ajax.php

@@ -96,7 +96,7 @@ switch ($action) {
             $workInfoParent = get_work_data_by_id($workInfo['parent_id']);
             $resultUpload = uploadWork($workInfoParent, $courseInfo, true, $workInfo);
             if (!$resultUpload) {
-                echo false;
+                echo 'false';
                 break;
             }
             $work_table = Database:: get_course_table(

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

@@ -1594,7 +1594,7 @@ class Agenda
 
         $coachCanEdit = false;
         if (!empty($session_id)) {
-            $coachCanEdit = api_is_coach($session_id, $course_id);
+            $coachCanEdit = api_is_coach($session_id, $course_id) || api_is_platform_admin();
         }
 
         if (Database::num_rows($result)) {

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

@@ -3720,6 +3720,8 @@ class CourseManager
             $course_title_url = '';
             $course_title_url = api_get_path(WEB_COURSE_PATH) . $course_info['path'] . '/index.php?id_session=0';
 
+            $teachers = '';
+
             if (api_get_setting('display_teacher_in_courselist') === 'true') {
                 $teachers = CourseManager::getTeachersFromCourseByCode($course['code']);
             }
@@ -4025,7 +4027,7 @@ class CourseManager
         if (1) {
             $session = '';
             $active = false;
-            if (!empty($course_info['session_name'])) {
+            if (!empty($course_info['id_session'])) {
 
                 // Request for the name of the general coach
                 $sql = 'SELECT lastname, firstname,sc.name
@@ -4039,13 +4041,12 @@ class CourseManager
 
                 $rs = Database::query($sql);
                 $sessioncoach = Database::store_result($rs);
-                $sessioncoach = $sessioncoach[0];
+                $sessioncoach = $sessioncoach ? $sessioncoach[0] : null;
 
-                $session = array();
-                $session['title'] = $course_info['session_name'];
+                $session = api_get_session_info($course_info['id_session']);
                 $session_category_id = CourseManager::get_session_category_id_by_session_id($course_info['id_session']);
                 $session['category'] = $sessioncoach['name'];
-                if ($course_info['access_start_date'] == '0000-00-00') {
+                if ($session['access_start_date'] == '0000-00-00') {
                     //$session['dates'] = get_lang('WithoutTimeLimits');
                     $session['dates'] = '';
                     if (api_get_setting('show_session_coach') === 'true') {
@@ -4054,12 +4055,15 @@ class CourseManager
                     }
                     $active = true;
                 } else {
-                    $session ['dates'] = ' - ' . get_lang('From') . ' ' . $course_info['access_start_date'] . ' ' . get_lang('To') . ' ' . $course_info['access_end_date'];
+                    $session ['dates'] = ' - ' . get_lang('From') . ' ' . $session['access_start_date'] . ' ' . get_lang('To') . ' ' . $session['access_end_date'];
                     if (api_get_setting('show_session_coach') === 'true') {
                         $session['coach'] = get_lang('GeneralCoach') . ': ' . api_get_person_name($sessioncoach['firstname'],
                                 $sessioncoach['lastname']);
                     }
-                    $active = ($date_start <= $now && $date_end >= $now);
+                    $date_start = $session['access_start_date'];
+                    $date_end = $session['access_end_date'];
+
+                    $active = !$date_end ? ($date_start <= $now) : ($date_start <= $now && $date_end >= $now);
                 }
             }
             $user_course_category = '';

+ 5 - 4
main/inc/lib/course_home.lib.php

@@ -1218,26 +1218,27 @@ class CourseHome
                 $style_id = "toolshortcuts_vertical";
             }
             $html .= '<div id="'.$style_id.'">';
-
             foreach ($navigation_items as $key => $navigation_item) {
                 if (strpos($navigation_item['link'], 'chat') !== false &&
                     api_get_course_setting('allow_open_chat_window')
                 ) {
-                    $html .= '<a href="javascript: void(0);" onclick="javascript: window.open(\''.$navigation_item['link'].'\',\'window_chat'.$_SESSION['_cid'].'\',config=\'height=\'+600+\', width=\'+825+\', left=2, top=2, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=no, directories=no, status=no\')" target="'.$navigation_item['target'].'"';
+                    $html .= '<a class="items-icon" href="javascript: void(0);" onclick="javascript: window.open(\''.$navigation_item['link'].'\',\'window_chat'.$_SESSION['_cid'].'\',config=\'height=\'+600+\', width=\'+825+\', left=2, top=2, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=no, directories=no, status=no\')" target="'.$navigation_item['target'].'"';
                 } else {
-                    $html .= '<a href="'.$navigation_item['link'].'"';
+                    $html .= '<a class="items-icon" href="'.$navigation_item['link'].'"';
                 }
                 if (strpos(api_get_self(), $navigation_item['link']) !== false) {
                     $html .= ' id="here"';
                 }
                 $html .= ' target="_top" title="'.$navigation_item['name'].'">';
-                $html .= '<img src="'.api_get_path(WEB_IMG_PATH).$navigation_item['image'].'" alt="'.$navigation_item['name'].'"/>';
+                $html .= Display::return_icon(substr($navigation_item['image'],0,-3)."png", $navigation_item['name'], null, ICON_SIZE_MEDIUM);
+                //$html .= '<img src="'.api_get_path(WEB_IMG_PATH).$navigation_item['image'].'" alt="'.$navigation_item['name'].'"/>';
                 $html .= '</a> ';
                 if ($orientation == SHORTCUTS_VERTICAL) {
                     $html .= '<br />';
                 }
             }
             $html .= '</div>';
+            
         }
 
         return $html;

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

@@ -105,7 +105,6 @@ class ExerciseLib
             // suggestions here, for the sake of comprehensions, while the ones
             // on the right side are called answers
             $num_suggestions = 0;
-
             if (in_array($answerType, [MATCHING, DRAGGABLE, MATCHING_DRAGGABLE])) {
                 if ($answerType == DRAGGABLE) {
                     $s .= '<div class="col-md-12 ui-widget ui-helper-clearfix">
@@ -319,6 +318,7 @@ class ExerciseLib
                         }
 
                         $answer = Security::remove_XSS($answer, STUDENT);
+          
                         $s .= Display::input(
                             'hidden',
                             'choice2[' . $questionId . ']',

+ 40 - 2
main/inc/lib/extra_field.lib.php

@@ -122,6 +122,8 @@ class ExtraField extends Model
             case 'lp_item':
                 $this->extraFieldType = EntityExtraField::LP_ITEM_FIELD_TYPE;
                 break;
+            case 'skill':
+                $this->extraFieldType = EntityExtraField::SKILL_FIELD_TYPE;
         }
 
         $this->pageUrl  = 'extra_fields.php?type='.$this->type;
@@ -149,7 +151,8 @@ class ExtraField extends Model
             'question',
             'lp',
             'calendar_event',
-            'lp_item'
+            'lp_item',
+            'skill'
         );
     }
 
@@ -286,7 +289,7 @@ class ExtraField extends Model
     }
 
     /**
-     * Get all the field info for User Tags
+     * Get all the field info for tags
      * @param string $variable
      *
      * @return array|bool
@@ -410,8 +413,12 @@ class ExtraField extends Model
 
         switch ($handler) {
             case 'course':
+                // no break
             case 'session':
+                // no break
             case 'user':
+                // no break
+            case 'skill':
                 break;
         }
 
@@ -2637,4 +2644,35 @@ JAVASCRIPT;
 
         return Database::store_result($result, 'ASSOC');
     }
+
+    /**
+     * @param int $fieldId
+     * @param int $tagId
+     *
+     * @return array
+     */
+    public function getAllSkillPerTag($fieldId, $tagId)
+    {
+        $skillTable = Database::get_main_table(TABLE_MAIN_SKILL);
+        $tagRelXtraTable = Database::get_main_table(TABLE_MAIN_EXTRA_FIELD_REL_TAG);
+        $fieldId = intval($fieldId);
+        $tagId = intval($tagId);
+
+        $sql = "SELECT s.id
+                FROM $skillTable s INNER JOIN $tagRelXtraTable t
+                ON t.item_id = s.id
+                WHERE tag_id = $tagId AND t.field_id = $fieldId;
+        ";
+
+        $result = Database::query($sql);
+        $result = Database::store_result($result, 'ASSOC');
+
+        $skillList = [];
+
+        foreach ($result as $index => $value) {
+            $skillList[$value['id']] = $value['id'];
+        }
+
+        return $skillList;
+    }
 }

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

@@ -682,6 +682,7 @@ class ExtraFieldValue extends Model
             $sql .= " AND visible = $visibility ";
         }
         $sql .= " ORDER BY id";
+
         $result = Database::query($sql);
         if (Database::num_rows($result)) {
             $result = Database::fetch_array($result, 'ASSOC');

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

@@ -584,8 +584,8 @@ class Login
                 $sql = "SELECT * FROM $course_user_table
                        WHERE
                         user_id  = '" . $user_id . "' AND
-                        relation_type <> ".COURSE_RELATION_TYPE_RRHH." AND
-                        course_code = '$course_id'";
+                        relation_type <> " . COURSE_RELATION_TYPE_RRHH . " AND
+                        c_id = '".$_real_cid."'";
                 $result = Database::query($sql);
 
                 $cuData = null;

+ 231 - 165
main/inc/lib/message.lib.php

@@ -24,7 +24,7 @@ class MessageManager
         $userlist = who_is_online(0, $count, null, null, 30, true);
         $online_user_list = array();
         foreach ($userlist as $user_id) {
-            $online_user_list[$user_id] = GetFullUserName($user_id).($current_user_id == $user_id ? ("&nbsp;(".get_lang('Myself').")") : (""));
+            $online_user_list[$user_id] = GetFullUserName($user_id) . ($current_user_id == $user_id ? ("&nbsp;(" . get_lang('Myself') . ")") : (""));
         }
 
         return $online_user_list;
@@ -40,20 +40,20 @@ class MessageManager
             $_SESSION['social_exist'] === true
         ) {
             if (api_get_setting('allow_social_tool') == 'true' && api_get_setting('allow_message_tool') == 'true') {
-                $success = get_lang('MessageSentTo').
-                    "&nbsp;<b>".
-                    GetFullUserName($uid).
+                $success = get_lang('MessageSentTo') .
+                    "&nbsp;<b>" .
+                    GetFullUserName($uid) .
                     "</b>";
             } else {
-                $success = get_lang('MessageSentTo').
-                    "&nbsp;<b>".
-                    GetFullUserName($uid).
+                $success = get_lang('MessageSentTo') .
+                    "&nbsp;<b>" .
+                    GetFullUserName($uid) .
                     "</b>";
             }
         } else {
-            $success = get_lang('MessageSentTo').
-                "&nbsp;<b>".
-                GetFullUserName($uid).
+            $success = get_lang('MessageSentTo') .
+                "&nbsp;<b>" .
+                GetFullUserName($uid) .
                 "</b>";
         }
 
@@ -72,8 +72,8 @@ class MessageManager
         }
         $sql = "SELECT * FROM $table
                 WHERE
-                    user_receiver_id=".api_get_user_id()." AND
-                    msg_status=".MESSAGE_STATUS_UNREAD;
+                    user_receiver_id=" . api_get_user_id() . " AND
+                    msg_status=" . MESSAGE_STATUS_UNREAD;
         $result = Database::query($sql);
         $i = Database::num_rows($result);
 
@@ -102,9 +102,9 @@ class MessageManager
     {
         $table_message = Database::get_main_table(TABLE_MESSAGE);
         if ($unread) {
-            $condition_msg_status = ' msg_status = '.MESSAGE_STATUS_UNREAD.' ';
+            $condition_msg_status = ' msg_status = ' . MESSAGE_STATUS_UNREAD . ' ';
         } else {
-            $condition_msg_status = ' msg_status IN('.MESSAGE_STATUS_NEW.','.MESSAGE_STATUS_UNREAD.') ';
+            $condition_msg_status = ' msg_status IN(' . MESSAGE_STATUS_NEW . ',' . MESSAGE_STATUS_UNREAD . ') ';
         }
 
         $keyword = Session::read('message_search_keyword');
@@ -117,7 +117,7 @@ class MessageManager
         $sql = "SELECT COUNT(*) as number_messages
                 FROM $table_message
                 WHERE $condition_msg_status AND
-                    user_receiver_id=".api_get_user_id()."
+                    user_receiver_id=" . api_get_user_id() . "
                     $keywordCondition
                 ";
         $result = Database::query($sql);
@@ -159,7 +159,7 @@ class MessageManager
         $sql = "SELECT id as col0, user_sender_id as col1, title as col2, send_date as col3, msg_status as col4
                 FROM $table_message
                 WHERE
-                  user_receiver_id=".api_get_user_id()." AND
+                  user_receiver_id=" . api_get_user_id() . " AND
                   msg_status IN (0,1)
                   $keywordCondition
                 ORDER BY col$column $direction
@@ -183,9 +183,9 @@ class MessageManager
             if (isset($_GET['f']) && $_GET['f'] == 'social') {
                 $link = '&f=social';
             }
-            $message[1] = '<a '.$class.' href="view_message.php?id='.$result[0].$link.'">'.$result[2].'</a><br />'.GetFullUserName(($result[1]));
-            $message[3] = '<a href="new_message.php?re_id='.$result[0].$link.'">'.Display::return_icon('message_reply.png', get_lang('ReplyToMessage')).'</a>'.
-                '&nbsp;&nbsp;<a onclick="javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmDeleteMessage')))."'".')) return false;" href="inbox.php?action=deleteone&id='.$result[0].$link.'">'.Display::return_icon('delete.png', get_lang('DeleteMessage')).'</a>';
+            $message[1] = '<a ' . $class . ' href="view_message.php?id=' . $result[0] . $link . '">' . $result[2] . '</a><br />' . GetFullUserName(($result[1]));
+            $message[3] = '<a href="new_message.php?re_id=' . $result[0] . $link . '">' . Display::return_icon('message_reply.png', get_lang('ReplyToMessage')) . '</a>' .
+                '&nbsp;&nbsp;<a onclick="javascript:if(!confirm(' . "'" . addslashes(api_htmlentities(get_lang('ConfirmDeleteMessage'))) . "'" . ')) return false;" href="inbox.php?action=deleteone&id=' . $result[0] . $link . '">' . Display::return_icon('delete.png', get_lang('DeleteMessage')) . '</a>';
 
             $message[2] = api_convert_and_format_date($result[3], DATE_TIME_FORMAT_LONG); //date stays the same
             foreach ($message as $key => $value) {
@@ -201,16 +201,16 @@ class MessageManager
     /**
      * Sends a message to a user/group
      *
-     * @param int 	  $receiver_user_id
-     * @param string  $subject
-     * @param string  $content
-     * @param array   $file_attachments files array($_FILES) (optional)
-     * @param array   $file_comments about attachment files (optional)
-     * @param int     $group_id (optional)
-     * @param int     $parent_id (optional)
-     * @param int 	  $edit_message_id id for updating the message (optional)
-     * @param int     $topic_id (optional) the default value is the current user_id
-     * @param int     $sender_id
+     * @param int $receiver_user_id
+     * @param string $subject
+     * @param string $content
+     * @param array $file_attachments files array($_FILES) (optional)
+     * @param array $file_comments about attachment files (optional)
+     * @param int $group_id (optional)
+     * @param int $parent_id (optional)
+     * @param int $edit_message_id id for updating the message (optional)
+     * @param int $topic_id (optional) the default value is the current user_id
+     * @param int $sender_id
      * @param bool $directMessage
      *
      * @return bool
@@ -227,7 +227,8 @@ class MessageManager
         $topic_id = 0,
         $sender_id = null,
         $directMessage = false
-    ) {
+    )
+    {
         $table_message = Database::get_main_table(TABLE_MESSAGE);
         $group_id = intval($group_id);
         $receiver_user_id = intval($receiver_user_id);
@@ -287,7 +288,7 @@ class MessageManager
             //@todo it's possible to edit a message? yes, only for groups
             if ($edit_message_id) {
                 $query = " UPDATE $table_message SET
-                                update_date = '".$now."',
+                                update_date = '" . $now . "',
                                 content = '$clean_content'
                            WHERE id = '$edit_message_id' ";
                 Database::query($query);
@@ -434,7 +435,8 @@ class MessageManager
         $sender_id = null,
         $sendCopyToDrhUsers = false,
         $directMessage = false
-    ) {
+    )
+    {
         $result = MessageManager::send_message(
             $receiver_user_id,
             $subject,
@@ -458,7 +460,7 @@ class MessageManager
                     $message = sprintf(
                             get_lang('CopyOfMessageSentToXUser'),
                             $userInfo['complete_name']
-                        ).' <br />'.$message;
+                        ) . ' <br />' . $message;
 
                     MessageManager::send_message_simple(
                         $drhInfo['user_id'],
@@ -478,9 +480,9 @@ class MessageManager
     /**
      * Update parent ids for other receiver user from current message in groups
      * @author Christian Fasanando Flores
-     * @param  int	$parent_id
-     * @param  int	$receiver_user_id
-     * @param  int	$message_id
+     * @param  int $parent_id
+     * @param  int $receiver_user_id
+     * @param  int $message_id
      * @return void
      */
     public static function update_parent_ids_from_reply($parent_id, $receiver_user_id, $message_id)
@@ -506,7 +508,7 @@ class MessageManager
         $row = Database::fetch_array($rs_msg_id);
 
         // update parent_id for other user receiver
-        $sql = "UPDATE $table_message SET parent_id = ".$row['id']."
+        $sql = "UPDATE $table_message SET parent_id = " . $row['id'] . "
                 WHERE id = $message_id";
         Database::query($sql);
     }
@@ -524,7 +526,7 @@ class MessageManager
         $user_receiver_id = intval($user_receiver_id);
         $id = intval($id);
         $sql = "SELECT * FROM $table_message
-                WHERE id=".$id." AND msg_status<>4";
+                WHERE id=" . $id . " AND msg_status<>4";
         $rs = Database::query($sql);
 
         if (Database::num_rows($rs) > 0) {
@@ -532,7 +534,7 @@ class MessageManager
             self::delete_message_attachment_file($id, $user_receiver_id);
             // delete message
             $query = "UPDATE $table_message SET msg_status=3
-                      WHERE user_receiver_id=".$user_receiver_id." AND id=".$id;
+                      WHERE user_receiver_id=" . $user_receiver_id . " AND id=" . $id;
             $result = Database::query($query);
             return $result;
         } else {
@@ -577,12 +579,12 @@ class MessageManager
 
     /**
      * Saves a message attachment files
-     * @param  array 	$file_attach $_FILES['name']
-     * @param  string  	a comment about the uploaded file
-     * @param  int		message id
-     * @param  int		receiver user id (optional)
-     * @param  int		sender user id (optional)
-     * @param  int		group id (optional)
+     * @param  array $file_attach $_FILES['name']
+     * @param  string    a comment about the uploaded file
+     * @param  int        message id
+     * @param  int        receiver user id (optional)
+     * @param  int        sender user id (optional)
+     * @param  int        group id (optional)
      * @return void
      */
     public static function save_message_attachment_file(
@@ -592,7 +594,8 @@ class MessageManager
         $receiver_user_id = 0,
         $sender_user_id = 0,
         $group_id = 0
-    ) {
+    )
+    {
         $tbl_message_attach = Database::get_main_table(TABLE_MESSAGE_ATTACHMENT);
 
         // Try to add an extension to the file if it hasn't one
@@ -601,7 +604,7 @@ class MessageManager
         // user's file name
         $file_name = $file_attach['name'];
         if (!filter_extension($new_file_name)) {
-            Display :: display_error_message(get_lang('UplUnableToSaveFileFilteredExtension'));
+            Display:: display_error_message(get_lang('UplUnableToSaveFileFilteredExtension'));
         } else {
             $new_file_name = uniqid('');
             if (!empty($receiver_user_id)) {
@@ -619,13 +622,13 @@ class MessageManager
                 $path_user_info['dir'] = UserManager::getUserPathById($message_user_id, 'system');
             }
 
-            $path_message_attach = $path_user_info['dir'].'message_attachments/';
+            $path_message_attach = $path_user_info['dir'] . 'message_attachments/';
 
             // If this directory does not exist - we create it.
             if (!file_exists($path_message_attach)) {
                 @mkdir($path_message_attach, api_get_permissions_for_new_directories(), true);
             }
-            $new_path = $path_message_attach.$new_file_name;
+            $new_path = $path_message_attach . $new_file_name;
             if (is_uploaded_file($file_attach['tmp_name'])) {
                 @copy($file_attach['tmp_name'], $new_path);
             }
@@ -644,9 +647,9 @@ class MessageManager
 
     /**
      * Delete message attachment files (logically updating the row with a suffix _DELETE_id)
-     * @param  int	message id
-     * @param  int	message user id (receiver user id or sender user id)
-     * @param  int	group id (optional)
+     * @param  int    message id
+     * @param  int    message user id (receiver user id or sender user id)
+     * @param  int    group id (optional)
      * @return void
      */
     public static function delete_message_attachment_file($message_id, $message_uid, $group_id = 0)
@@ -660,7 +663,7 @@ class MessageManager
         while ($row = Database::fetch_array($rs)) {
             $path = $row['path'];
             $attach_id = $row['id'];
-            $new_path = $path.'_DELETED_'.$attach_id;
+            $new_path = $path . '_DELETED_' . $attach_id;
 
             if (!empty($group_id)) {
                 $userGroup = new UserGroup();
@@ -676,9 +679,9 @@ class MessageManager
                 );
             }
 
-            $path_message_attach = $path_user_info['dir'].'message_attachments/';
-            if (is_file($path_message_attach.$path)) {
-                if (rename($path_message_attach.$path, $path_message_attach.$new_path)) {
+            $path_message_attach = $path_user_info['dir'] . 'message_attachments/';
+            if (is_file($path_message_attach . $path)) {
+                if (rename($path_message_attach . $path, $path_message_attach . $new_path)) {
                     $sql = "UPDATE $table_message_attach set path='$new_path'
                             WHERE id ='$attach_id'";
                     Database::query($sql);
@@ -689,8 +692,8 @@ class MessageManager
 
     /**
      * update messages by user id and message id
-     * @param  int		$user_id
-     * @param  int		$message_id
+     * @param  int $user_id
+     * @param  int $message_id
      * @return resource
      */
     public static function update_message($user_id, $message_id)
@@ -702,8 +705,8 @@ class MessageManager
         $sql = "UPDATE $table_message SET msg_status = '0'
                 WHERE
                     msg_status<>4 AND
-                    user_receiver_id=".intval($user_id)." AND
-                    id='".intval($message_id)."'";
+                    user_receiver_id=" . intval($user_id) . " AND
+                    id='" . intval($message_id) . "'";
         Database::query($sql);
     }
 
@@ -713,7 +716,7 @@ class MessageManager
      * @param string $type
      * @return bool
      */
-    public static function update_message_status($user_id, $message_id,$type)
+    public static function update_message_status($user_id, $message_id, $type)
     {
         $type = intval($type);
         if ($message_id != strval(intval($message_id)) || $user_id != strval(intval($user_id))) {
@@ -723,15 +726,15 @@ class MessageManager
         $sql = "UPDATE $table_message SET
                     msg_status = '$type'
                 WHERE
-                    user_receiver_id=".intval($user_id)." AND
-                    id='".intval($message_id)."'";
+                    user_receiver_id=" . intval($user_id) . " AND
+                    id='" . intval($message_id) . "'";
         Database::query($sql);
     }
 
     /**
      * get messages by user id and message id
-     * @param  int		$user_id
-     * @param  int		$message_id
+     * @param  int $user_id
+     * @param  int $message_id
      * @return array
      */
     public static function get_message_by_user($user_id, $message_id)
@@ -740,14 +743,14 @@ class MessageManager
             return false;
         $table_message = Database::get_main_table(TABLE_MESSAGE);
         $query = "SELECT * FROM $table_message
-                  WHERE user_receiver_id=".intval($user_id)." AND id='".intval($message_id)."'";
+                  WHERE user_receiver_id=" . intval($user_id) . " AND id='" . intval($message_id) . "'";
         $result = Database::query($query);
         return $row = Database::fetch_array($result);
     }
 
     /**
      * get messages by group id
-     * @param  int		group id
+     * @param  int        group id
      * @return array
      */
     public static function get_messages_by_group($group_id)
@@ -760,7 +763,7 @@ class MessageManager
         $sql = "SELECT * FROM $table_message
                 WHERE
                     group_id= $group_id AND
-                    msg_status NOT IN ('".MESSAGE_STATUS_OUTBOX."', '".MESSAGE_STATUS_DELETED."')
+                    msg_status NOT IN ('" . MESSAGE_STATUS_OUTBOX . "', '" . MESSAGE_STATUS_DELETED . "')
                 ORDER BY id";
         $rs = Database::query($sql);
         $data = array();
@@ -787,7 +790,7 @@ class MessageManager
         $sql = "SELECT * FROM $table_message
                 WHERE
                     group_id = $group_id AND
-                    msg_status NOT IN ('".MESSAGE_STATUS_OUTBOX."', '".MESSAGE_STATUS_DELETED."')
+                    msg_status NOT IN ('" . MESSAGE_STATUS_OUTBOX . "', '" . MESSAGE_STATUS_DELETED . "')
                 ORDER BY id ";
 
         $rs = Database::query($sql);
@@ -807,10 +810,10 @@ class MessageManager
 
     /**
      * get messages by parent id optionally with limit
-     * @param  int		parent id
-     * @param  int		group id (optional)
-     * @param  int		offset (optional)
-     * @param  int		limit (optional)
+     * @param  int        parent id
+     * @param  int        group id (optional)
+     * @param  int        offset (optional)
+     * @param  int        limit (optional)
      * @return array
      */
     public static function get_messages_by_parent($parent_id, $group_id = '', $offset = 0, $limit = 0)
@@ -836,7 +839,7 @@ class MessageManager
         $sql = "SELECT * FROM $table_message
                 WHERE
                     parent_id='$parent_id' AND
-                    msg_status <> ".MESSAGE_STATUS_OUTBOX."
+                    msg_status <> " . MESSAGE_STATUS_OUTBOX . "
                     $condition_group_id
                 ORDER BY send_date DESC $condition_limit ";
         $rs = Database::query($sql);
@@ -864,8 +867,8 @@ class MessageManager
         $table_message = Database::get_main_table(TABLE_MESSAGE);
         $query = "SELECT id FROM $table_message
                   WHERE
-                    user_receiver_id = ".intval($user_id)." AND
-                    id = '".intval($id)."'";
+                    user_receiver_id = " . intval($user_id) . " AND
+                    id = '" . intval($id) . "'";
         $result = Database::query($query);
         $num = Database::num_rows($result);
         if ($num > 0) {
@@ -908,8 +911,8 @@ class MessageManager
                     id as col0, user_sender_id as col1, title as col2, send_date as col3, user_receiver_id as col4, msg_status as col5
                 FROM $table_message
                 WHERE
-                    user_sender_id=".api_get_user_id()." AND
-                    msg_status=".MESSAGE_STATUS_OUTBOX."
+                    user_sender_id=" . api_get_user_id() . " AND
+                    msg_status=" . MESSAGE_STATUS_OUTBOX . "
                     $keywordCondition
                 ORDER BY col$column $direction
                 LIMIT $from, $number_of_items";
@@ -918,7 +921,7 @@ class MessageManager
         $message_list = array();
         while ($result = Database::fetch_row($sql_result)) {
             if ($request === true) {
-                $message[0] = '<input type="checkbox" value='.$result[0].' name="out[]">';
+                $message[0] = '<input type="checkbox" value=' . $result[0] . ' name="out[]">';
             } else {
                 $message[0] = ($result[0]);
             }
@@ -926,20 +929,20 @@ class MessageManager
             $result[2] = Security::remove_XSS($result[2]);
 
             if ($request === true) {
-                $message[1] = '<a onclick="show_sent_message('.$result[0].')" href="javascript:void(0)">'.GetFullUserName($result[4]).'</a>';
-                $message[2] = '<a onclick="show_sent_message('.$result[0].')" href="javascript:void(0)">'.str_replace("\\", "", $result[2]).'</a>';
+                $message[1] = '<a onclick="show_sent_message(' . $result[0] . ')" href="javascript:void(0)">' . GetFullUserName($result[4]) . '</a>';
+                $message[2] = '<a onclick="show_sent_message(' . $result[0] . ')" href="javascript:void(0)">' . str_replace("\\", "", $result[2]) . '</a>';
                 $message[3] = api_convert_and_format_date($result[3], DATE_TIME_FORMAT_LONG); //date stays the same
 
-                $message[4] = '&nbsp;&nbsp;<a onclick="delete_one_message_outbox('.$result[0].')" href="javascript:void(0)"  >'.Display::return_icon('delete.png', get_lang('DeleteMessage')).'</a>';
+                $message[4] = '&nbsp;&nbsp;<a onclick="delete_one_message_outbox(' . $result[0] . ')" href="javascript:void(0)"  >' . Display::return_icon('delete.png', get_lang('DeleteMessage')) . '</a>';
             } else {
                 $link = '';
                 if (isset($_GET['f']) && $_GET['f'] == 'social') {
                     $link = '&f=social';
                 }
-                $message[1] = '<a '.$class.' onclick="show_sent_message ('.$result[0].')" href="../messages/view_message.php?id_send='.$result[0].$link.'">'.$result[2].'</a><br />'.GetFullUserName($result[4]);
+                $message[1] = '<a ' . $class . ' onclick="show_sent_message (' . $result[0] . ')" href="../messages/view_message.php?id_send=' . $result[0] . $link . '">' . $result[2] . '</a><br />' . GetFullUserName($result[4]);
                 //$message[2] = '<a '.$class.' onclick="show_sent_message ('.$result[0].')" href="../messages/view_message.php?id_send='.$result[0].$link.'">'.$result[2].'</a>';
                 $message[2] = api_convert_and_format_date($result[3], DATE_TIME_FORMAT_LONG); //date stays the same
-                $message[3] = '<a href="outbox.php?action=deleteone&id='.$result[0].'&'.$link.'"  onclick="javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmDeleteMessage')))."'".')) return false;" >'.Display::return_icon('delete.png', get_lang('DeleteMessage')).'</a>';
+                $message[3] = '<a href="outbox.php?action=deleteone&id=' . $result[0] . '&' . $link . '"  onclick="javascript:if(!confirm(' . "'" . addslashes(api_htmlentities(get_lang('ConfirmDeleteMessage'))) . "'" . ')) return false;" >' . Display::return_icon('delete.png', get_lang('DeleteMessage')) . '</a>';
             }
 
             foreach ($message as $key => $value) {
@@ -971,8 +974,8 @@ class MessageManager
 
         $sql = "SELECT COUNT(*) as number_messages FROM $table_message
                 WHERE
-                  msg_status=".MESSAGE_STATUS_OUTBOX." AND
-                  user_sender_id=".api_get_user_id()."
+                  msg_status=" . MESSAGE_STATUS_OUTBOX . " AND
+                  user_sender_id=" . api_get_user_id() . "
                   $keywordCondition
                 ";
         $result = Database::query($sql);
@@ -997,25 +1000,25 @@ class MessageManager
             if (isset($message_id) && is_numeric($message_id)) {
                 $query = "SELECT * FROM $table_message
                           WHERE
-                            user_sender_id = ".api_get_user_id()." AND
-                            id = ".$message_id." AND
+                            user_sender_id = " . api_get_user_id() . " AND
+                            id = " . $message_id . " AND
                             msg_status = 4;";
                 $result = Database::query($query);
             }
         } else {
             if (is_numeric($message_id) && !empty($message_id)) {
                 $query = "UPDATE $table_message SET
-                          msg_status = '".MESSAGE_STATUS_NEW."'
+                          msg_status = '" . MESSAGE_STATUS_NEW . "'
                           WHERE
-                            user_receiver_id=".api_get_user_id()." AND
-                            id='".$message_id."'";
+                            user_receiver_id=" . api_get_user_id() . " AND
+                            id='" . $message_id . "'";
                 Database::query($query);
 
                 $query = "SELECT * FROM $table_message
                           WHERE
                             msg_status<>4 AND
-                            user_receiver_id=".api_get_user_id()." AND
-                            id='".$message_id."'";
+                            user_receiver_id=" . api_get_user_id() . " AND
+                            id='" . $message_id . "'";
                 $result = Database::query($query);
             }
         }
@@ -1045,7 +1048,7 @@ class MessageManager
 
         $receiverUserInfo = api_get_user_info($row['user_receiver_id']);
 
-        $message_content .='<tr>';
+        $message_content .= '<tr>';
         if (api_get_setting('allow_social_tool') == 'true') {
             $message_content .= '<div class="row">';
 
@@ -1055,8 +1058,8 @@ class MessageManager
                 $message_content .= '</div>';
 
                 $message_content .= '<div class="col-md-4">';
-                $message_content .= '<a href="'.api_get_path(WEB_PATH).'main/social/profile.php?u='.$user_sender_id.'">'.$name.'</a> ';
-                $message_content .= api_strtolower(get_lang('To')).'&nbsp;<b>'.$receiverUserInfo['complete_name'];
+                $message_content .= '<a href="' . api_get_path(WEB_PATH) . 'main/social/profile.php?u=' . $user_sender_id . '">' . $name . '</a> ';
+                $message_content .= api_strtolower(get_lang('To')) . '&nbsp;<b>' . $receiverUserInfo['complete_name'];
                 $message_content .= '</div>';
 
                 $message_content .= '<div class="col-md-2 col-md-offset-5">';
@@ -1069,7 +1072,7 @@ class MessageManager
                 $message_content .= '</div>';
 
                 $message_content .= '<div class="col-md-4">';
-                $message_content .= '<a href="'.api_get_path(WEB_PATH).'main/social/profile.php?u='.$user_sender_id.'">'.$name.'</a> ';
+                $message_content .= '<a href="' . api_get_path(WEB_PATH) . 'main/social/profile.php?u=' . $user_sender_id . '">' . $name . '</a> ';
                 $message_content .= '</div>';
 
                 $message_content .= '<div class="col-md-2 col-md-offset-5">';
@@ -1079,38 +1082,38 @@ class MessageManager
             $message_content .= '</div>';
         } else {
             if ($source == 'outbox') {
-                $message_content .= get_lang('From').':&nbsp;'.$name.'</b> '.api_strtolower(get_lang('To')).' <b>'.$receiverUserInfo['complete_name'].'</b>';
+                $message_content .= get_lang('From') . ':&nbsp;' . $name . '</b> ' . api_strtolower(get_lang('To')) . ' <b>' . $receiverUserInfo['complete_name'] . '</b>';
             } else {
-                $message_content .= get_lang('From').':&nbsp;'.$name.'</b> '.api_strtolower(get_lang('To')).' <b>'.get_lang('Me').'</b>';
+                $message_content .= get_lang('From') . ':&nbsp;' . $name . '</b> ' . api_strtolower(get_lang('To')) . ' <b>' . get_lang('Me') . '</b>';
             }
         }
-        $message_content .='
+        $message_content .= '
 		        <br />
 		        <hr style="color:#ddd" />
 		        <table height="209px" width="100%">
 		            <tr>
-		              <td valign=top class="view-message-content">'.str_replace("\\", "", $content).'</td>
+		              <td valign=top class="view-message-content">' . str_replace("\\", "", $content) . '</td>
 		            </tr>
 		        </table>
-		        <div id="message-attach">'.(!empty($files_attachments) ? implode('<br />', $files_attachments) : '').'</div>
+		        <div id="message-attach">' . (!empty($files_attachments) ? implode('<br />', $files_attachments) : '') . '</div>
 		        <div style="padding: 15px 0px 5px 0px">';
         $social_link = '';
         if (isset($_GET['f']) && $_GET['f'] == 'social') {
             $social_link = 'f=social';
         }
         if ($source == 'outbox') {
-            $message_content .= '<a href="outbox.php?'.$social_link.'">'.
-                Display::return_icon('back.png', get_lang('ReturnToOutbox')).'</a> &nbsp';
+            $message_content .= '<a href="outbox.php?' . $social_link . '">' .
+                Display::return_icon('back.png', get_lang('ReturnToOutbox')) . '</a> &nbsp';
         } else {
-            $message_content .= '<a href="inbox.php?'.$social_link.'">'.
-                Display::return_icon('back.png', get_lang('ReturnToInbox')).'</a> &nbsp';
-            $message_content .= '<a href="new_message.php?re_id='.$message_id.'&'.$social_link.'">'.
-                Display::return_icon('message_reply.png', get_lang('ReplyToMessage')).'</a> &nbsp';
+            $message_content .= '<a href="inbox.php?' . $social_link . '">' .
+                Display::return_icon('back.png', get_lang('ReturnToInbox')) . '</a> &nbsp';
+            $message_content .= '<a href="new_message.php?re_id=' . $message_id . '&' . $social_link . '">' .
+                Display::return_icon('message_reply.png', get_lang('ReplyToMessage')) . '</a> &nbsp';
         }
-        $message_content .= '<a href="inbox.php?action=deleteone&id='.$message_id.'&'.$social_link.'" >'.
-            Display::return_icon('delete.png', get_lang('DeleteMessage')).'</a>&nbsp';
+        $message_content .= '<a href="inbox.php?action=deleteone&id=' . $message_id . '&' . $social_link . '" >' .
+            Display::return_icon('delete.png', get_lang('DeleteMessage')) . '</a>&nbsp';
 
-        $message_content .='</div></td>
+        $message_content .= '</div></td>
 		      <td width=10></td>
 		    </tr>
 		</table>';
@@ -1126,8 +1129,8 @@ class MessageManager
     public static function get_user_id_by_email($user_email)
     {
         $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
-        $sql = 'SELECT user_id FROM '.$tbl_user.'
-                WHERE email="'.Database::escape_string($user_email).'";';
+        $sql = 'SELECT user_id FROM ' . $tbl_user . '
+                WHERE email="' . Database::escape_string($user_email) . '";';
         $rs = Database::query($sql);
         $row = Database::fetch_array($rs, 'ASSOC');
         if (isset($row['user_id'])) {
@@ -1188,7 +1191,7 @@ class MessageManager
 
                 $items = $topic['count'];
                 $reply_label = ($items == 1) ? get_lang('GroupReply') : get_lang('GroupReplies');
-                $label =  '<i class="fa fa-envelope"></i> ' . $items . ' ' . $reply_label;
+                $label = '<i class="fa fa-envelope"></i> ' . $items . ' ' . $reply_label;
                 $topic['title'] = trim($topic['title']);
 
                 if (empty($topic['title'])) {
@@ -1200,31 +1203,31 @@ class MessageManager
                     'h4',
                     Display::url(
                         Security::remove_XSS($topic['title'], STUDENT, true),
-                        api_get_path(WEB_CODE_PATH).'social/group_topics.php?id='.$group_id.'&topic_id='.$topic['id']
-                    ), array('class'=>'title')
+                        api_get_path(WEB_CODE_PATH) . 'social/group_topics.php?id=' . $group_id . '&topic_id=' . $topic['id']
+                    ), array('class' => 'title')
                 );
                 $actions = '';
                 if ($my_group_role == GROUP_USER_PERMISSION_ADMIN ||
                     $my_group_role == GROUP_USER_PERMISSION_MODERATOR
                 ) {
-                    $actions = '<br />'.Display::url(get_lang('Delete'), api_get_path(WEB_CODE_PATH).'social/group_topics.php?action=delete&id='.$group_id.'&topic_id='.$topic['id'], array('class' => 'btn btn-default'));
+                    $actions = '<br />' . Display::url(get_lang('Delete'), api_get_path(WEB_CODE_PATH) . 'social/group_topics.php?action=delete&id=' . $group_id . '&topic_id=' . $topic['id'], array('class' => 'btn btn-default'));
                 }
 
                 $date = '';
                 if ($topic['send_date'] != $topic['update_date']) {
                     if (!empty($topic['update_date'])) {
-                        $date .= '<i class="fa fa-calendar"></i> '.get_lang('LastUpdate').' '.date_to_str_ago($topic['update_date']);
+                        $date .= '<i class="fa fa-calendar"></i> ' . get_lang('LastUpdate') . ' ' . date_to_str_ago($topic['update_date']);
                     }
                 } else {
-                    $date .= '<i class="fa fa-calendar"></i> '.get_lang('Created').' '.date_to_str_ago($topic['send_date']);
+                    $date .= '<i class="fa fa-calendar"></i> ' . get_lang('Created') . ' ' . date_to_str_ago($topic['send_date']);
                 }
-                $html .= '<div class="date">'. $label.' - '.$date.$actions . '</div>';
+                $html .= '<div class="date">' . $label . ' - ' . $date . $actions . '</div>';
                 $html .= '</div>';
 
                 $image = $user_sender_info['avatar'];
 
-                $user_info = '<div class="author"><img class="img-responsive img-circle" src="'.$image.'" alt="'.$name.'"  width="64" height="64" title="'.$name.'" /></div>';
-                $user_info .= '<div class="name"><a href="'.api_get_path(WEB_PATH).'main/social/profile.php?u='.$topic['user_sender_id'].'">'.$name.'&nbsp;</a></div>';
+                $user_info = '<div class="author"><img class="img-responsive img-circle" src="' . $image . '" alt="' . $name . '"  width="64" height="64" title="' . $name . '" /></div>';
+                $user_info .= '<div class="name"><a href="' . api_get_path(WEB_PATH) . 'main/social/profile.php?u=' . $topic['user_sender_id'] . '">' . $name . '&nbsp;</a></div>';
 
                 $html .= '<div class="col-xs-4 col-md-2">';
                 $html .= $user_info;
@@ -1288,11 +1291,11 @@ class MessageManager
 
         $topic_page_nr = isset($_GET['topics_page_nr']) ? intval($_GET['topics_page_nr']) : null;
 
-        $links.= '<div class="pull-right">';
-        $links.= '<div class="btn-group">';
+        $links .= '<div class="pull-right">';
+        $links .= '<div class="btn-group">';
 
         if (($my_group_role == GROUP_USER_PERMISSION_ADMIN ||
-            $my_group_role == GROUP_USER_PERMISSION_MODERATOR) ||
+                $my_group_role == GROUP_USER_PERMISSION_MODERATOR) ||
             $main_message['user_sender_id'] == $current_user_id
         ) {
             $urlEdit = api_get_path(WEB_CODE_PATH);
@@ -1310,7 +1313,7 @@ class MessageManager
             if (api_is_platform_admin()) {
                 $links .= Display::url(
                     Display::returnFontAwesomeIcon('trash'),
-                    'group_topics.php?action=delete&id='.$group_id.'&topic_id='.$topic_id,
+                    'group_topics.php?action=delete&id=' . $group_id . '&topic_id=' . $topic_id,
                     [
                         'class' => 'btn btn-default'
                     ]
@@ -1350,27 +1353,27 @@ class MessageManager
                 'data-size' => 'lg'
             ]
         );
-        $links.= '</div>';
-        $links.= '</div>';
+        $links .= '</div>';
+        $links .= '</div>';
 
-        $title = '<h4>'.Security::remove_XSS($main_message['title'], STUDENT, true).$links.'</h4>';
+        $title = '<h4>' . Security::remove_XSS($main_message['title'], STUDENT, true) . $links . '</h4>';
 
         $userPicture = $user_sender_info['avatar'];
         $main_content .= '<div class="avatar-author">';
-        $main_content .= '<img src="'.$userPicture.'" alt="'.$name.'" class="img-responsive img-circle" width="64" height="64" title="'.$name.'" />';
-        $main_content .= '<a href="'.api_get_path(WEB_PATH).'main/social/profile.php?u='.$main_message['user_sender_id'].'">'.$name.'</a>';
+        $main_content .= '<img src="' . $userPicture . '" alt="' . $name . '" class="img-responsive img-circle" width="64" height="64" title="' . $name . '" />';
+        $main_content .= '<a href="' . api_get_path(WEB_PATH) . 'main/social/profile.php?u=' . $main_message['user_sender_id'] . '">' . $name . '</a>';
         $main_content .= '</div>';
 
         $date = '';
         if ($main_message['send_date'] != $main_message['update_date']) {
             if (!empty($main_message['update_date'])) {
-                $date = '<div class="message-date"> '.get_lang('LastUpdate').' '.date_to_str_ago($main_message['update_date']).'</div>';
+                $date = '<div class="message-date"> ' . get_lang('LastUpdate') . ' ' . date_to_str_ago($main_message['update_date']) . '</div>';
             }
         } else {
-            $date = '<div class="message-date"> '.get_lang('Created').' '.date_to_str_ago($main_message['send_date']).'</div>';
+            $date = '<div class="message-date"> ' . get_lang('Created') . ' ' . date_to_str_ago($main_message['send_date']) . '</div>';
         }
-        $attachment = '<div class="message-attach">'.(!empty($files_attachments) ? implode('<br />', $files_attachments) : '').'</div>';
-        $main_content.= '<div class="message-content"> '.$date.$main_message['content'].$attachment.'</div>';
+        $attachment = '<div class="message-attach">' . (!empty($files_attachments) ? implode('<br />', $files_attachments) : '') . '</div>';
+        $main_content .= '<div class="message-content"> ' . $date . $main_message['content'] . $attachment . '</div>';
         //$main_content = Security::remove_XSS($main_content, STUDENT, true);
 
         $html .= Display::div(Display::div($title . $main_content, array('class' => 'message-topic')), array('class' => 'sm-groups-message'));
@@ -1384,39 +1387,39 @@ class MessageManager
                 if (empty($topic['id'])) {
                     continue;
                 }
-                $items_page_nr = isset($_GET['items_'.$topic['id'].'_page_nr']) ? intval($_GET['items_'.$topic['id'].'_page_nr']) : null;
+                $items_page_nr = isset($_GET['items_' . $topic['id'] . '_page_nr']) ? intval($_GET['items_' . $topic['id'] . '_page_nr']) : null;
                 $links = '';
-                $links.= '<div class="pull-right">';
+                $links .= '<div class="pull-right">';
                 $html_items = '';
                 $user_sender_info = api_get_user_info($topic['user_sender_id']);
                 $files_attachments = self::get_links_message_attachment_files($topic['id']);
                 $name = $user_sender_info['complete_name'];
 
-                $links.= '<div class="btn-group">';
+                $links .= '<div class="btn-group">';
                 if (($my_group_role == GROUP_USER_PERMISSION_ADMIN || $my_group_role == GROUP_USER_PERMISSION_MODERATOR) || $topic['user_sender_id'] == $current_user_id) {
-                    $links.= '<a href="'.api_get_path(WEB_CODE_PATH).'social/message_for_group_form.inc.php?height=400&width=800&&user_friend='.$current_user_id.'&group_id='.$group_id.'&message_id='.$topic['id'].'&action=edit_message_group&anchor_topic=topic_'.$topic_id.'&topics_page_nr='.$topic_page_nr.'&items_page_nr='.$items_page_nr.'&topic_id='.$topic_id.'" class="ajax btn btn-default" data-size="lg" data-title="'.get_lang('Edit').'" title="'.get_lang('Edit').'">'.
-                    Display::returnFontAwesomeIcon('pencil') . '</a>';
+                    $links .= '<a href="' . api_get_path(WEB_CODE_PATH) . 'social/message_for_group_form.inc.php?height=400&width=800&&user_friend=' . $current_user_id . '&group_id=' . $group_id . '&message_id=' . $topic['id'] . '&action=edit_message_group&anchor_topic=topic_' . $topic_id . '&topics_page_nr=' . $topic_page_nr . '&items_page_nr=' . $items_page_nr . '&topic_id=' . $topic_id . '" class="ajax btn btn-default" data-size="lg" data-title="' . get_lang('Edit') . '" title="' . get_lang('Edit') . '">' .
+                        Display::returnFontAwesomeIcon('pencil') . '</a>';
                 }
-                $links.= '<a href="'.api_get_path(WEB_CODE_PATH).'social/message_for_group_form.inc.php?height=400&width=800&&user_friend='.api_get_user_id().'&group_id='.$group_id.'&message_id='.$topic['id'].'&action=reply_message_group&anchor_topic=topic_'.$topic_id.'&topics_page_nr='.$topic_page_nr.'&items_page_nr='.$items_page_nr.'&topic_id='.$topic_id.'" class="ajax btn btn-default" data-size="lg" data-title="'.get_lang('Reply').'" title="'.get_lang('Reply').'">';
-                $links.= Display::returnFontAwesomeIcon('commenting') . '</a>';
-                $links.= '</div>';
-                $links.= '</div>';
+                $links .= '<a href="' . api_get_path(WEB_CODE_PATH) . 'social/message_for_group_form.inc.php?height=400&width=800&&user_friend=' . api_get_user_id() . '&group_id=' . $group_id . '&message_id=' . $topic['id'] . '&action=reply_message_group&anchor_topic=topic_' . $topic_id . '&topics_page_nr=' . $topic_page_nr . '&items_page_nr=' . $items_page_nr . '&topic_id=' . $topic_id . '" class="ajax btn btn-default" data-size="lg" data-title="' . get_lang('Reply') . '" title="' . get_lang('Reply') . '">';
+                $links .= Display::returnFontAwesomeIcon('commenting') . '</a>';
+                $links .= '</div>';
+                $links .= '</div>';
 
                 $userPicture = $user_sender_info['avatar'];
-                $user_link = '<a href="'.api_get_path(WEB_PATH).'main/social/profile.php?u='.$topic['user_sender_id'].'">'.$name.'&nbsp</a>';
-                $html_items.= '<div class="avatar-author"><img src="'.$userPicture.'" alt="'.$name.'" class="img-responsive img-circle"  width="64" height="64" title="'.$name.'" />'.$user_link.'</div>';
+                $user_link = '<a href="' . api_get_path(WEB_PATH) . 'main/social/profile.php?u=' . $topic['user_sender_id'] . '">' . $name . '&nbsp</a>';
+                $html_items .= '<div class="avatar-author"><img src="' . $userPicture . '" alt="' . $name . '" class="img-responsive img-circle"  width="64" height="64" title="' . $name . '" />' . $user_link . '</div>';
 
 
                 $date = '';
                 if ($topic['send_date'] != $topic['update_date']) {
                     if (!empty($topic['update_date'])) {
-                        $date = '<div class="message-date"> '.get_lang('LastUpdate').' '.date_to_str_ago($topic['update_date']).'</div>';
+                        $date = '<div class="message-date"> ' . get_lang('LastUpdate') . ' ' . date_to_str_ago($topic['update_date']) . '</div>';
                     }
                 } else {
-                    $date = '<div class="message-date"> '.get_lang('Created').' '.date_to_str_ago($topic['send_date']).'</div>';
+                    $date = '<div class="message-date"> ' . get_lang('Created') . ' ' . date_to_str_ago($topic['send_date']) . '</div>';
                 }
-                $attachment = '<div class="message-attach">'.(!empty($files_attachments) ? implode('<br />', $files_attachments) : '').'</div>';
-                $html_items.= '<div class="message-content">'.$links.' '.$date.Security::remove_XSS($topic['content'], STUDENT, true).$attachment.'</div>';
+                $attachment = '<div class="message-attach">' . (!empty($files_attachments) ? implode('<br />', $files_attachments) : '') . '</div>';
+                $html_items .= '<div class="message-content">' . $links . ' ' . $date . Security::remove_XSS($topic['content'], STUDENT, true) . $attachment . '</div>';
 
                 $base_padding = 20;
 
@@ -1426,8 +1429,8 @@ class MessageManager
                     $indent = intval($topic['indent_cnt']) * $base_padding + $base_padding;
                 }
 
-                $html_items = Display::div($html_items, array('class' => 'message-post', 'id' => 'msg_'.$topic['id']));
-                $html_items = Display::div($html_items, array('class' => '', 'style' => 'margin-left:'.$indent.'px'));
+                $html_items = Display::div($html_items, array('class' => 'message-post', 'id' => 'msg_' . $topic['id']));
+                $html_items = Display::div($html_items, array('class' => '', 'style' => 'margin-left:' . $indent . 'px'));
                 $array_html_items[] = array($html_items);
             }
             // grids for items with paginations
@@ -1440,7 +1443,7 @@ class MessageManager
             );
             if (!empty($array_html_items)) {
                 $html .= Display::return_sortable_grid(
-                    'items_'.$topic['id'],
+                    'items_' . $topic['id'],
                     array(),
                     $array_html_items,
                     $options,
@@ -1457,7 +1460,7 @@ class MessageManager
 
     /**
      * Add children to messages by id is used for nested view messages
-     * @param array  $rows rows of messages
+     * @param array $rows rows of messages
      * @return array $first_seed new list adding the item children
      */
     public static function calculate_children($rows, $first_seed)
@@ -1500,8 +1503,8 @@ class MessageManager
 
     /**
      * Sort date by desc from a multi-dimensional array
-     * @param array $array1  first array to compare
-     * @param array $array2  second array to compare
+     * @param array $array1 first array to compare
+     * @param array $array2 second array to compare
      * @return bool
      */
     public function order_desc_date($array1, $array2)
@@ -1511,8 +1514,8 @@ class MessageManager
 
     /**
      * Get array of links (download) for message attachment files
-     * @param int  		$message_id
-     * @param string	$type message list (inbox/outbox)
+     * @param int $message_id
+     * @param string $type message list (inbox/outbox)
      * @return array
      */
     public static function get_links_message_attachment_files($message_id, $type = '')
@@ -1530,14 +1533,14 @@ class MessageManager
             $rs_file = Database::query($sql);
             if (Database::num_rows($rs_file) > 0) {
                 $attach_icon = Display::return_icon('attachment.gif', '');
-                $archiveURL = api_get_path(WEB_CODE_PATH).'messages/download.php?type='.$type.'&file=';
+                $archiveURL = api_get_path(WEB_CODE_PATH) . 'messages/download.php?type=' . $type . '&file=';
                 while ($row_file = Database::fetch_array($rs_file)) {
                     $archiveFile = $row_file['path'];
                     $filename = $row_file['filename'];
                     $filesize = format_file_size($row_file['size']);
                     $filecomment = Security::remove_XSS($row_file['comment']);
                     $filename = Security::remove_XSS($filename);
-                    $links_attach_file[] = $attach_icon.'&nbsp;<a href="'.$archiveURL.$archiveFile.'">'.$filename.'</a>&nbsp;('.$filesize.')'.(!empty($filecomment) ? '&nbsp;-&nbsp;<i>'.$filecomment.'</i>' : '');
+                    $links_attach_file[] = $attach_icon . '&nbsp;<a href="' . $archiveURL . $archiveFile . '">' . $filename . '</a>&nbsp;(' . $filesize . ')' . (!empty($filecomment) ? '&nbsp;-&nbsp;<i>' . $filecomment . '</i>' : '');
                 }
             }
         }
@@ -1546,7 +1549,7 @@ class MessageManager
 
     /**
      * Get message list by id
-     * @param int  $message_id
+     * @param int $message_id
      * @return array
      */
     public static function get_message_by_id($message_id)
@@ -1554,7 +1557,7 @@ class MessageManager
         $tbl_message = Database::get_main_table(TABLE_MESSAGE);
         $message_id = intval($message_id);
         $sql = "SELECT * FROM $tbl_message
-                WHERE id = '$message_id' AND msg_status <> '".MESSAGE_STATUS_DELETED."' ";
+                WHERE id = '$message_id' AND msg_status <> '" . MESSAGE_STATUS_DELETED . "' ";
         $res = Database::query($sql);
         $item = array();
         if (Database::num_rows($res) > 0) {
@@ -1603,7 +1606,7 @@ class MessageManager
 
         if (isset($_REQUEST['action'])) {
             switch ($_REQUEST['action']) {
-                 case 'mark_as_unread' :
+                case 'mark_as_unread' :
                     $number_of_selected_messages = count($_POST['id']);
                     if (is_array($_POST['id'])) {
                         foreach ($_POST['id'] as $index => $message_id) {
@@ -1680,7 +1683,7 @@ class MessageManager
 
         Session::write('message_sent_search_keyword', $keyword);
 
-        $success = get_lang('SelectedMessagesDeleted').'&nbsp</b><br /><a href="outbox.php?'.$social_link.'">'.get_lang('BackToOutbox').'</a>';
+        $success = get_lang('SelectedMessagesDeleted') . '&nbsp</b><br /><a href="outbox.php?' . $social_link . '">' . get_lang('BackToOutbox') . '</a>';
 
         $html = null;
         if (isset($_REQUEST['action'])) {
@@ -1696,7 +1699,7 @@ class MessageManager
                     break;
                 case 'deleteone' :
                     MessageManager::delete_message_by_user_receiver(api_get_user_id(), $_GET['id']);
-                    $html .=Display::return_message(api_xml_http_response_encode($success), 'normal', false);
+                    $html .= Display::return_message(api_xml_http_response_encode($success), 'normal', false);
                     $html .= '<br/>';
                     break;
             }
@@ -1885,4 +1888,67 @@ class MessageManager
             );
         }
     }
+
+    /**
+     * Get the error log from failed mailing
+     * @return array|bool
+     */
+    public static function failedSentMailErrors()
+    {
+        $base = api_get_path(SYS_ARCHIVE_PATH) . 'mail/';
+        $mailq = $base . 'mailq';
+
+        if (!file_exists($mailq) || !is_readable($mailq)) {
+            return false;
+        }
+
+        $file = fopen($mailq, 'r');
+        $i = 1;
+        while (!feof($file)) {
+            $line = fgets($file);
+            //$line = trim($line);
+
+            if (trim($line) == '') {
+                continue;
+            }
+
+            //Get the mail code, something like 1WBumL-0002xg-FF
+            if (preg_match('/(.*)\s((.*)-(.*)-(.*))\s<(.*)$/', $line, $codeMatches)) {
+                $mail_queue[$i]['code'] = $codeMatches[2];
+            }
+
+            $fullMail = $base . $mail_queue[$i]['code'];
+            $mailFile = fopen($fullMail, 'r');
+
+            //Get the reason of mail fail
+            $iX = 1;
+
+            while (!feof($mailFile)) {
+                $mailLine = fgets($mailFile);
+                #if ($iX == 4 && preg_match('/(.*):\s(.*)$/', $mailLine, $matches)) {
+                if (
+                    $iX == 2 &&
+                    preg_match('/(.*)(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\s(.*)/', $mailLine, $detailsMatches)
+                ) {
+                    $mail_queue[$i]['reason'] = $detailsMatches[3];
+                }
+
+                $iX++;
+            }
+
+            fclose($mailFile);
+
+            //Get the time of mail fail
+            if (preg_match('/^\s?(\d+)(\D+)\s+(.*)$/', $line, $timeMatches)) {
+                $mail_queue[$i]['time'] = $timeMatches[1] . $timeMatches[2];
+            } elseif (preg_match('/^(\s+)((.*)@(.*))\s+(.*)$/', $line, $emailMatches)) {
+                $mail_queue[$i]['mail'] = $emailMatches[2];
+                $i++;
+            }
+        }
+
+        fclose($file);
+
+        return array_reverse($mail_queue);
+    }
 }

+ 9 - 3
main/inc/lib/sessionmanager.lib.php

@@ -5016,7 +5016,6 @@ class SessionManager
         }
 
         $urlId = api_get_current_access_url_id();
-
         $sessionConditions = null;
         $courseConditions = null;
         $userConditions = null;
@@ -5026,6 +5025,13 @@ class SessionManager
             $userConditions .= " AND active = $active";
         }
 
+        $courseList = CourseManager::get_courses_followed_by_drh($userId, DRH);
+        $courseConditions = ' AND 1 <> 1';
+        if (!empty($courseList)) {
+            $courseIdList = array_column($courseList, 'id');
+            $courseConditions = ' AND c.id IN ("'.implode('","', $courseIdList).'")';
+        }
+
         switch ($status) {
             case 'drh':
                 // Classic DRH
@@ -5116,8 +5122,7 @@ class SessionManager
                     INNER JOIN $tbl_session_rel_access_url url ON (url.session_id = s.id)
                     $where
                     $sessionConditions
-                )
-                UNION (
+                ) UNION (
                     $select
                     FROM $tbl_course c
                     INNER JOIN $tbl_course_user cu ON (cu.c_id = c.id)
@@ -5145,6 +5150,7 @@ class SessionManager
         }
 
         $sql .= $limitCondition;
+
         $result = Database::query($sql);
         $result = Database::store_result($result);
 

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

@@ -327,6 +327,7 @@ class Statistics
                     $row[6] = get_lang('Unknown');
                 }
             }
+
             $activities[] = $row;
         }
 

+ 10 - 5
main/inc/lib/template.lib.php

@@ -533,7 +533,6 @@ class Template
         }
 
         // Default CSS Bootstrap
-
         $bowerCSSFiles = [
             'bootstrap-daterangepicker/daterangepicker-bs3.css',
             'fontawesome/css/font-awesome.min.css',
@@ -568,14 +567,20 @@ class Template
             $this->assign('css_static_file_to_string', $css_file_to_string);
         }
     }
-    public function setCSSEditor() {
+
+    /**
+     *
+     */
+    public function setCSSEditor()
+    {
         $cssEditor = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'editor.css');
-            if (is_file(api_get_path(SYS_CSS_PATH).'themes/'.$this->theme.'/editor.css')) {
-                $cssEditor = api_get_path(WEB_CSS_PATH).'themes/'.$this->theme.'/editor.css';
-            }
+        if (is_file(api_get_path(SYS_CSS_PATH).'themes/'.$this->theme.'/editor.css')) {
+            $cssEditor = api_get_path(WEB_CSS_PATH).'themes/'.$this->theme.'/editor.css';
+        }
 
         $this->assign('cssEditor', $cssEditor);
     }
+
     /**
      * Prepare custom CSS to be added at the very end of the <head> section
      * @return void

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

@@ -1958,7 +1958,7 @@ class UserManager
                     0 => $rowf['id'],
                     1 => $rowf['variable'],
                     2 => $rowf['field_type'],
-                    3 => (empty($rowf['display_text']) ? '' : $rowf['display_text']),
+                    3 => empty($rowf['display_text']) ? '' : $rowf['display_text'],
                     4 => $rowf['default_value'],
                     5 => $rowf['field_order'],
                     6 => $rowf['visible'],
@@ -1977,7 +1977,7 @@ class UserManager
                         $fields[$rowf['id']][9][$rowo['id']] = array(
                             0 => $rowo['id'],
                             1 => $rowo['option_value'],
-                            2 => (empty($rowo['display_text']) ? '' : $rowo['display_text']),
+                            2 => empty($rowo['display_text']) ? '' : $rowo['display_text'],
                             3 => $rowo['option_order']
                         );
                     }
@@ -2112,7 +2112,7 @@ class UserManager
 
     /**
      * Check if a field is available
-     * @param    string    th$variable
+     * @param    string    $variable
      * @return    boolean
      */
     public static function is_extra_field_available($variable)

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

@@ -448,7 +448,7 @@ class IndexManager
         // Initialization.
         $user_identified = (api_get_user_id() > 0 && !api_is_anonymous());
         $web_course_path = api_get_path(WEB_COURSE_PATH);
-        $category = Database::escape_string($_GET['category']);
+        $category = isset($_GET['category']) ? Database::escape_string($_GET['category']) : '';
         $setting_show_also_closed_courses = api_get_setting('show_closed_courses') == 'true';
 
         // Database table definitions.
@@ -457,7 +457,7 @@ class IndexManager
 
         // Get list of courses in category $category.
         $sql_get_course_list = "SELECT * FROM $main_course_table cours
-                                    WHERE category_code = '".Database::escape_string($_GET['category'])."'
+                                    WHERE category_code = '" . $category . "'
                                     ORDER BY title, UPPER(visual_code)";
 
         // Showing only the courses of the current access_url_id.

+ 4 - 0
main/install/data.sql

@@ -1885,3 +1885,7 @@ INSERT INTO settings_options (variable, value, display_text) VALUES ('show_offic
 INSERT INTO access_url_rel_course_category (access_url_id, course_category_id) VALUES (1, 1);
 INSERT INTO access_url_rel_course_category (access_url_id, course_category_id) VALUES (1, 2);
 INSERT INTO access_url_rel_course_category (access_url_id, course_category_id) VALUES (1, 3);
+
+UPDATE settings_current SET selected_value = '1.11.0.5' WHERE variable = 'chamilo_database_version';
+
+INSERT INTO extra_field (extra_field_type, field_type, variable, display_text, visible, changeable, created_at) VALUES (8, 10, 'tags', 'Tags', 1, 1, NOW());

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

@@ -1487,7 +1487,6 @@ $TitleManipulateStudentPublication = "عالج المنشور الحالي لل
 $EnterDataNewChapter = "أدخل بيانات الفقرة الجديدة";
 $EnterDataNewModule = "أدخل بيانات الوحدة الجديدة";
 $CreateNewStep = ": قم بإنشاء خطوة جديدة";
-$NewDocument = "مستند جديد";
 $UseAnExistingResource = ": أو استخدم مورد موجود";
 $Position = "لموضعا";
 $NewChapterCreated = ".تم إنشاء الفقرة الجديدة. بإمكانك الآن إضافة خطوة إليها أو إضافة فقرة أخرى";

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

@@ -1986,7 +1986,6 @@ $TitleManipulateStudentPublication = "Modificar el trabayu actual";
 $EnterDataNewChapter = "Escriba los datos del módulu nuevu";
 $EnterDataNewModule = "Escriba los datos del módulu nuevu";
 $CreateNewStep = "Crear un recursu nuevu :";
-$NewDocument = "Documentu nuevu";
 $UseAnExistingResource = "O usar un recursu que yá esiste :";
 $Position = "Posición";
 $NewChapterCreated = "El módulu nuevu creóse. Agora pue amestar un elementu o crear otru módulu.";

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

@@ -2048,7 +2048,6 @@ $TitleManipulateStudentPublication = "Editatu egin beharreko lana";
 $EnterDataNewChapter = "Sartu atalaren ezaugarriak";
 $EnterDataNewModule = "Sartu atalaren inguruko informazioa";
 $CreateNewStep = "Sortu beste urrats bat";
-$NewDocument = "Dokumentu berria";
 $UseAnExistingResource = "Edo erabili lehendik badagoen baliabide bat";
 $Position = "Kokalekua";
 $NewChapterCreated = "Oraintxe atal bat sortu da. Beste atal bat edo beste ikaskuntza objketuak gehitzen jarraitu dezakezu.";

+ 107 - 1
main/lang/brazilian/trad4all.inc.php

@@ -2476,7 +2476,7 @@ $TitleManipulateStudentPublication = "Manipular o trabalho atual";
 $EnterDataNewChapter = "Enviar informação para o novo capítulo";
 $EnterDataNewModule = "Enviar informação para o novo módulo";
 $CreateNewStep = "Criar uma nova etapa:";
-$NewDocument = "Novo documento";
+$TicketUpdated = "Ticket atualizada";
 $UseAnExistingResource = "Ou usar um recurso existente:";
 $Position = "Posição";
 $NewChapterCreated = "O novo capítulo foi criado. Agora pode acrescentar um novo capítulo ou etapa.";
@@ -5961,6 +5961,7 @@ $Off = "Off";
 $webserver = "servidor Web";
 $mysql = "MySQL";
 $NotInserted = "Não é inserido";
+$StudentBoss = "Superior (n+1)";
 $EnableMathJaxComment = "Ativar MathJax editor matemático.";
 $YouCanNowLoginAtXUsingTheLoginAndThePasswordYouHaveProvided = "Agora você pode fazer login em%s usando o login ea senha que você forneceu.";
 $HaveFun = "Divirta-se";
@@ -7595,4 +7596,109 @@ $StartRecordingAudio = "Comece a gravar";
 $StopRecordingAudio = "Parar a gravação";
 $SaveRecordedAudio = "Salvar o áudio gravado";
 $GradeFromX = "Grades de curso: %s";
+$TitleMandatory = "Um título é necessário";
+$NoCourseCategorySupplied = "Nenhuma categoria do curso foi fornecida";
+$ForumStartDate = "Data de publicação";
+$ForumEndDate = "Data de encerramento";
+$ForumStartDateComment = "O fórum será visível a partir desta data";
+$ForumEndDateComment = "Uma vez que esta data já passou, o fórum será fechado";
+$ModeratedForum = "Fórum moderado";
+$DiagnosisFilledSubject = "Diagnóstico preenchido com sucesso";
+$DiagnosisFilledDescription = "O diagnóstico foi preenchido com sucesso";
+$UserXHasFilledTheDiagnosis = "Usuário %s encheu o diagnóstico";
+$UserXHasFilledTheDiagnosisDescription = "Usuário %s encheu o diagnóstico na plataforma e que está pronto para você analisar.";
+$SendLegal = "Enviar acordo legal";
+$DeleteLegal = "Excluir acordo legal";
+$LegalAccepted = "Legal aceites";
+$LoadTermConditionsSectionTitle = "Seção de condições duração de carga";
+$LoadTermConditionsSectionDescription = "O acordo legal aparecerá durante o login ou quando entrar para um curso.";
+$SendTermsSubject = "Os seus termos e condições está pronto para ser assinado";
+$SendTermsDescriptionToUrlX = "Olá, seu tutor lhe enviou seus termos e condições. Você pode assinar no seguinte endereço: %s";
+$UserXSignedTheAgreement = "Usuário %s assinaram o acordo.";
+$UserXSignedTheAgreementTheY = "Usuário %s assinaram o acordo a %s.";
+$ShowTermsIfProfileCompletedTitle = "Termos e condições só com perfil completo";
+$ShowTermsIfProfileCompletedComment = "Ao ativar esta opção, termos e condições estarão disponíveis para o usuário apenas quando os campos de perfil extras que começam com 'termos_' e definidos para visíveis estão concluídas.";
+$EnableProfileUsersAddressGeolocalizationTitle = "Ativar geolocalização do usuário";
+$EnableProfileUsersAddressGeolocalizationComment = "Ativar campo de endereço do usuário e mostrá-la em um mapa usando os recursos de geolocalização";
+$ProfileIsNotCompleted = "Primeiro, você deve preencher o seu perfil para continuar";
+$TermActivatedIsNeededDescription = "Os termos e condições ainda não foram validados pelo seu tutor.";
+$DiagnosisManagement = "Gestão de diagnóstico";
+$TermYourProfileIsNotCompleted = "Primeiro, você deve preencher o seu perfil para permitir a validação termos e condições.";
+$Diagnostic = "Diagnóstico";
+$AllowShowSkypeAccountTitle = "Permitir que mostram a conta Skype do usuário";
+$AllowShowSkypeAccountComment = "Adicionar um link no bloco sociais do usuário permitindo iniciar uma conversa por Skype";
+$AllowShowLinkedInUrlTitle = "Permitir mostrar ao usuário LinkedIn URL";
+$AllowShowLinkedInUrlComment = "Adicionar um link no bloco sociais do usuário, permitindo visitar perfil LinkedIn do usuário";
+$LaunchVideoConferenceRoom = "Sala de videoconferência de lançamento";
+$VideoConference = "Vídeoconferência";
+$TermsDuplicatedInFile = "Termos duplicado em arquivo";
+$GlossaryTermAlreadyExists = "Prazo já existe";
+$LinkedInUrl = "LinkedIn URL de perfil";
+$SaveTheCorrectAnswersForTheNextAttempt = "Salvar a resposta correta para a próxima tentativa";
+$TranslateThisTerm = "Traduzir este termo";
+$OnlyActiveSubLanguagesAreListed = "Somente ativos sub-línguas aparecem nesta lista";
+$Translation = "Tradução";
+$IfThisTranslationExistsThisWillReplaceTheTerm = "Se este termo já foi traduzido, esta operação irá substituir a sua tradução para este sub-idioma.";
+$LastConnection = "Última conexão";
+$HisProfileIs = "Seu perfil é";
+$UserXWithLangXRegisteredTheSite = "Usuário %s com a linguagem %s está registado no site";
+$YouCanAssignATutorInThisLinkX = "Você pode atribuir um tutor nesta ligação %s";
+$UpdateExistingGlossaryTerms = "Atualizar termos existentes.";
+$TermsUpdated = "Termos atualizados";
+$TermsAdded = "Termos acrescentou";
+$TeacherTimeReportBySession = "Professores relatório de tempo por sessão";
+$NumberOfWorks = "Número de obras";
+$LastWork = "Último trabalho";
+$WaitingModeration = "À espera de moderação";
+$WorksInSessionReport = "Trabalha no relatório da sessão";
+$Files = "Arquivos";
+$AssignedTo = "Atribuído a";
+$UpdatedByX = "Atualizado por %s";
+$AssignedChangeFromXToY = "Cessionário alterado de %s para %s";
+$RequestConfirmation = "Confirmação do pedido";
+$ChangeAssign = "Mudança de atribuição";
+$ToBeAssigned = "A ser atribuído";
+$StatusNew = "Novo";
+$StatusPending = "Pendente";
+$StatusUnconfirmed = "Não confirmado";
+$StatusClose = "Fechar";
+$StatusForwarded = "Encaminhado";
+$MyTickets = "Meus tickets";
+$PriorityNormal = "Normal";
+$PriorityHigh = "Alto";
+$PriorityLow = "Médio";
+$TicketDetail = "Detalhes do ticket";
+$StatusAll = "Todos";
+$StatusUnread = "Não lida";
+$StatusRead = "Ler";
+$Projects = "Projects";
+$AssignUser = "Atribuir usuário";
+$TicketEnrollment = "Inscrição";
+$TicketGeneralInformation = "Informação geral";
+$TicketRequestAndPapework = "Os pedidos e documentos";
+$TicketAcademicIncidence = "Incidentes acadêmicos";
+$TicketVirtualCampus = "Campus virtual";
+$TicketOnlineEvaluation = "Avaliação on-line";
+$TicketsAboutEnrollment = "Bilhetes cerca de matrículas";
+$TicketsAboutGeneralInformation = "Bilhetes cerca de informação geral";
+$TicketsAboutRequestAndPapework = "Bilhetes cerca de pedidos e documentos";
+$TicketsAboutAcademicIncidence = "Bilhetes sobre incidentes acadêmicas, como exames, práticas, tarefas, etc.";
+$TicketsAboutVirtualCampus = "Bilhetes cerca de campus virtual";
+$TicketsAboutOnlineEvaluation = "Bilhetes cerca de avaliação on-line";
+$Assign = "Atribuir";
+$PersonalEmail = "E-mail pessoal";
+$Priority = "Prioridade";
+$Source = "Fonte";
+$SrcPlatform = "Plataforma";
+$SrcEmail = "O e-mail";
+$SrcPhone = "Telefone";
+$SrcPresential = "Presencial";
+$TicketXCreated = "Ticket %s criado";
+$ShowLinkTicketNotificationTitle = "Mostrar link criação do bilhete";
+$ShowLinkTicketNotificationComment = "Mostrar o link criação de ingresso para os usuários no lado direito do portal";
+$LastSentWorkDate = "Última data de trabalho enviado";
+$SSOSubclassTitle = "Único sinal na subclasse";
+$SSOSubclassComment = "Para habilitar um Single Sign On método, você terá que criar o seu próprio sub-classe no main / auth / sso / com base na classe padrão. Indique o nome da sub-classe. Por exemplo, se o arquivo é sso.Drupal.class.php, indicam 'Drupal\" neste campo.";
+$CourseCreationSplashScreenTitle = "Tela de abertura criação do curso";
+$CourseCreationSplashScreenComment = "A tela inicial do curso de mostrar uma série de opções sugeridas para o professor na criação de um novo curso. Desativá-lo para permitir que seus professores pousar diretamente na página inicial do curso.";
 ?>

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

@@ -1972,7 +1972,6 @@ $TitleManipulateStudentPublication = "Работа с текущата публ
 $EnterDataNewChapter = "Въвеждане на данни за новия модул";
 $EnterDataNewModule = "Въвеждане на данни за новия модул";
 $CreateNewStep = "Създаване на стъпка:";
-$NewDocument = "Нов документ";
 $UseAnExistingResource = "Или да се използва съществуващ ресурс:";
 $Position = "Позиция";
 $NewChapterCreated = "Новият модул е създаден. В него можете да добавите друг модул или стъпка.";

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

@@ -2322,7 +2322,6 @@ $TitleManipulateStudentPublication = "Modificar l'actual treball";
 $EnterDataNewChapter = "Introduïu les dades del nou apartat";
 $EnterDataNewModule = "Introduïu les dades del nou apartat";
 $CreateNewStep = "Creeu un nou recurs";
-$NewDocument = "Nou document";
 $UseAnExistingResource = "O utilitzeu un recurs existent:";
 $Position = "Posició";
 $NewChapterCreated = "El nou apartat ha estat creat. Ara podeu afegir-hi un recurs o bé crear un altre apartat.";

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

@@ -1308,7 +1308,6 @@ $TitleManipulateStudentPublication = "Upravljanje s trenutnim studentskim radom"
 $EnterDataNewChapter = "Unesite podatke za novo poglavlje";
 $EnterDataNewModule = "Unesite podatke za novi modul";
 $CreateNewStep = "Napravi novi korak :";
-$NewDocument = "Novi dokument";
 $UseAnExistingResource = "Ili upotrijebite postojeći skup podataka :";
 $Position = "Pozicija";
 $NewChapterCreated = "Napravljeno je novo poglavlje. Sada mu možete pridodati sljedeće poglavlje ili korak.";

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

@@ -1358,7 +1358,6 @@ $TitleManipulateStudentPublication = "Håndter den aktuelle aflevering";
 $EnterDataNewChapter = "Indtast informationerne om det nye kapitel";
 $EnterDataNewModule = "Indtast informationerne om det nye kapitel";
 $CreateNewStep = "Opret et nyt trin";
-$NewDocument = "Nyt dokument";
 $UseAnExistingResource = "Eller anvend en eksisterende ressource";
 $Position = "Postition";
 $NewChapterCreated = "Det nye kapitel er oprettet. Du kan nu tilføje et nyt kapitel eller tilføje trin til kapitlet";

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

@@ -2042,7 +2042,6 @@ $TitleManipulateStudentPublication = "Dit document wijzigen";
 $EnterDataNewChapter = "Informatie van het nieuwe hoofdstuk ingeven";
 $EnterDataNewModule = "Informatie van de nieuwe module ingeven";
 $CreateNewStep = "Nieuwe stap aanmaken:";
-$NewDocument = "Nieuw document";
 $UseAnExistingResource = "of gebruik bestaand materiaal :";
 $Position = "Positie";
 $NewChapterCreated = "Het nieuwe hoofdstuk is aangemaakt. U kunt nu nog een hoofdstuk aanmaken of een nieuwe stap toevoegen aan het zopas aangemaakte hoofdstuk.";

+ 115 - 112
main/lang/english/trad4all.inc.php

@@ -325,18 +325,18 @@ $DeleteUsersNotInList = "Unsubscribe students which are not in the imported list
 $IfSessionExistsUpdate = "If a session exists, update it";
 $CreatedByXYOnZ = "Create by <a href=\"%s\">%s</a> on %s";
 $LoginWithExternalAccount = "Login without an institutional account";
-$ImportAikenQuizExplanationExample = "This is the text for question 1
-A. Answer 1
-B. Answer 2
-C. Answer 3
-ANSWER: B
-
-This is the text for question 2
-A. Answer 1
-B. Answer 2
-C. Answer 3
-D. Answer 4
-ANSWER: D
+$ImportAikenQuizExplanationExample = "This is the text for question 1
+A. Answer 1
+B. Answer 2
+C. Answer 3
+ANSWER: B
+
+This is the text for question 2
+A. Answer 1
+B. Answer 2
+C. Answer 3
+D. Answer 4
+ANSWER: D
 ANSWER_EXPLANATION: this is an optional feedback comment that will appear next to the correct answer.";
 $ImportAikenQuizExplanation = "The Aiken format comes in a simple text (.txt) file, with several question blocks, each separated by a blank line. The first line is the question, the answer lines are prefixed by a letter and a dot, and the correct answer comes next with the ANSWER: prefix. See example below.";
 $ExerciseAikenErrorNoAnswerOptionGiven = "The imported file has at least one question without any answer (or the answers do not include the required prefix letter). Please make sure each question has at least one answer and that it is prefixed by a letter and a dot or a parenthesis, like this: A. answer one";
@@ -425,18 +425,18 @@ $VersionUpToDate = "Your version is up-to-date";
 $LatestVersionIs = "The latest version is";
 $YourVersionNotUpToDate = "Your version is not up-to-date";
 $Hotpotatoes = "Hotpotatoes";
-$ZeroMeansNoQuestionWillBeSelectedMinusOneMeansThatAllQuestionsWillBeSelected = "-1 = All questions will be selected.
+$ZeroMeansNoQuestionWillBeSelectedMinusOneMeansThatAllQuestionsWillBeSelected = "-1 = All questions will be selected.
  0 = No questions will be selected.";
-$EmailNotificationTemplateDescription = "You can customize the email sent to users when they finished the exercise. You can use tags like these:
-
-1. {{ student.username }}
-2. {{ student.firstname }}
-3. {{ student.lastname }}
-4. {{ student.official_code }}
-5. {{ exercise.title }}
-6. {{ exercise.start_time }}
-7. {{ exercise.end_time }}
-8. {{ course.title }}
+$EmailNotificationTemplateDescription = "You can customize the email sent to users when they finished the exercise. You can use tags like these:
+
+1. {{ student.username }}
+2. {{ student.firstname }}
+3. {{ student.lastname }}
+4. {{ student.official_code }}
+5. {{ exercise.title }}
+6. {{ exercise.start_time }}
+7. {{ exercise.end_time }}
+8. {{ course.title }}
 9. {{ course.code }}";
 $EmailNotificationTemplate = "Email notification template";
 $ExerciseEndButtonDisconnect = "Logout";
@@ -844,10 +844,10 @@ $AllowVisitors = "Allow visitors";
 $EnableIframeInclusionComment = "Allowing arbitrary iframes in the HTML Editor will enhance the edition capabilities of the users, but it can represent a security risk. Please make sure you can rely on your users (i.e. you know who they are) before enabling this feature.";
 $AddedToLPCannotBeAccessed = "This exercise has been included in a learning path, so it cannot be accessed by students directly from here. If you want to put the same exercise available through the exercises tool, please make a copy of the current exercise using the copy icon.";
 $EnableIframeInclusionTitle = "Allow iframes in HTML Editor";
-$MailTemplateRegistrationMessage = "Dear ((firstname)) ((lastname)),\n\nYou are registered on
-((sitename)) with the following settings:\n\nUsername :
-((username))\nPass : ((password))\n\nThe address of ((sitename)) is :
-((url))\n\nIn case of trouble, contact us.\n\nYours sincerely
+$MailTemplateRegistrationMessage = "Dear ((firstname)) ((lastname)),\n\nYou are registered on
+((sitename)) with the following settings:\n\nUsername :
+((username))\nPass : ((password))\n\nThe address of ((sitename)) is :
+((url))\n\nIn case of trouble, contact us.\n\nYours sincerely
 \n((admin_name)) ((admin_surname)).";
 $Explanation = "Once you click on \"Create a course\", a course is created with a section for Tests, Project based learning, Assessments, Courses, Dropbox, Agenda and much more. Logging in as teacher provides you with editing privileges for this course.";
 $CodeTaken = "This course code is already in use.<br>Use the <b>Back</b> button on your browser and try again.";
@@ -2640,16 +2640,16 @@ $NoPosts = "No posts";
 $WithoutAchievedSkills = "Without achieved skills";
 $TypeMessage = "Please type your message!";
 $ConfirmReset = "Do you really want to delete all messages?";
-$MailCronCourseExpirationReminderBody = "Dear %s,
-
-It has come to our attention that you have not completed the course %s although its expiration date had been set on %s, remaining %s days to finish it.
-
-We remind you that you have only the possibility to follow this course once a year, that is why we invite you insistently to complete your course on time.
-
-You can return to the course connecting to the platform through this address: %s
-
-Best Regards,
-
+$MailCronCourseExpirationReminderBody = "Dear %s,
+
+It has come to our attention that you have not completed the course %s although its expiration date had been set on %s, remaining %s days to finish it.
+
+We remind you that you have only the possibility to follow this course once a year, that is why we invite you insistently to complete your course on time.
+
+You can return to the course connecting to the platform through this address: %s
+
+Best Regards,
+
 %s Team";
 $MailCronCourseExpirationReminderSubject = "Urgent: %s course expiration reminder";
 $ExerciseAndLearningPath = "Exercise and learning path";
@@ -5778,8 +5778,8 @@ $CheckThatYouHaveEnoughQuestionsInYourCategories = "Make sure you have enough qu
 $PortalCoursesLimitReached = "Sorry, this installation has a courses limit, which has now been reached. To increase the number of courses allowed on this Chamilo installation, please contact your hosting provider or, if available, upgrade to a superior hosting plan.";
 $PortalTeachersLimitReached = "Sorry, this installation has a teachers limit, which has now been reached. To increase the number of teachers allowed on this Chamilo installation, please contact your hosting provider or, if available, upgrade to a superior hosting plan.";
 $PortalUsersLimitReached = "Sorry, this installation has a users limit, which has now been reached. To increase the number of users allowed on this Chamilo installation, please contact your hosting provider or, if available, upgrade to a superior hosting plan.";
-$GenerateSurveyAccessLinkExplanation = "By copying the link below and pasting it in an e-mail or on a website, you will allow any anonymous person to enter and answer this survey.
-You can test this feature by clicking the link above and answering the survey.
+$GenerateSurveyAccessLinkExplanation = "By copying the link below and pasting it in an e-mail or on a website, you will allow any anonymous person to enter and answer this survey.
+You can test this feature by clicking the link above and answering the survey.
 This is particularly useful if you want to allow anyone on a forum to answer you survey and you don't know their e-mail addresses.";
 $LinkOpenSelf = "Open self";
 $LinkOpenBlank = "Open blank";
@@ -5832,8 +5832,8 @@ $Item = "Item";
 $ConfigureDashboardPlugin = "Configure Dashboard Plugin";
 $EditBlocks = "Edit blocks";
 $Never = "Never";
-$YourAccountIsActiveYouCanLoginAndCheckYourCourses = "Dear user, 
-
+$YourAccountIsActiveYouCanLoginAndCheckYourCourses = "Dear user, 
+
 Your account has now been activated on the platform. Please login and enjoy your courses.";
 $SessionFields = "Session fields";
 $CopyLabelSuffix = "Copy";
@@ -5895,7 +5895,7 @@ $CourseSettingsRegisterDirectLink = "If your course is public or open, you can u
 $DirectLink = "Direct link";
 $here = "here";
 $GoAheadAndBrowseOurCourseCatalogXOnceRegisteredYouWillSeeTheCourseHereX = "<p>Go ahead and browse our course catalog %s to register to any course you like. Once registered, you will see the course appear right %s, instead of this message.</p>";
-$HelloXAsYouCanSeeYourCourseListIsEmpty = "<p>Hello <strong>%s</strong> and welcome,</p>
+$HelloXAsYouCanSeeYourCourseListIsEmpty = "<p>Hello <strong>%s</strong> and welcome,</p>
 <p>As you can see, your courses list is still empty. That's because you are not registered to any course yet! </p>";
 $UnsubscribeUsersAlreadyAddedInCourse = "Unsubscribe users already added";
 $ImportUsers = "Import users";
@@ -6159,7 +6159,7 @@ $AverageScore = "Average score";
 $LastConnexionDate = "Last connexion date";
 $ToolVideoconference = "Videoconference";
 $BigBlueButtonEnableTitle = "BigBlueButton videoconference tool";
-$BigBlueButtonEnableComment = "Choose whether you want to enable the BigBlueButton videoconference tool. Once enabled, it will show as an additional course tool in all courses' homepage, and teachers will be able to launch a conference at any time. Learners will not be able to launch a conference, only join one. If you don't have a BigBlueButton server, please <a href=\"http://bigbluebutton.org/\" target=\"_blank\">set one up</a> or ask the <a href=\"http://www.chamilo.org/en/providers\" target=\"_blank\">Chamilo official providers</a> for a quote.
+$BigBlueButtonEnableComment = "Choose whether you want to enable the BigBlueButton videoconference tool. Once enabled, it will show as an additional course tool in all courses' homepage, and teachers will be able to launch a conference at any time. Learners will not be able to launch a conference, only join one. If you don't have a BigBlueButton server, please <a href=\"http://bigbluebutton.org/\" target=\"_blank\">set one up</a> or ask the <a href=\"http://www.chamilo.org/en/providers\" target=\"_blank\">Chamilo official providers</a> for a quote.
 BigBlueButton is a free (as in freedom *and* beer), but its installation requires a set of technical skills that might not be immediately available to all. You can install it on your own or seek professional help to assist you or do it for you. This help, however, will generate a certain cost. In the pure logic of the free software, we offer you the tools to make your work easier and recommend professionals (the Chamilo Official Providers) that will be able to help you if this were too difficult.";
 $BigBlueButtonHostTitle = "BigBlueButton server host";
 $BigBlueButtonHostComment = "This is the name of the server where your BigBlueButton server is running. Might be <i>localhost</i>, an IP address (e.g. 192.168.13.54) or a domain name (e.g. my.video.com).";
@@ -6170,14 +6170,14 @@ $OnlyAccessFromYourGroup = "Only accessible from your group";
 $CreateAssignmentPage = "This will create a special wiki page in which the teacher can describe the task and which will be automatically linked to the wiki pages where learners perform the task. Both the teacher's and the learners' pages are created automatically. In these tasks, learners can only edit and view theirs pages, but this can be changed easily if you need to.";
 $UserFolders = "Folders of users";
 $UserFolder = "User folder";
-$HelpUsersFolder = "INFORMATION VISIBLE TO THE TEACHER ONLY:\nThe users folder contains a folder for each user who has accessed it through the documents tool, or when any file has been sent in the course through the online editor. If neither circumstances has occurred, then no user folder will have been created. In the case of groups, files that are sent through the editor will be added in the folder of each group, which is only accessible by students from this group.
-<br /><br />
-The users folder and each of the included folders will be hidden by default in for all students, but each student can see the contents of his/her directory through the online editor. However, if a student knows the address of a file or folder of another student, he may be able to access it.
-<br /><br />
-If the folder of a student is visible, other students can see what it contains. In this case, the student that owns the folder can also (from the documents tool and only in his/her folder): create and edit web documents, convert a document into a template for personal use, create and edit drawings in SVG and PNG formats, record audio files in WAV format, make audio files in MP3 from a text, make snapshops from a webcam, send documents, create folders, move folders and files, delete folders and files, and download backup of his/her folder.
-<br /><br />
-Moreover, the documents tool is synchronized with the file manager of the online editor, so changes in the documents triggered in any one of these will affect both.
-<br /><br />
+$HelpUsersFolder = "INFORMATION VISIBLE TO THE TEACHER ONLY:\nThe users folder contains a folder for each user who has accessed it through the documents tool, or when any file has been sent in the course through the online editor. If neither circumstances has occurred, then no user folder will have been created. In the case of groups, files that are sent through the editor will be added in the folder of each group, which is only accessible by students from this group.
+<br /><br />
+The users folder and each of the included folders will be hidden by default in for all students, but each student can see the contents of his/her directory through the online editor. However, if a student knows the address of a file or folder of another student, he may be able to access it.
+<br /><br />
+If the folder of a student is visible, other students can see what it contains. In this case, the student that owns the folder can also (from the documents tool and only in his/her folder): create and edit web documents, convert a document into a template for personal use, create and edit drawings in SVG and PNG formats, record audio files in WAV format, make audio files in MP3 from a text, make snapshops from a webcam, send documents, create folders, move folders and files, delete folders and files, and download backup of his/her folder.
+<br /><br />
+Moreover, the documents tool is synchronized with the file manager of the online editor, so changes in the documents triggered in any one of these will affect both.
+<br /><br />
 As such, the user folder is not only a place to deposit files, it becomes a complete manager of the documents students use during the course. Also, remember that any user can copy a file that is visible from any folder in the documents tool (whether or not he is the owner) to his/her portfolios or personal documents area of social network, which will be available to him/her for use in other courses.";
 $HelpFolderChat = "INFORMATION VISIBLE TO THE TEACHER ONLY:\nThis folder contains all sessions that have been opened in the chat. Although the chat sessions can often be trivial, others can be really interesting and worthy of being incorporated as an additional work document. To do this without changing the visibility of this folder, make the file visible and link it from where you deem appropriate. It is not recommended to make this folder visible to all.";
 $HelpFolderCertificates = "INFORMATION VISIBLE TO THE TEACHER ONLY:\nThis folder contains the various certificates templates that have been created for the rating tool. It is not recommended to make this folder visible to all.";
@@ -6226,8 +6226,8 @@ $Pediaphon = "Use Pediaphon audio services";
 $HelpPediaphon = "Supports text with several thousands characters, in various types of male and female voices (depending on the language). Audio files will be generated and automatically saved to the Chamilo directory in which you are.";
 $FirstSelectALanguage = "Please select a language";
 $MoveUserStats = "Move users results from/to a session";
-$CompareUserResultsBetweenCoursesAndCoursesInASession = "This advanced tool allows you to manually improve the tracking of users results when moving from courses methodology to sessions methodology. In most cases, you won't need to use it.<br />
-On this screen, you can compare results of users between the context of a standalone course, and the context of the same course inside a session.<br />
+$CompareUserResultsBetweenCoursesAndCoursesInASession = "This advanced tool allows you to manually improve the tracking of users results when moving from courses methodology to sessions methodology. In most cases, you won't need to use it.<br />
+On this screen, you can compare results of users between the context of a standalone course, and the context of the same course inside a session.<br />
 Once you are sure about what to do, you can choose to move the tracking data of the students (exercises results and learning paths tracking) from a course to a session.";
 $PDFExportWatermarkEnableTitle = "Enable watermark in PDF export";
 $PDFExportWatermarkEnableComment = "By enabling this option, you can upload an image or a text that will be automatically added as watermark to all PDF exports of documents on the system.";
@@ -6362,8 +6362,8 @@ $MailNotifyInvitation = "Notify by mail on new invitation received";
 $MailNotifyMessage = "Notify by mail on new personal message received";
 $MailNotifyGroupMessage = "Notify by mail on new message received in group";
 $SearchEnabledTitle = "Fulltext search";
-$SearchEnabledComment = "This feature allows you to index most of the documents uploaded to your portal, then provide a search feature for users.<br />
-This feature will not index documents that have already been uploaded, so it is important to enable (if wanted) at the beginning of your implementation.<br />
+$SearchEnabledComment = "This feature allows you to index most of the documents uploaded to your portal, then provide a search feature for users.<br />
+This feature will not index documents that have already been uploaded, so it is important to enable (if wanted) at the beginning of your implementation.<br />
 Once enabled, a search box will appear in the courses list of every user. Searching for a specific term will bring a list of corresponding documents, exercises or forum topics, filtered depending on the availability of these contents to the user.";
 $SpecificSearchFieldsAvailable = "Available custom search fields";
 $XapianModuleInstalled = "Xapian module installed";
@@ -7009,45 +7009,45 @@ $ResourceLockedByGradebook = "This option is not available because this activity
 $GradebookLockedAlert = "This assessment has been locked. You cannot unlock it. If you really need to unlock it, please contact the platform administrator, explaining the reason why you would need to do that (it might otherwise be considered as fraud attempt).";
 $GradebookEnableLockingTitle = "Enable locking of assessments by teachers";
 $GradebookEnableLockingComment = "Once enabled, this option will enable locking of any assessment by the teachers of the corresponding course. This, in turn, will prevent any modification of results by the teacher inside the resources used in the assessment: exams, learning paths, tasks, etc. The only role authorized to unlock a locked assessment is the administrator. The teacher will be informed of this possibility. The locking and unlocking of gradebooks will be registered in the system's report of important activities";
-$LdapDescriptionComment = "    <div class=\"alert alert-info\">
-        <ul>
-            <li>LDAP authentication : <br>
-                See I. below to configure LDAP <br>
-                See II. below to activate LDAP authentication
-            </li>
-            <li>Update user attributes, with LDAP data, after CAS authentication(see <a href=\"settings.php?category=CAS\">CAS configuration </a>) : <br>
-                See I. below to configure LDAP <br>
-                CAS manage user authentication, LDAP activation isn't required.
-            </li>
-        </ul>
-    </div>
-    <h4>I. LDAP configuration</h4>
-    <h5>Edit file app/config/auth.conf.php </h5>
-    <p>-&gt; Edit values of array <code>\$extldap_config</code></p>
-    <ul>
-        <li>base domain string (ex : 'base_dn' =&gt; 'DC=cblue,DC=be')</li>
-        <li>admin distinguished name (ex : 'admin_dn' =&gt;'CN=admin,dc=cblue,dc=be')</li>
-        <li>admin password (ex : 'admin_password' =&gt; '123456') </li>
-        <li>ldap host (ex : 'host' =&gt; array('1.2.3.4', '2.3.4.5', '3.4.5.6'))</li>
-        <li>filter (ex : 'filter' =&gt; '') </li>
-        <li>port (ex : 'port' =&gt; 389) </li>
-        <li>protocol version (2 or 3) (ex : 'protocol_version' =&gt; 3)</li>
-        <li>user_search (ex : 'user_search' =&gt; 'sAMAccountName=%username%') </li>
-        <li>encoding (ex : 'encoding' =&gt; 'UTF-8')</li>
-        <li>update_userinfo (ex : 'update_userinfo' =&gt; true) </li>
-    </ul>
-    <p>-&gt; To update correspondences between user and LDAP attributes, edit array <code>\$extldap_user_correspondance</code></p>
-    <p>Array values are &lt;chamilo_field&gt; =&gt; &gt;ldap_field&gt;</p><p>
-    </p>
-    <h4>II. Activate LDAP authentication </h4>
-    <h5>Edit file main/inc/conf/configuration.php </h5>
-    <p>-&gt; Uncomment lines:</p>
-    <ul>
-        <li>
-    \$extAuthSource[\"extldap\"][\"login\"] = \$_configuration['root_sys'].\"main/auth/external_login/login.ldap.php\";</li>
-        <li>\$extAuthSource[\"extldap\"][\"newUser\"] = \$_configuration['root_sys'].\"main/auth/external_login/newUser.ldap.php\";</li>
-    </ul>
-    <p>N.B.: LDAP users use same fields than platform users to login. <br>
+$LdapDescriptionComment = "    <div class=\"alert alert-info\">
+        <ul>
+            <li>LDAP authentication : <br>
+                See I. below to configure LDAP <br>
+                See II. below to activate LDAP authentication
+            </li>
+            <li>Update user attributes, with LDAP data, after CAS authentication(see <a href=\"settings.php?category=CAS\">CAS configuration </a>) : <br>
+                See I. below to configure LDAP <br>
+                CAS manage user authentication, LDAP activation isn't required.
+            </li>
+        </ul>
+    </div>
+    <h4>I. LDAP configuration</h4>
+    <h5>Edit file app/config/auth.conf.php </h5>
+    <p>-&gt; Edit values of array <code>\$extldap_config</code></p>
+    <ul>
+        <li>base domain string (ex : 'base_dn' =&gt; 'DC=cblue,DC=be')</li>
+        <li>admin distinguished name (ex : 'admin_dn' =&gt;'CN=admin,dc=cblue,dc=be')</li>
+        <li>admin password (ex : 'admin_password' =&gt; '123456') </li>
+        <li>ldap host (ex : 'host' =&gt; array('1.2.3.4', '2.3.4.5', '3.4.5.6'))</li>
+        <li>filter (ex : 'filter' =&gt; '') </li>
+        <li>port (ex : 'port' =&gt; 389) </li>
+        <li>protocol version (2 or 3) (ex : 'protocol_version' =&gt; 3)</li>
+        <li>user_search (ex : 'user_search' =&gt; 'sAMAccountName=%username%') </li>
+        <li>encoding (ex : 'encoding' =&gt; 'UTF-8')</li>
+        <li>update_userinfo (ex : 'update_userinfo' =&gt; true) </li>
+    </ul>
+    <p>-&gt; To update correspondences between user and LDAP attributes, edit array <code>\$extldap_user_correspondance</code></p>
+    <p>Array values are &lt;chamilo_field&gt; =&gt; &gt;ldap_field&gt;</p><p>
+    </p>
+    <h4>II. Activate LDAP authentication </h4>
+    <h5>Edit file main/inc/conf/configuration.php </h5>
+    <p>-&gt; Uncomment lines:</p>
+    <ul>
+        <li>
+    \$extAuthSource[\"extldap\"][\"login\"] = \$_configuration['root_sys'].\"main/auth/external_login/login.ldap.php\";</li>
+        <li>\$extAuthSource[\"extldap\"][\"newUser\"] = \$_configuration['root_sys'].\"main/auth/external_login/newUser.ldap.php\";</li>
+    </ul>
+    <p>N.B.: LDAP users use same fields than platform users to login. <br>
     N.B.: LDAP activation adds a menu External authentication [LDAP] in \"add or modify\" user pages.</p>";
 $ShibbolethMainActivateTitle = "<h3>Shibboleth authentication</h3>";
 $ShibbolethMainActivateComment = "<p>First of all, you have to configure Shibboleth for your web server.</p>To configure it for Chamilo<h5>edit file main/auth/shibboleth/config/aai.class.php</h5><p>Modify object &#36;result values with the name of your Shibboleth attributes</p><ul><li>&#36;result-&gt;unique_id = 'mail';</li><li>&#36;result-&gt;firstname = 'cn';</li><li>&#36;result-&gt;lastname = 'uid';</li><li>&#36;result-&gt;email = 'mail';</li><li>&#36;result-&gt;language = '-';</li><li>&#36;result-&gt;gender = '-';</li><li>&#36;result-&gt;address = '-';</li><li>&#36;result-&gt;staff_category = '-';</li><li>&#36;result-&gt;home_organization_type = '-'; </li><li>&#36;result-&gt;home_organization = '-';</li><li>&#36;result-&gt;affiliation = '-';</li><li>&#36;result-&gt;persistent_id = '-';</li><li>...</li></ul><br/>Go to <a href='settings.php?category=Shibboleth'>Plugin</a> to add a configurable 'Shibboleth Login' button for your Chamilo campus.";
@@ -7157,7 +7157,7 @@ $TeacherAutosubscribeComment = "Teacher autosubscribe - not yet available";
 $DRHAutosubscribeTitle = "Human resources director autosubscribe";
 $DRHAutosubscribeComment = "Human resources director autosubscribe - not yet available";
 $ScormCumulativeSessionTimeTitle = "Cumulative session time for SCORM";
-$ScormCumulativeSessionTimeComment = "When enabled, the session time for SCORM learning paths will be cumulative, otherwise, it will only be counted from the last update time.";
+$ScormCumulativeSessionTimeComment = "When enabled, the session time for SCORM learning paths will be cumulative, otherwise, it will only be counted from the last update time. This is a global setting. It is used when creating a new learning path but can then be redefined for each learning path.";
 $SessionAdminPageAfterLoginTitle = "Session admin page after login";
 $SessionAdminPageAfterLoginComment = "Page to load after login for the session administrators";
 $SessionadminAutosubscribeTitle = "Session admin autosubscribe";
@@ -7478,12 +7478,12 @@ $AreYouSureToSubscribe = "Are you sure to subscribe?";
 $CheckYourEmailAndFollowInstructions = "Check your email and follow the instructions.";
 $LinkExpired = "Link expired, please try again.";
 $ResetPasswordInstructions = "Instructions for the password change procedure";
-$ResetPasswordCommentWithUrl = "You are receiving this message because you (or someone pretending to be you) have requested a new password to be generated for you.
-
-To set a the new password you need to activate it. To do this, please click this link:
-
-%s
-
+$ResetPasswordCommentWithUrl = "You are receiving this message because you (or someone pretending to be you) have requested a new password to be generated for you.
+
+To set a the new password you need to activate it. To do this, please click this link:
+
+%s
+
 If you did not request this procedure, then please ignore this message. If you keep receiving it, please contact the portal administrator.";
 $CronRemindCourseExpirationActivateTitle = "Remind Course Expiration cron";
 $CronRemindCourseExpirationActivateComment = "Enable the Remind Course Expiration cron";
@@ -7492,14 +7492,14 @@ $CronRemindCourseExpirationFrequencyComment = "Number of days before the expirat
 $CronCourseFinishedActivateText = "Course Finished cron";
 $CronCourseFinishedActivateComment = "Activate the Course Finished cron";
 $MailCronCourseFinishedSubject = "End of course %s";
-$MailCronCourseFinishedBody = "Dear %s,
-
-Thank you for your participation to course %s. We hope you've acquired new relevant knowledge and enjoyed the course.
-
-You can check your performance in the course through the My Progress section.
-
-Best regards,
-
+$MailCronCourseFinishedBody = "Dear %s,
+
+Thank you for your participation to course %s. We hope you've acquired new relevant knowledge and enjoyed the course.
+
+You can check your performance in the course through the My Progress section.
+
+Best regards,
+
 %s Team";
 $GenerateDefaultContent = "Generate default content";
 $ThanksForYourSubscription = "Thanks for your subscription";
@@ -7517,7 +7517,7 @@ $BlankInputSize = "Input size of box to fill";
 $DateFormatLongNoDayJS = "MM dd, yy";
 $TimeFormatNoSecJS = "HH:mm";
 $AtTime = " at";
-$SendSubscriptionNotification = "Send mail notification for subscription";
+$SendSubscriptionNotification = "Send mail notification to students to inform of subscription";
 $SendAnEmailWhenAUserBeingSubscribed = "Send an email when a user being subscribed to session";
 $SelectDate = "Select date";
 $OnlyLettersAndSpaces = "Only letters and spaces";
@@ -7721,8 +7721,8 @@ $LegalAccepted = "Legal accepted";
 $LoadTermConditionsSectionTitle = "Load term conditions section";
 $LoadTermConditionsSectionDescription = "The legal agreement will appear during the login or when enter to a course.";
 $SendTermsSubject = "Your terms and conditions are ready to be signed";
-$SendTermsDescriptionToUrlX = "Hello,
-
+$SendTermsDescriptionToUrlX = "Hello,
+
 Your tutor sent you your terms and conditions. You can sign it following this url: %s";
 $UserXSignedTheAgreement = "User %s signed the agreement.";
 $UserXSignedTheAgreementTheY = "User %s signed the agreement the %s.";
@@ -7811,4 +7811,7 @@ $SSOSubclassTitle = "Single Sign On sub-class";
 $SSOSubclassComment = "To enable a Single Sign On method, you will have to create your own sub-class in main/auth/sso/ based on the default class. Indicate here the name of the sub-class. For example, if the file is sso.Drupal.class.php, indicate 'Drupal' in this field.";
 $CourseCreationSplashScreenTitle = "Course creation splash screen";
 $CourseCreationSplashScreenComment = "The course splash screen show a series of suggested options to the teacher when creating a new course. Disable it to let your teachers land directly on the course homepage.";
+$WorksReport = "Assignments report";
+$AccumulateScormTime = "Accumulate SCORM session time";
+$AccumulateScormTimeInfo = "When enabled, the session time for SCORM learning paths will be cumulative, otherwise, it will only be counted from the last update time.";
 ?>

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

@@ -868,7 +868,6 @@ $TitleManipulateStudentPublication = "Muokkaa tehtävää";
 $EnterDataNewChapter = "Osion lisääminen tälle kurssille";
 $EnterDataNewModule = "Syötä osion tiedot";
 $CreateNewStep = "Luo uusi askel";
-$NewDocument = "Uusi dokumentti";
 $UseAnExistingResource = "Tai käytä jo olemassa olevaa resurssia:";
 $Position = "Sisällysluettelossa";
 $NewChapterCreated = "Uusi osio on luotu. Voit jatkaa lisäämällä osion tai askeleen.";

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

@@ -225,7 +225,7 @@ $AccountBlockedByCaptcha = "Compte bloqué par CAPTCHA";
 $CatchScreenCasts = "Capturer un screenshot/screencast";
 $View = "Visualiser";
 $AmountSubmitted = "Envoyés";
-$InstallWarningCouldNotInterpretPHP = "Attention: l'installateur a détecté une erreur au moment d'essayer de se connecter au fichier de test %s. Il semblerait que le script PHP n'ait pas pu être interprété. Ceci peut être un signe précurseur de problèmes à venir lors de la création d'îlots. Consultez le guide d'installation pour plus d'informations concernant les permissions. Si vous installez un site en configurant une URL qui n'est pas encore habilitée, vous pouvez probablement ignorer ce message.";
+$InstallWarningCouldNotInterpretPHP = "Attention: l'installateur a détecté une erreur au moment d'essayer de se connecter au fichier de test %s. Il semblerait que le script PHP n'ait pas pu être interprété. Ceci peut être un signe précurseur de problèmes à venir lors de la création de cours. Consultez le guide d'installation pour plus d'informations concernant les permissions. Si vous installez un site en configurant une URL qui n'est pas encore habilitée, vous pouvez probablement ignorer ce message.";
 $BeforeX = "Avant %s";
 $AfterX = "Après %s";
 $ExportSettingsAsXLS = "Exporter configuration en XLS";
@@ -240,7 +240,7 @@ $IncorrectScore = "Score réponse incorrecte";
 $CorrectScore = "Score réponse correcte";
 $UseCustomScoreForAllQuestions = "Utiliser le score sur mesure pour toutes les questions";
 $YouShouldAddItemsBeforeAttachAudio = "
-Vous devez ajouter des étapes à votre parcpours avant de pouvoir leur affecter des fichiers audio";
+Vous devez ajouter des étapes à votre parcours avant de pouvoir leur affecter des fichiers audio";
 $InactiveDays = "Joours inactifs";
 $FollowedHumanResources = "DRH suivis";
 $TheTextYouEnteredDoesNotMatchThePicture = "Le texte introduit ne correspond pas à l'image.";
@@ -7758,6 +7758,10 @@ $SSOSubclassTitle = "Single Sign On: Sous-classe";
 $SSOSubclassComment = "Pour activer une méthode de Single Sign On, vous devrez créer une sous-classe dans main/auth/sso/ basée sur la classe par défaut. Indiquez ici le nom de la sous-classe. Par exemple, si le fichier se nomme sso.Drupal.class.php, indiquez 'Drupal' dans ce champ.";
 $CourseCreationSplashScreenTitle = "Écran d'accueil de création de cours";
 $CourseCreationSplashScreenComment = "L'écran d'accueil de création de cours montre une série d'options suggérées à l'enseignant lorsqu'il vient de créer un nouveau cours. Désactivez cette option si vous souhaitez envoyer directement les enseignants sur la page principale du cours.";
+$WorksReport = "Rapport de travaux";
+$AccumulateScormTime = "Temps cumulatif SCORM";
+$AccumulateScormTimeInfo = "Si activé, le temps de session pour les parcours SCORM sera cumulatif. Sinon, il sera uniquement compté depuis le dernier temps de connexion.";
+
 $TCCConnection = 'Connexion à TCC';
 $TCCConnect = 'Se connecter';
 $ForMoreDetailsVisitX = "Pour que nous puissions mieux te connaître et te proposer un parcours sur mesure, tu dois d’abord remplir ce questionnaire %s.

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

@@ -2474,7 +2474,6 @@ $TitleManipulateStudentPublication = "Manipular a actual publicación de estudan
 $EnterDataNewChapter = "Introduza os datos do novo capítulo";
 $EnterDataNewModule = "Introduza os datos do novo módulo";
 $CreateNewStep = " \tCrear un novo paso :";
-$NewDocument = "Novo documento";
 $UseAnExistingResource = " \tOu use un recurso xa existente :";
 $Position = "Posición";
 $NewChapterCreated = "Creouse o capítulo novo. Agora pode engadir outro capítulo ou un paso.";

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

@@ -2168,7 +2168,6 @@ $TitleManipulateStudentPublication = "Ausarbeitung bearbeiten";
 $EnterDataNewChapter = "Die Daten für das neue Kapitel eingeben";
 $EnterDataNewModule = "Die Daten für das neue Modul eingeben";
 $CreateNewStep = "Neues Dokument erstellen";
-$NewDocument = "Dokument / Aktivität";
 $UseAnExistingResource = "oder eine bestehende Quelle benutzen:";
 $Position = "Position";
 $NewChapterCreated = "Das neue Kapitel wurde erstellt. Sie können nun ein weiteres Kapitel oder einen weiteren Schritt hinzufügen";

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

@@ -2486,7 +2486,6 @@ $TitleManipulateStudentPublication = "Επεξεργασία ανάθεσης";
 $EnterDataNewChapter = "Adding a section to the course";
 $EnterDataNewModule = "Enter information for section";
 $CreateNewStep = "Δημιουργία πολυμεσικής σελίδας";
-$NewDocument = "Σελίδα Πλούσιου Κειμένου / δραστηριότητα";
 $UseAnExistingResource = "Η χρησιμοποιήστε ένα υπάρχον πόρο:";
 $Position = "Στον πίνακα περιεχομένων";
 $NewChapterCreated = "A new section has now been created. You may continue by adding a section or step.";

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

@@ -1545,7 +1545,6 @@ $TitleManipulateStudentPublication = "A jelenlegi hallgatói publikáció módos
 $EnterDataNewChapter = "Adja meg az új fejezet adatait";
 $EnterDataNewModule = "Adja meg az új modul adatait";
 $CreateNewStep = "Új lépés létrehozása:";
-$NewDocument = "Új dokumentum";
 $UseAnExistingResource = "vagy már létező elem használata:";
 $Position = "Pozíció";
 $NewChapterCreated = "Az új fejezet létrehozása megtörtént. Hozzáadhat lépést vagy létrehozhat újabb fejezetet.";

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

@@ -1071,7 +1071,6 @@ $TitleManipulateStudentPublication = "Ubah publikasi siswa ini";
 $EnterDataNewChapter = "Masukkan data pada bab baru";
 $EnterDataNewModule = "Masukkan data ke modul baru";
 $CreateNewStep = "Buat sebuah langkah/step baru :";
-$NewDocument = "Dokumen baru";
 $UseAnExistingResource = "Atau gunakan sumberdaya yang ada :";
 $Position = "Posisi";
 $NewChapterCreated = "Bab baru telah dibuat.  Anda kini dapat menambah bab lain atau langkah pada bab tsb.";

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

@@ -2493,7 +2493,6 @@ $TitleManipulateStudentPublication = "Modifica la pagina degli elaborati";
 $EnterDataNewChapter = "Configura le proprietà del capitolo";
 $EnterDataNewModule = "Modifica le informazioni del capitolo";
 $CreateNewStep = "Crea un nuovo elemento";
-$NewDocument = "Nuovo documento";
 $UseAnExistingResource = "oppure usa una risorsa esistente :";
 $Position = "Posizione";
 $NewChapterCreated = "Il nuovo capitolo è stato creato. Puoi aggiungere altri capitoli o immettere nuovi elementi.";

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

@@ -518,7 +518,6 @@ $LearnpathDeleteModule = "セクションを削除";
 $NewChapter = "セクションを追加";
 $NewStep = "学習オブジェクトまたは活動項目を追加";
 $EnterDataNewChapter = "セクションをコースに追加しています";
-$NewDocument = "リッチ メディアのページ / 活動項目";
 $Position = "目次";
 $ViewModeEmbedded = "現在の表示モード: 埋め込み";
 $ShowDebug = "デバッグを表示する";

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

@@ -1874,7 +1874,6 @@ $TitleManipulateStudentPublication = "Rediģēt mājas darbu";
 $EnterDataNewChapter = "Pievienot tēmai nodaļu";
 $EnterDataNewModule = "Ievadīt informāciju par nodaļu";
 $CreateNewStep = "Veidojiet mācību tēmas saturu pakāpeniski.<br>Pievienojiet saturam:<br><br>___jaunu interaktīvu mācību satura lapu ar teksta un mēdiju elementiem:";
-$NewDocument = "- Pievienot jaunu mācību satura lapu,<br>-- jeb, materiālu no mapes  Dokumenti, zemāk";
 $UseAnExistingResource = "___ jau iepriekš sagatavotus resursus :";
 $Position = "Vieta satura rādītājā";
 $NewChapterCreated = "Jauna tēmas nodaļa ir izveidota. Jūs variet pievienot jaunu apakšnodaļu vai apgūstamu mācību elementu";

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

@@ -1273,7 +1273,6 @@ $TitleManipulateStudentPublication = "Redaguoti šią studento publikaciją";
 $EnterDataNewChapter = "Įrašyti naujo skyriaus duomenis";
 $EnterDataNewModule = "Įrašyti naujo modulio duomenis";
 $CreateNewStep = "Sukurti naują žingsnį:";
-$NewDocument = "Naujas dokumentas";
 $UseAnExistingResource = "arba naudoti jau esamą resursą:";
 $Position = "Pozicija";
 $NewChapterCreated = "Naujas skyrius sukurtas. Dabar galite į jį įterpti kitą  skyrių arba žingsnį.";

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

@@ -1227,7 +1227,6 @@ $TitleManipulateStudentPublication = "Ракување со тековната 
 $EnterDataNewChapter = "Внесување на податоците за новото поглавје";
 $EnterDataNewModule = "Внесување на податоците за новиот модул";
 $CreateNewStep = "Креирај нов чекор:";
-$NewDocument = "Нов документ";
 $UseAnExistingResource = "Или исползувај постоечки ресурси:";
 $Position = "Позиција";
 $NewChapterCreated = "Беше креирано новото поглавје. Сега можете да додадете чекор во него, или да креирате ново поглавје.";

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

@@ -2058,7 +2058,6 @@ $TitleManipulateStudentPublication = "Edytuj zadanie";
 $EnterDataNewChapter = "Dodawanie modułu do kursu";
 $EnterDataNewModule = "Wprowadź dane nowego modułu";
 $CreateNewStep = "Utwórz nową bogatą stronę mediów";
-$NewDocument = "Nowy dokument";
 $UseAnExistingResource = "Lub wykorzystaj istniejące zasoby:";
 $Position = "Pozycja";
 $NewChapterCreated = "Utworzono nowy moduł. Możesz kontynuować dodając do niego kolejny moduł lub krok.";

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

@@ -2220,7 +2220,6 @@ $TitleManipulateStudentPublication = "Editar trabalho/tarefa";
 $EnterDataNewChapter = "Adicionar uma secção ao curso";
 $EnterDataNewModule = "Editar informação para a secção";
 $CreateNewStep = "Criar uma nova página para conteúdos media";
-$NewDocument = "Página de conteúdos media / actividade";
 $UseAnExistingResource = "Ou utilizar um recurso existente :";
 $Position = "Na tabela de conteúdos";
 $NewChapterCreated = "Foi criada uma nova secção. Pode continuar adicionando uma secção ou etapa.";

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

@@ -1838,7 +1838,6 @@ $TitleManipulateStudentPublication = "T'ijrapay kunan kaq llank'ayta";
 $EnterDataNewChapter = "Churay musuq sutichaqaq imayninta";
 $EnterDataNewModule = "Churay musuq sutichaqaq imayninta";
 $CreateNewStep = "Kamay musuq yanapaysinata :";
-$NewDocument = "Musuq qelqa khipu";
 $UseAnExistingResource = "Utaq hap'ipay ña yanapaysina kasqata:";
 $Position = "Posición";
 $NewChapterCreated = "Sutichasqaqa karisqañan. Kunanqa ña churawaq imaymanakunata utaq kamariwaqpas hoq sutichasqata";

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

@@ -2389,7 +2389,6 @@ $TitleManipulateStudentPublication = "Manipuleaza publicatia studentului actuala
 $EnterDataNewChapter = "Introduceti data noului capitol";
 $EnterDataNewModule = "Introduceti data noului modul";
 $CreateNewStep = "Creati un pas nou :";
-$NewDocument = "Document nou";
 $UseAnExistingResource = "sau folositi o resursa existenta :";
 $Position = "Pozitie";
 $NewChapterCreated = "Noul capitolul a fost creat. Acum puteti sa-i adaugati un alt capitol sau pas.";

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

@@ -1466,7 +1466,6 @@ $TitleManipulateStudentPublication = "Манипулировать текущи
 $EnterDataNewChapter = "Ввести данные новой главы";
 $EnterDataNewModule = "Ввести данные новой главы";
 $CreateNewStep = "Создать новый шаг:";
-$NewDocument = "Новый документ";
 $UseAnExistingResource = "Или используйте существующий ресурс:";
 $Position = "Позиция";
 $NewChapterCreated = "Новая глава создана. Вы можете сейчас добавить другую главу или шаг в нее.";

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

@@ -1400,7 +1400,6 @@ $TitleManipulateStudentPublication = "处理当前作业";
 $EnterDataNewChapter = "请输入章节标题";
 $EnterDataNewModule = "请输入学习路径标题";
 $CreateNewStep = "创建步骤:";
-$NewDocument = "创建文档";
 $UseAnExistingResource = "使用现有资源:";
 $Position = "位置";
 $NewChapterCreated = "章节已创建,您可以添加其他章节或加入步骤。";

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

@@ -2517,7 +2517,6 @@ $TitleManipulateStudentPublication = "Spravovať túto študentskú publikáciu"
 $EnterDataNewChapter = "Zadajte údaje pre novú kapitolu";
 $EnterDataNewModule = "Zadajte údaje pre novú kapitolu";
 $CreateNewStep = "Vytvoriť novú etapu";
-$NewDocument = "Nový dokument";
 $UseAnExistingResource = "Alebo použite existujúci zdroj :";
 $Position = "Pozícia";
 $NewChapterCreated = "Nová kapitola bola vytvorená. Teraz môžete do nej vstúpiť alebo pridať ďalšiu kapitolu.";

+ 41 - 1
main/lang/slovenian/trad4all.inc.php

@@ -2470,7 +2470,6 @@ $TitleManipulateStudentPublication = "Uredi nalogo";
 $EnterDataNewChapter = "Vnesite podatke o razdelku";
 $EnterDataNewModule = "Vnesite podatke o razdelku";
 $CreateNewStep = "Ustvari dokument:";
-$NewDocument = "Nov dokument / aktivnost";
 $UseAnExistingResource = "Ali uporabite obstoječ vir :";
 $Position = "V kazalu vsebine";
 $NewChapterCreated = "Nov razdelek je bil ustvarjen. Sedaj lahko nadaljujete z dodajanjem razdelkov ali učnih objektov.";
@@ -3125,6 +3124,7 @@ $ModifyQuestion = "Shrani vprašanje";
 $Example = "Primer";
 $CheckAll = "Izberi vse";
 $NbAnnoucement = "Obvestilo";
+$DisplayCertificate = "Prikaži certifikat";
 $Doc = "Tečaj";
 $PlataformAdmin = "Admin portala";
 $Groups = "Skupine";
@@ -7439,6 +7439,8 @@ $DownloadReportPdf = "Prenesi poročilo v obliki PDF";
 $ShowFullSkillNameOnSkillWheelTitle = "Prikaži polno ime veščine na drevesu kompetenc";
 $DBPort = "Vrata";
 $CreatedBy = "Ustvaril(a)";
+$DropboxHideGeneralCoachTitle = "Skrij glavnega učitelja v nabiralniku";
+$DropboxHideGeneralCoachComment = "Skrije glavnega učitelja v orodju nabiralnika kadar ta v nabiralnik naloži dokument.";
 $UploadMyAssignment = "Naloži mojo nalogo";
 $Inserted = "Vstavljeno";
 $YourBroswerDoesNotSupportWebRTC = "Tvoj brskalnik ne omogoča naravnega video videokonferenčnega prenosa.";
@@ -7505,10 +7507,14 @@ $HotspotExerciseFinished = "Sedaj kliknite na spodnji gumb za uveljavitev vaših
 $ClosePolygon = "Zapri poligon";
 $DelineationStatus1 = "Uporabite desni klik, da zaprete razmejitev";
 $Beta = "Beta";
+$CropYourPicture = "Obreži svojo sliko";
 $DownloadBadge = "Prenesi značko";
 $NoXMLFileFoundInTheZip = "Ne najdem XML datoteke v ZIP arhivu. XML datoteka za potrebna za uvoz tega tipa.";
+$ClickOrDropOneFileHere = "Kliknite ali izpustite datoteko tule";
+$LastXDays = "Zadnjih % dni";
 $ExportBadges = "Izvozi značke";
 $LanguagesDisableAllExceptDefault = "Onemogoči vse jezike razen privzetega jezika platforme";
+$ThereAreUsersUsingThisLanguagesDisableItManually = "Aktivni uporabniki trenutno uporabljajo ta jezik. Prosim, onemogočite ga ročno.";
 $Overwrite = "Prepiši";
 $TheLogoMustBeSizeXAndFormatY = "Logo mora biti velikosti %s px in v obliki %s";
 $ResetToTheOriginalLogo = "Originalni logo je bil obnovljen";
@@ -7517,6 +7523,7 @@ $CurrentLogo = "Trenutni logo";
 $UpdateLogo = "Ažuriraj logo";
 $DatabaseManager = "Upravitelj podatkovne baze";
 $CourseTemplate = "Predloga tečaja";
+$PickACourseAsATemplateForThisNewCourse = "Izberi tečaj kot predlogo za ta nov tečaj";
 $NowDownloadYourCertificateClickHere = "Svoj certifikat lahko prenesete s klikom tule";
 $AnotherAttempt = "Naslednji poskus";
 $RemainingXAttempts = "Preostalo je še %s poskusov";
@@ -7544,4 +7551,37 @@ $ForumEndDate = "Končni datum (zapiranje)";
 $ForumStartDateComment = "Forum bo viden od začetnega datuma dalje";
 $ForumEndDateComment = "Po preteku tega datuma bo forum zaprt";
 $ModeratedForum = "Moderiran forum";
+$EnableProfileUsersAddressGeolocalizationTitle = "Omogoči uporabnikovo geolociranje";
+$ProfileIsNotCompleted = "Pred nadaljevanjem morate vnesti informacijo o profilu";
+$Diagnostic = "Diagnostika";
+$AllowShowLinkedInUrlTitle = "Dovoli prikaz uporanikovega LinkedIn profila";
+$AllowShowLinkedInUrlComment = "Dodaj povezavo v uporabnikov socialni blok, ki dovoljuje obisk uporabnikovega LinkedIn profila";
+$LaunchVideoConferenceRoom = "Zaženi videokonferenčno sobo";
+$VideoConference = "Videokanferenca";
+$TermsDuplicatedInFile = "Termin je podvojen v datoteki";
+$GlossaryTermAlreadyExists = "Ta termin že obstaja";
+$LinkedInUrl = "URL LinkedIn profila";
+$SaveTheCorrectAnswersForTheNextAttempt = "Shrani pravilen odgovor za naslednji poskus";
+$TranslateThisTerm = "Prevedi ta termin";
+$OnlyActiveSubLanguagesAreListed = "Zgolj aktivni pod-jeziki nastopajo na tem seznamu";
+$Translation = "Prevod";
+$IfThisTranslationExistsThisWillReplaceTheTerm = "Če je ta termin že bil preveden, bo ta operacija nadomestila njegov prevod v tem pod-jeziku";
+$LastConnection = "Zadnja povezava";
+$UpdateExistingGlossaryTerms = "Ažuriraj obstoječ termin";
+$TermsUpdated = "Termin ažuriran";
+$TermsAdded = "Termin dodan";
+$Files = "Datoteke";
+$AssignedTo = "Dodeljen k";
+$RequestConfirmation = "Potrditev zahteve";
+$PriorityNormal = "Normalna";
+$PriorityHigh = "Visoka";
+$PriorityLow = "Nizka";
+$TicketVirtualCampus = "Virtualni kampus";
+$Assign = "Dodeli";
+$PersonalEmail = "Osebni e-poštni naslov";
+$Priority = "Prioriteta";
+$SrcEmail = "E-pošta";
+$SrcPhone = "Telefon";
+$CourseCreationSplashScreenTitle = "Uvodno okno pri kreiranju tečaja (splash screen)";
+$CourseCreationSplashScreenComment = "Uvodno okno tečaja prikaže množico predlaganih opcij, ki učitelju pomagajo pri kreiranju novega tečaja. Onemogočena opcija omogoča učitelju, da je preusmerjen direktno na domačo stran tečaja po njegovem kreiranju.";
 ?>

+ 6 - 3
main/lang/spanish/trad4all.inc.php

@@ -6743,7 +6743,7 @@ $XQuestionsWithTotalScoreY = "%d preguntas, con un resultado máximo (todas preg
 $ThisIsAutomaticEmailNoReply = "Este es un mensaje automático. Por favor no le de respuesta (será ignorada).";
 $UploadedDocuments = "Documentos enviados";
 $QuestionLowerCase = "Pregunta minúsculas";
-$QuestionsLowerCase = "Preguntas minúsculas";
+$QuestionsLowerCase = "preguntas";
 $BackToTestList = "Regreso a lista de ejercicios";
 $CategoryDescription = "Descripción de categoría";
 $BackToCategoryList = "Regreso a la lista de categorías";
@@ -7180,7 +7180,7 @@ $TeacherAutosubscribeComment = "Inscripción por el propio profesor";
 $DRHAutosubscribeTitle = "Inscripción por el propio Director de Recursos Humanos";
 $DRHAutosubscribeComment = "Inscripción por el propio Director de Recursos Humanos";
 $ScormCumulativeSessionTimeTitle = "Tiempo acumulado de sesión para SCORM";
-$ScormCumulativeSessionTimeComment = "Cuando se activa el tiempo de una sesión para una secuencia de aprendizaje SCORM será acumulativo, de lo contrario, sólo se contará desde el momento en la última actualización.";
+$ScormCumulativeSessionTimeComment = "Cuando se activa el tiempo de una sesión para un itinerario de aprendizaje SCORM será acumulativo, de lo contrario, sólo se contará desde el momento en la última actualización. Este parámetro es global. Se utiliza a la creación de cada nuevo itinerario de aprendizaje, pero luego puede ser redefinido en la configuracinó de cada uno.";
 $SessionAdminPageAfterLoginTitle = "Página del administrador de sesiones después de identificarse";
 $SessionAdminPageAfterLoginComment = "Página que será cargada después de que un administrador de sesiones se haya identificado";
 $SessionadminAutosubscribeTitle = "Inscripción por el propio administrador de sesiones";
@@ -7536,7 +7536,7 @@ $BlankInputSize = "Tamaño del espacio en blanco";
 $DateFormatLongNoDayJS = "dd 'de' MM 'de' yy";
 $TimeFormatNoSecJS = "HH'h':mm";
 $AtTime = "a las";
-$SendSubscriptionNotification = "Enviar notificación de suscripción por correo electrónico";
+$SendSubscriptionNotification = "Enviar notificación de suscripción por correo electrónico a los alumnos";
 $SendAnEmailWhenAUserBeingSubscribed = "Enviar un correo electrónico cuando un usuario está suscrito a la sesión";
 $SelectDate = "Seleccionar fecha";
 $OnlyLettersAndSpaces = "Sólo letras y espacios";
@@ -7830,4 +7830,7 @@ $SSOSubclassTitle = "Single Sign On: sub-clase";
 $SSOSubclassComment = "Para activar algun método de Single Sign On, es necesario definir su propia sub-clase en main/auth/sso/, basada en la clase por defecto. Indique aquí el nombre de la sub-clase. Por ejemplo, si el archivo se llama sso.Drupal.class.php, indique 'Drupal' en este campo.";
 $CourseCreationSplashScreenTitle = "Pantalla de bienvenida de curso";
 $CourseCreationSplashScreenComment = "La pantalla de bienvenida muestra una serie de sugerencias al profesor cuando acaba de crear un nuevo curso. Deactive esta opción para que el profesor llegue directamente a la pantalla principal del curso.";
+$WorksReport = "Reporte de tareas";
+$AccumulateScormTime = "Acumular tiempo de sesión SCORM";
+$AccumulateScormTimeInfo = "Cuando se activa, el tiempo de una sesión para una secuencia de aprendizaje SCORM será acumulativo, de lo contrario, sólo se contará desde el momento de la última actualización.";
 ?>

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

@@ -1158,7 +1158,6 @@ $TitleManipulateStudentPublication = "Manipular la publicación actual del estud
 $EnterDataNewChapter = "Ingrese la información del nuevo capítulo";
 $EnterDataNewModule = "Ingrese la información del nuevo módulo";
 $CreateNewStep = "Crear un nuevo paso :";
-$NewDocument = "Nuevo documento";
 $UseAnExistingResource = "O utilizar un recurso existente :";
 $Position = "Posición";
 $NewChapterCreated = "El nuevo capítulo ha sido creado. Ahora puede agregar otro capítulo o paso en él.";

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

@@ -446,7 +446,6 @@ $LearnpathDeleteModule = "Tanggalin ang seksyon";
 $NewChapter = "Magdagdag ng seksyon";
 $NewStep = "Magdagdag ng bagay na pinag-aaralan o aktibidad";
 $EnterDataNewChapter = "Pagdadagdag ng isang seksyon sa kurso";
-$NewDocument = "Matingkad na pahina ng media / aktibidad";
 $Position = "Sa talaan ng mga nilalaman";
 $ViewModeEmbedded = "Kasalukuyang view mode: embedded";
 $ShowDebug = "Ipakita ang debug";

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

@@ -1378,7 +1378,6 @@ $TitleManipulateStudentPublication = "處理當前作業";
 $EnterDataNewChapter = "請輸入章節標題";
 $EnterDataNewModule = "請輸入學習路徑標題";
 $CreateNewStep = "創建步驟︰";
-$NewDocument = "創建文檔";
 $UseAnExistingResource = "使用現有資源︰";
 $Position = "位置";
 $NewChapterCreated = "章節已創建,您可以添加其他章節或加入步驟。";

+ 16 - 18
main/lp/learnpath.class.php

@@ -44,6 +44,7 @@ class learnpath
     public $path = ''; // Path inside the scorm directory (if scorm).
     public $theme; // The current theme of the learning path.
     public $preview_image; // The current image of the learning path.
+    public $accumulate_scorm_time; // Flag to accumulate scorm time
 
     // Tells if all the items of the learnpath can be tried again. Defaults to "no" (=1).
     public $prevent_reinit = 1;
@@ -150,6 +151,7 @@ class learnpath
                 $this->modified_on = $row['modified_on'];
                 $this->ref = $row['ref'];
                 $this->categoryId = $row['category_id'];
+                $this->accumulate_scorm_time = isset($row['accumulate_scorm_time']) ? $row['accumulate_scorm_time'] : 'false';
 
                 if (!empty($row['publicated_on'])) {
                     $this->publicated_on = $row['publicated_on'];
@@ -1131,9 +1133,9 @@ class learnpath
         );
 
         $link_info = GradebookUtils::isResourceInCourseGradebook(
-            api_get_course_id(), 
-            4, 
-            $id, 
+            api_get_course_id(),
+            4,
+            $id,
             api_get_session_id()
         );
         if ($link_info !== false) {
@@ -9136,7 +9138,7 @@ class learnpath
 
         // Remove memory and time limits as much as possible as this might be a long process...
         if (function_exists('ini_set')) {
-            api_set_memory_limit('128M');
+            api_set_memory_limit('256M');
             ini_set('max_execution_time', 600);
         }
 
@@ -9228,8 +9230,8 @@ class learnpath
             $path_to_replace = $folder_name.'/';
         }
 
-        //Fixes chamilo scorm exports
-        if ($this->ref == 'chamilo_scorm_export') {
+        // Fixes chamilo scorm exports
+        if ($this->ref === 'chamilo_scorm_export') {
             $path_to_remove = 'scorm/'.$this->path.'/document/';
         }
 
@@ -9293,7 +9295,7 @@ class learnpath
                     $my_xml_file_path = str_replace($path_to_remove, $path_to_replace, $my_file_path);
 
                     //From quiz
-                    if ($this->ref == 'chamilo_scorm_export') {
+                    if ($this->ref === 'chamilo_scorm_export') {
                         $path_to_remove = 'scorm/'.$this->path.'/';
                         $my_xml_file_path = str_replace($path_to_remove, '', $my_file_path);
                     }
@@ -9625,7 +9627,9 @@ class learnpath
                         $contents = ScormSection::export_exercise_to_scorm($exe_id, true);
                         $tmp_file_path = $archive_path.$temp_dir_short.'/'.$my_file_path;
                         $res = file_put_contents($tmp_file_path, $contents);
-                        if ($res === false) { error_log('Could not write into file '.$tmp_file_path.' '.__FILE__.' '.__LINE__, 0); }
+                        if ($res === false) {
+                            error_log('Could not write into file '.$tmp_file_path.' '.__FILE__.' '.__LINE__, 0);
+                        }
                         $files_cleanup[] = $tmp_file_path;
                         //error_log($tmp_path); die();
                         //$my_xml_file_path = api_htmlentities(api_utf8_encode($my_file_path), ENT_QUOTES, 'UTF-8');
@@ -9952,16 +9956,10 @@ EOD;
 
         // Add the extra files that go along with a SCORM package.
         $main_code_path = api_get_path(SYS_CODE_PATH) . 'lp/packaging/';
-        $extra_files = scandir($main_code_path);
-        foreach ($extra_files as $extra_file) {
-            if (strpos($extra_file, '.') === 0) {
-                continue;
-            } else {
-                $dest_file = $archive_path.$temp_dir_short.'/'.$extra_file;
-                $this->create_path($dest_file);
-                copy($main_code_path.$extra_file, $dest_file);
-            }
-        }
+
+        $fs = new \Symfony\Component\Filesystem\Filesystem;
+        $fs->mirror($main_code_path, $archive_path.$temp_dir_short);
+       
 
         // Finalize the imsmanifest structure, add to the zip, then return the zip.
 

+ 11 - 1
main/lp/learnpathItem.class.php

@@ -3627,8 +3627,18 @@ class learnpathItem
             error_log("total_time: $total_time");
         }
 
+        $lp_table = Database::get_course_table(TABLE_LP_MAIN);
+        $lp_id = intval($this->lp_id);
+        $sql = "SELECT * FROM $lp_table
+                    WHERE id = $lp_id AND c_id = $course_id";
+        $res = Database::query($sql);
+        $accumulate_scorm_time = 'false';
+        if (Database::num_rows($res) > 0) {
+            $accumulate_scorm_time = $row['accumulate_scorm_time'];
+        }
+
         //Step 2.1 : if normal mode total_time = total_time + total_sec
-        if (api_get_setting('scorm_cumulative_session_time') != 'false') {
+        if ($accumulate_scorm_time != 'false') {
             $total_time += $total_sec;
             //$this->last_scorm_session_time = $total_sec;
         } else {

+ 13 - 0
main/lp/lp_add.php

@@ -117,6 +117,13 @@ $form->addElement('html', '<div id="advanced_params_options" style="display:none
 $items = learnpath::getCategoryFromCourseIntoSelect(api_get_course_int_id(), true);
 $form->addElement('select', 'category_id', get_lang('Category'), $items);
 
+// accumulate_scorm_time
+$form->addElement(
+    'checkbox',
+    'accumulate_scorm_time',
+    [get_lang('AccumulateScormTime'), get_lang('AccumulateScormTimeInfo')]
+);
+
 // Start date
 $form->addElement('checkbox', 'activate_start_date_check', null, get_lang('EnableStartTime'), array('onclick' => 'activate_start_date()'));
 $form->addElement('html','<div id="start_date_div" style="display:block;">');
@@ -133,6 +140,12 @@ $form->addElement('html','</div>');
 
 $defaults['activate_start_date_check']  = 1;
 
+if (api_get_setting('scorm_cumulative_session_time') == 'true') {
+    $defaults['accumulate_scorm_time']  = 1;
+} else {
+    $defaults['accumulate_scorm_time']  = 0;
+}
+
 $defaults['publicated_on'] = date('Y-m-d 08:00:00');
 $defaults['expired_on'] = date('Y-m-d 08:00:00',time()+86400);
 

+ 7 - 4
main/lp/lp_controller.php

@@ -808,12 +808,15 @@ switch ($action) {
         if ($hideScormExportLink === 'true') {
             api_not_allowed(true);
         }
-        if ($debug > 0) error_log('New LP - export action triggered', 0);
-        if (!$lp_found) { error_log('New LP - No learnpath given for export', 0); require 'lp_list.php'; }
-        else {
+        if ($debug > 0) {
+            error_log('New LP - export action triggered', 0);
+        }
+        if (!$lp_found) {
+            error_log('New LP - No learnpath given for export', 0);
+            require 'lp_list.php';
+        } else {
             $_SESSION['oLP']->scorm_export();
             exit();
-            //require 'lp_list.php';
         }
         break;
     case 'export_to_pdf':

+ 222 - 293
main/lp/js/api_wrapper.js → main/lp/packaging/assets/api_wrapper.js

@@ -11,11 +11,10 @@
  * Find the SCO functions (startTimer, computeTime, etc in the second section)
  * Find the Chamilo-proper functions (checkAnswers, etc in the third section)
  */
-var _debug = false;
+var _debug = true;
 var findAPITries = 0;
 var _apiHandle = null; //private variable
 var errMsgLocate = "Unable to locate the LMS's API implementation";
-
 var _NoError = 0;
 var _GeneralException = 101;
 var _ServerBusy = 102;
@@ -28,17 +27,18 @@ var _InvalidSetValue = 402;
 var _ElementIsReadOnly = 403;
 var _ElementIsWriteOnly = 404;
 var _IncorrectDataType = 405;
+
 /**
  * Gets the API handle right into the local API object and ensure there is only one.
  * Using the singleton pattern to ensure there's only one API object.
  * @return	object The API object as given by the LMS
  */
-var API = new function ()
+var API = new function()
 {
-    if (_apiHandle == null)
-    {
+    if (_apiHandle == null) {
         _apiHandle = getAPI();
     }
+
     return _apiHandle;
 }
 
@@ -49,11 +49,9 @@ var API = new function ()
  */
 function findAPI(win)
 {
-    while((win.API == null) && (win.parent != null) && (win.parent != win))
-    {
+    while((win.API == null) && (win.parent != null) && (win.parent != win)) {
         findAPITries++;
-        if(findAPITries>10)
-        {
+        if (findAPITries>10) {
             alert("Error finding API - too deeply nested");
             return null;
         }
@@ -61,6 +59,7 @@ function findAPI(win)
     }
     return win.API;
 }
+
 /**
  * Gets the API from the current window/frame or from parent objects if not found
  * @return	object	The API object recovered from the LMS's implementation of the SCORM API
@@ -70,13 +69,11 @@ function getAPI()
     //window is the global/root object of the current window/frame
     var MyAPI = findAPI(window);
     //look through parents if any
-    if((MyAPI == null) && (window.opener != null) && (typeof(window.opener) != "undefined"))
-    {
+    if ((MyAPI == null) && (window.opener != null) && (typeof(window.opener) != "undefined")) {
         MyAPI = findAPI(window.opener);
     }
     //still not found? error message
-    if(MyAPI == null)
-    {
+    if (MyAPI == null) {
         alert("Unable to find SCORM API adapter.\nPlease check your LMS is considering this page as SCORM and providing the right JavaScript interface.")
     }
     return MyAPI;
@@ -87,71 +84,60 @@ function getAPI()
  */
 function ErrorHandler()
 {
-    if(API == null)
-    {
+    if (API == null) {
         alert("Unable to locate the LMS's API. Cannot determine LMS error code");
         return;
     }
     var errCode = API.LMSGetLastError().toString();
-    if(errCode != _NoError)
-    {
-        if(errCode == _NotImplementedError)
-        {
+    if (errCode != _NoError) {
+        if (errCode == _NotImplementedError) {
             var errDescription = "The LMS doesn't support this feature";
-            if(_debug)
-            {
+            if (_debug) {
                 errDescription += "\n";
                 errDescription += api.LMSGetDiagnostic(null);
             }
-            alert (errDescription);
-        }
-        else
-        {
+            console.log(errDescription);
+        } else {
             var errDescription = API.LMSGetErrorString(errCode);
-            if(_debug)
-            {
+            if (_debug) {
                 errDescription += "\n";
                 errDescription += api.LMSGetDiagnostic(null);
             }
-            alert (errDescription);
+            console.log(errDescription);
         }
     }
     return errCode;
 }
+
 /**
  * Calls the LMSInitialize method of the LMS's API object
  * @return string	The string value of the LMS returned value or false if error (should be "true" otherwise)
  */
 function doLMSInitialize()
 {
-    if(API == null)
-    {
+    if (API == null) {
         alert(errMsgLocate + "\nLMSInitialize failed");
         return false;
     }
     var result = API.LMSInitialize("");
-    if(result.toString() != "true")
-    {
+    if (result.toString() != "true") {
         var err = ErrorHandler();
     }
     return result.toString();
 }
+
 /**
  * Calls the LMSFinish method of the LMS's API object
  * @return	string	The string value of the LMS return value, or false if error (should be "true" otherwise)
  */
 function doLMSFinish()
 {
-    if(API == null)
-    {
+    if (API == null) {
         alert(errMsgLocate + "\nLMSFinish failed");
         return false;
-    }
-    else
-    {
+    } else {
         var result = API.LMSFinish('');
-        if(result.toString() != "true")
-        {
+        if (result.toString() != "true") {
             var err = ErrorHandler();
         }
     }
@@ -164,28 +150,21 @@ function doLMSFinish()
  */
 function doLMSGetValue(name)
 {
-    if (API == null)
-    {
+    if (API == null) {
         alert(errMsgLocate + "\nLMSGetValue was not successful.");
         return "";
-    }
-    else
-    {
+    } else {
         var value = API.LMSGetValue(name);
         var errCode = API.LMSGetLastError().toString();
-        if (errCode != _NoError)
-        {
+        if (errCode != _NoError) {
             // an error was encountered so display the error description
             var errDescription = API.LMSGetErrorString(errCode);
-            alert("LMSGetValue("+name+") failed. \n"+ errDescription);
+            alert("LMSGetValue(" + name + ") failed. \n" + errDescription);
             return "";
         }
-        else
-        {
-            return value.toString();
-        }
     }
 }
+
 /**
  * Calls the LMSSetValue method of the API object
  * @param	string	The name of the SCORM parameter to set
@@ -194,74 +173,68 @@ function doLMSGetValue(name)
  */
 function doLMSSetValue(name, value)
 {
-   if (API == null)
-   {
-      alert("Unable to locate the LMS's API Implementation.\nLMSSetValue was not successful.");
-      return;
-   }
-   else
-   {
-      var result = API.LMSSetValue(name, value);
-      if (result.toString() != "true")
-      {
-         var err = ErrorHandler();
-      }
-   }
-   return;
+    if (API == null) {
+        alert("Unable to locate the LMS's API Implementation.\nLMSSetValue was not successful.");
+        return;
+    } else {
+        var result = API.LMSSetValue(name, value);
+        if (result.toString() != "true") {
+            var err = ErrorHandler();
+        }
+    }
+    return;
 }
+
 /**
  * Calls the LMSCommit method
  */
 function doLMSCommit()
 {
-    if(API == null)
-    {
-        alert(errMsgLocate +"\nLMSCommit was not successful.");
+    if (API == null) {
+        alert(errMsgLocate + "\nLMSCommit was not successful.");
         return "false";
-    }
-    else
-    {
+    } else {
         var result = API.LMSCommit("");
-        if (result != "true")
-        {
+        if (result != "true") {
             var err = ErrorHandler();
         }
     }
     return result.toString();
 }
+
 /**
  * Calls GetLastError()
  */
 function doLMSGetLastError()
 {
-    if (API == null)
-    {
-        alert(errMsgLocate + "\nLMSGetLastError was not successful.");      //since we can't get the error code from the LMS, return a general error
+    if (API == null) {
+        alert(errMsgLocate + "\nLMSGetLastError was not successful.");
+        //since we can't get the error code from the LMS, return a general error
         return _GeneralError;
     }
     return API.LMSGetLastError().toString();
 }
+
 /**
  * Calls LMSGetErrorString()
  */
 function doLMSGetErrorString(errorCode)
 {
-   if (API == null)
-   {
-      alert(errMsgLocate + "\nLMSGetErrorString was not successful.");
-   }
+    if (API == null) {
+        alert(errMsgLocate + "\nLMSGetErrorString was not successful.");
+    }
 
    return API.LMSGetErrorString(errorCode).toString();
 }
+
 /**
  * Calls LMSGetDiagnostic()
  */
 function doLMSGetDiagnostic(errorCode)
 {
-   if (API == null)
-   {
-      alert(errMsgLocate + "\nLMSGetDiagnostic was not successful.");
-   }
+    if (API == null) {
+        alert(errMsgLocate + "\nLMSGetDiagnostic was not successful.");
+    }
 
    return API.LMSGetDiagnostic(errorCode).toString();
 }
@@ -278,17 +251,16 @@ var exitPageStatus;
 function loadPage()
 {
     var result = doLMSInitialize();
-    if(result)
-    {
+    if (result) {
         var status = doLMSGetValue("cmi.core.lesson_status");
-        if(status == "not attempted")
-        {
-            doLMSSetValue("cmi.core.lesson_status","incomplete");
+        if (status == "not attempted") {
+            doLMSSetValue("cmi.core.lesson_status", "incomplete");
         }
         exitPageStatus = false;
         startTimer();
     }
 }
+
 /**
  * Starts the local timer
  */
@@ -296,23 +268,21 @@ function startTimer()
 {
     startTime = new Date().getTime();
 }
+
 /**
  * Calculates the total time and sends the result to the LMS
  */
 function computeTime()
 {
-       if ( startTime != 0 )
-       {
-          var currentDate = new Date().getTime();
-          var elapsedSeconds = ( (currentDate - startTime) / 1000 );
-          var formattedTime = convertTotalSeconds( elapsedSeconds );
-       }
-       else
-       {
-          formattedTime = "00:00:00.0";
-       }
-
-       doLMSSetValue( "cmi.core.session_time", formattedTime );
+    if (startTime != 0) {
+        var currentDate = new Date().getTime();
+        var elapsedSeconds = ( (currentDate - startTime) / 1000 );
+        var formattedTime = convertTotalSeconds(elapsedSeconds);
+    } else {
+        formattedTime = "00:00:00.0";
+    }
+
+    doLMSSetValue( "cmi.core.session_time", formattedTime );
 }
 /**
  * Formats the time in a SCORM time format
@@ -330,31 +300,28 @@ function convertTotalSeconds(ts)
     var strWholeSec = strSec;
     var strFractionSec = "";
 
-    if (strSec.indexOf(".") != -1)
-    {
-        strWholeSec =  strSec.substring(0, strSec.indexOf("."));
-        strFractionSec = strSec.substring(strSec.indexOf(".")+1, strSec.length);
+    if (strSec.indexOf(".") != -1) {
+        strWholeSec = strSec.substring(0, strSec.indexOf("."));
+        strFractionSec = strSec.substring(strSec.indexOf(".") + 1, strSec.length);
     }
-    if (strWholeSec.length < 2)
-    {
+    if (strWholeSec.length < 2) {
         strWholeSec = "0" + strWholeSec;
     }
     strSec = strWholeSec;
-    if (strFractionSec.length)
-    {
-        strSec = strSec+ "." + strFractionSec;
+    if (strFractionSec.length) {
+        strSec = strSec + "." + strFractionSec;
     }
-    if ((ts % 3600) != 0 )
+    if ((ts % 3600) != 0)
         var hour = 0;
     else var hour = (ts / 3600);
-    if ( (tmp % 60) != 0 )
+    if ((tmp % 60) != 0)
         var min = 0;
     else var min = (tmp / 60);
     if ((new String(hour)).length < 2)
-        hour = "0"+hour;
+        hour = "0" + hour;
     if ((new String(min)).length < 2)
-        min = "0"+min;
-    var rtnVal = hour+":"+min+":"+strSec;
+        min = "0" + min;
+    var rtnVal = hour + ":" + min + ":" + strSec;
     return rtnVal
 }
 /**
@@ -370,6 +337,7 @@ function doBack()
     result = doLMSCommit();
     result = doLMSFinish();
 }
+
 /**
  * Handles the closure of the current SCO before an interruption. This is only useful if the LMS
  * deals with the cmi.core.exit, cmi.core.lesson_status and cmi.core.lesson_mode *and* the SCO
@@ -390,6 +358,7 @@ function doContinue(status)
     result = doLMSCommit();
     result = doLMSFinish();
 }
+
 /**
  * handles the recording of everything on a normal shutdown
  */
@@ -402,6 +371,7 @@ function doQuit()
     result = doLMSCommit();
     result = doLMSFinish();
 }
+
 /**
  * Called upon unload event from body element
  */
@@ -429,8 +399,14 @@ function checkAnswers(interrupted)
     var tmpScore = 0;
     var status = 'not attempted';
     var scoreMax = 0;
-    for(var i=0; i<questions.length;i++) {
-        if(questions[i] != undefined && questions[i] != null){
+
+    if (_debug) {
+        console.log('questions_answers_correct:');
+        console.log(questions_answers_correct);
+    }
+
+    for (var i=0; i < questions.length; i++) {
+        if (questions[i] != undefined && questions[i] != null){
             var idQuestion = questions[i];
             var type = questions_types[idQuestion];
             var interactionScore = 0;
@@ -438,183 +414,150 @@ function checkAnswers(interrupted)
             var interactionCorrectResponses = '';
             var interactionType = '';
 
+            if (_debug) {
+                console.log('Type: ' +type);
+                console.log('idQuestion: ' +idQuestion);
+                console.log('questions_answers: ');
+                console.log(questions_answers[idQuestion]);
+                console.log('questions_answers_ponderation: ');
+                console.log(questions_answers_ponderation[idQuestion]);
+                console.log('questions_answers_correct: ');
+                console.log(questions_answers_correct[idQuestion]);
+            }
+
             if (type == 'mcma') {
-                var interactionType = 'choice';
+                interactionType = 'choice';
                 var myScore = 0;
-                for(var j=0; j<questions_answers[idQuestion].length;j++)
-                {
+                for(var j=0; j<questions_answers[idQuestion].length;j++) {
                     var idAnswer = questions_answers[idQuestion][j];
                     var answer = document.getElementById('question_'+(idQuestion)+'_multiple_'+(idAnswer));
-                    if(answer.checked)
-                    {
+                    if (answer.checked) {
                         interactionAnswers += idAnswer+'__|';// changed by isaac flores
-                        myScore +=questions_answers_ponderation[idQuestion][idAnswer];
-
-                        /*for(k=0;k<questions_answers_correct[idQuestion].length;k++)
-                        {
-                            if(questions_answers_correct[idQuestion][k] == idAnswer)
-                            {
-                                if(questions_answers_ponderation[idQuestion][idAnswer])
-                                {
-                                    myScore += questions_answers_ponderation[idQuestion][idAnswer];
-                                }
-                                else
-                                {
-                                    myScore ++;
-                                }
-                            }
-                        }*/
+                        myScore += questions_answers_ponderation[idQuestion][idAnswer];
                     }
                 }
                 interactionScore = myScore;
-                //correct responses work by pattern, see SCORM Runtime Env Doc
-                //for(k=0;k<questions_answers_correct[idQuestion].length;k++)
-                //{
-                //	interactionCorrectResponses += questions_answers_correct[idQuestion][k].toString()+',';
-                //}
                 scoreMax += questions_score_max[idQuestion];
-            }
-            else if(type == 'mcua')
-            {
-                var interactionType = 'choice';
+                if (_debug) {
+                    console.log("Score: "+myScore);
+                }
+            } else if (type == 'mcua') {
+                interactionType = 'choice';
                 var myScore = 0;
-                for(var j=0; j<questions_answers[idQuestion].length;j++)
-                {
+                for (var j=0; j<questions_answers[idQuestion].length;j++) {
                     var idAnswer = questions_answers[idQuestion][j];
                     var answer = document.getElementById('question_'+(idQuestion)+'_unique_'+(idAnswer));
-                    if(answer.checked)
-                    {
+                    if (answer.checked) {
                         interactionAnswers += idAnswer;
-                        if(questions_answers_correct[idQuestion] == idAnswer)
-                        {
-                            if(questions_answers_ponderation[idQuestion][idAnswer])
-                            {
+                        if (_debug) {
+                            console.log("idAnswer: "+idAnswer);
+                            console.log("questions_answers_correct: "+questions_answers_correct[idQuestion][idAnswer]);
+                        }
+                        if (questions_answers_correct[idQuestion][idAnswer] == idAnswer) {
+                            if (questions_answers_ponderation[idQuestion][idAnswer]) {
                                 myScore += questions_answers_ponderation[idQuestion][idAnswer];
-                            }
-                            else
-                            {
-                                myScore ++;
+                            } else {
+                                myScore++;
                             }
                         }
                     }
                 }
+                if (_debug) {
+                    console.log("Score: "+myScore);
+                }
                 interactionScore = myScore;
-                //correct responses work by pattern, see SCORM Runtime Env Doc
-                //interactionCorrectResponses += questions_answers_correct[idQuestion].toString();
                 scoreMax += questions_score_max[idQuestion];
-            }
-            else if(type == 'tf')
-            {
-                var interactionType = 'true-false';
+            } else if (type == 'tf') {
+                interactionType = 'true-false';
                 var myScore = 0;
-                for(var j=0; j<questions_answers[idQuestion].length;j++)
-                {
+                for (var j = 0; j < questions_answers[idQuestion].length; j++) {
                     var idAnswer = questions_answers[idQuestion][j];
-                    var answer = document.getElementById('question_'+(idQuestion)+'_tf_'+(idAnswer));
-                    if(answer.checked.value)
-                    {
+                    var answer = document.getElementById('question_' + idQuestion + '_tf_' + (idAnswer));
+                    if (answer.checked.value) {
                         interactionAnswers += idAnswer;
-                        for(k=0;k<questions_answers_correct[idQuestion].length;k++)
-                        {
-                            if(questions_answers_correct[idQuestion][k] == idAnswer)
-                            {
-                                if(questions_answers_ponderation[idQuestion][idAnswer])
-                                {
+                        for (k = 0; k < questions_answers_correct[idQuestion].length; k++) {
+                            if (questions_answers_correct[idQuestion][k] == idAnswer) {
+                                if (questions_answers_ponderation[idQuestion][idAnswer]) {
                                     myScore += questions_answers_ponderation[idQuestion][idAnswer];
-                                }
-                                else
-                                {
-                                    myScore ++;
+                                } else {
+                                    myScore++;
                                 }
                             }
                         }
                     }
                 }
+                if (_debug) {
+                    console.log("Score: "+myScore);
+                }
                 interactionScore = myScore;
-                //correct responses work by pattern, see SCORM Runtime Env Doc
-                //interactionCorrectResponses += questions_answers_correct[idQuestion].toString();
                 scoreMax += questions_score_max[idQuestion];
-            }
-            else if(type == 'fib')
-            {
-                var interactionType = 'fill-in';
+            } else if (type == 'fib') {
+                interactionType = 'fill-in';
                 var myScore = 0;
-                for(var j=0; j<questions_answers[idQuestion].length;j++)
-                {
+                for (var j = 0; j < questions_answers[idQuestion].length; j++) {
                     var idAnswer = questions_answers[idQuestion][j];
                     var answer = document.getElementById('question_'+(idQuestion)+'_fib_'+(idAnswer));
-                    if(answer.value)
-                    {
-                        interactionAnswers += answer.value+'__|';//changed by isaac flores
-                        for(k=0;k<questions_answers_correct[idQuestion].length;k++)
-                        {
-                            if(questions_answers_correct[idQuestion][k] == answer.value)
-                            {
-                                if(questions_answers_ponderation[idQuestion][idAnswer])
-                                {
+                    if (answer.value) {
+                        interactionAnswers += answer.value + '__|';//changed by isaac flores
+                        for (k = 0; k < questions_answers_correct[idQuestion].length; k++) {
+                            if (questions_answers_correct[idQuestion][k] == answer.value) {
+                                if (questions_answers_ponderation[idQuestion][idAnswer]) {
                                     myScore += questions_answers_ponderation[idQuestion][idAnswer];
-                                }
-                                else
-                                {
-                                    myScore ++;
+                                } else {
+                                    myScore++;
                                 }
                             }
                         }
                     }
                 }
+                if (_debug) {
+                    console.log("Score: "+myScore);
+                }
                 interactionScore = myScore;
-                //correct responses work by pattern, see SCORM Runtime Env Doc
-                //for(k=0;k<questions_answers_correct[idQuestion].length;k++)
-                //{
-                //	interactionCorrectResponses += questions_answers_correct[idQuestion][k].toString()+',';
-                //}
                 scoreMax += questions_score_max[idQuestion];
-            }
-            else if(type == 'matching')
-            {
-                var interactionType = 'matching';
+            } else if (type == 'matching') {
+                interactionType = 'matching';
                 var myScore = 0;
-                for(var j=0; j<questions_answers[idQuestion].length;j++)
-                {
+                for (var j = 0; j < questions_answers[idQuestion].length; j++) {
                     var idAnswer = questions_answers[idQuestion][j];
-                    var answer = document.getElementById('question_'+(idQuestion)+'_matching_'+(idAnswer));
-                    if(answer && answer.value)
-                    {
-                        interactionAnswers += answer.value+'__|';//changed by isaac flores
-                        for(k=0;k<questions_answers_correct[idQuestion].length;k++)
-                        {
+                    var answer = document.getElementById('question_' + (idQuestion) + '_matching_' + (idAnswer));
+                    if (answer && answer.value) {
+                        interactionAnswers += answer.value + '__|';//changed by isaac flores
+                        for (k = 0; k < questions_answers_correct[idQuestion].length; k++) {
                             var left = questions_answers_correct[idQuestion][k][0];
                             var right = questions_answers_correct[idQuestion][k][1];
-                            if(left == idAnswer && right == answer.value)
-                            {
-                                if(questions_answers_ponderation[idQuestion][idAnswer])
-                                {
+                            if (left == idAnswer && right == answer.value) {
+                                if (questions_answers_ponderation[idQuestion][idAnswer]) {
                                     myScore += questions_answers_ponderation[idQuestion][idAnswer];
-                                }
-                                else
-                                {
-                                    myScore ++;
+                                } else {
+                                    myScore++;
                                 }
                             }
                         }
                     }
                 }
+                if (_debug) {
+                    console.log("Score: "+myScore);
+                }
                 interactionScore = myScore;
-                //correct responses work by pattern, see SCORM Runtime Env Doc
-                //for(k=0;k<questions_answers_correct[idQuestion].length;k++)
-                //{
-                //	interactionCorrectResponses += questions_answers_correct[idQuestion][k].toString()+',';
-                //}
                 scoreMax += questions_score_max[idQuestion];
-            } else if(type == 'free') {
+            } else if (type == 'free') {
                 //ignore for now as a score cannot be given
-                var interactionType = 'likert';
+                interactionType = 'free';
+                var answer = document.getElementById('question_'+(idQuestion)+'_free');
+                if (answer && answer.value) {
+                    interactionAnswers += answer.value
+                }
+
+                //interactionScore = questions_score_max[idQuestion];
                 interactionScore = 0;
+                scoreMax += questions_score_max[idQuestion];
+
                 //interactionAnswers = document.getElementById('question_'+(idQuestion)+'_free').value;
                 //correct responses work by pattern, see SCORM Runtime Env Doc
                 //interactionCorrectResponses += questions_answers_correct[idQuestion].toString();
-            } else if(type == 'hotspot') {
-                var interactionType = 'sequencing';
+            } else if (type == 'hotspot') {
+                interactionType = 'sequencing';
                 interactionScore = 0;
                 //if(question_score && question_score[idQuestion]){
                 //	interactionScore = question_score[idQuestion];
@@ -625,96 +568,82 @@ function checkAnswers(interrupted)
                 //{
                 //	interactionCorrectResponses += questions_answers_correct[idQuestion][k].toString()+',';
                 //}
-            } else if(type == 'exact') {
-                var interactionType = 'exact';
+            } else if (type == 'exact') {
+                interactionType = 'exact';
                 interactionScore = 0;
-                // not yet implemented see scorm_classes.php ScormAnswerMultipleChoice::export() function
-                /*
-
-                var myScore = 0;
                 var real_answers = new Array();
-
-                for(var j=0; j<questions_answers[idQuestion].length;j++) {
+                for (var j = 0; j < questions_answers[idQuestion].length; j++) {
                     var idAnswer = questions_answers[idQuestion][j];
-                    var answer   = document.getElementById('question_'+(idQuestion)+'_multiple_'+(idAnswer));
-                    if (answer.checked) {
-                        if(questions_answers_ponderation[idQuestion][idAnswer] != 0 ) {
+                    var answer = document.getElementById('question_' + (idQuestion) + '_exact_' + (idAnswer));
+
+                    if (answer.checked == true) {
+                        interactionAnswers += idAnswer+', ';
+                        if (questions_answers_correct[idQuestion][idAnswer] != 0) {
                             real_answers[j] = true;
                         } else {
                             real_answers[j] = false;
                         }
                     } else {
-                        if(questions_answers_ponderation[idQuestion][idAnswer] != 0) {
+                        if (questions_answers_correct[idQuestion][idAnswer] != 0) {
                             real_answers[j] = false;
                         } else {
                             real_answers[j] = true;
                         }
                     }
-                    //alert(real_answers[j] +' ' + answer.checked + ' ' + questions_answers_ponderation[idQuestion][idAnswer]);
                 }
 
                 var final_answer = true;
-                for(var z=0; z<real_answers.length ;z++) {
-                     if (!real_answers[z]) {
-                         final_answer = false;
-                     }
-                 }
-
-                 if (final_answer) {
+                for (var z = 0; z < real_answers.length; z++) {
+                    if (real_answers[z] == false) {
+                        final_answer = false;
+                    }
+                }
+                interactionScore = 0;
+                console.log(real_answers);
+                if (final_answer) {
                      //getting only the first score where we save the weight of all the question
-                    myScore += questions_answers_ponderation[idQuestion][1];
+                     interactionScore = questions_answers_ponderation[idQuestion][1];
+                }
+                if (_debug) {
+                    console.log("Score: "+interactionScore);
                 }
-
-                interactionScore = myScore;
-                //correct responses work by pattern, see SCORM Runtime Env Doc
-                //for(k=0;k<questions_answers_correct[idQuestion].length;k++)
-                //{
-                //	interactionCorrectResponses += questions_answers_correct[idQuestion][k].toString()+',';
-                //}
                 scoreMax += questions_score_max[idQuestion];
-                */
-            }
-            else
-            {
-                //
             }
             tmpScore += interactionScore;
 
-            doLMSSetValue('cmi.interactions.'+idQuestion+'.id','Q'+idQuestion);
-            doLMSSetValue('cmi.interactions.'+idQuestion+'.type',interactionType);
-            doLMSSetValue('cmi.interactions.'+idQuestion+'.student_response',interactionAnswers);
-            doLMSSetValue('cmi.interactions.'+idQuestion+'.result',interactionScore);
-            //correct responses work by pattern, see SCORM Runtime Env Doc
-            //doLMSSetValue('cmi.interactions.'+idQuestion+'.correct_responses',questions_answers_correct[idQuestion]);
-            //doLMSSetValue('cmi.interactions.'+idQuestion+'.correct_responses',interactionCorrectResponses);
+            doLMSSetValue('cmi.interactions.'+idQuestion+'.id', 'Q'+idQuestion);
+            doLMSSetValue('cmi.interactions.'+idQuestion+'.type', interactionType);
+            doLMSSetValue('cmi.interactions.'+idQuestion+'.student_response', interactionAnswers);
+            doLMSSetValue('cmi.interactions.'+idQuestion+'.result', interactionScore);
         }
     }
-    doLMSSetValue('cmi.core.score.min',0);
-    doLMSSetValue('cmi.core.score.max',scoreMax);
-    doLMSSetValue('cmi.core.score.raw',tmpScore);
-    //doLMSSetValue('cmi.student_data.mastery_score',(scoreMax*0.7));
+    doLMSSetValue('cmi.core.score.min', 0);
+    doLMSSetValue('cmi.core.score.max', scoreMax);
+    doLMSSetValue('cmi.core.score.raw', tmpScore);
+
     //get status
     var mastery_score = doLMSGetValue('cmi.student_data.mastery_score');
-    if(mastery_score <= 0)
-    {
-        mastery_score = (scoreMax*0.80);
+    if (mastery_score <= 0) {
+        mastery_score = (scoreMax * 0.80);
     }
-    if(tmpScore > mastery_score)
-    {
+    if (tmpScore > mastery_score) {
         status = 'passed';
-    }
-    else
-    {
+    } else {
         status = 'failed';
     }
-    doLMSSetValue('cmi.core.lesson_status',status);
 
-    if (interrupted && (status != 'completed') && (status != 'passed'))
-    {
-        doLMSSetValue('cmi.core.exit','suspended');
+    if (_debug) {
+        console.log('student_score: ' + tmpScore);
+        console.log('mastery_score: ' + mastery_score);
+        console.log('cmi.core.score.max: ' + scoreMax);
+        console.log('cmi.core.lesson_status: ' + status);
     }
-    else
-    {
+
+    doLMSSetValue('cmi.core.lesson_status', status);
+
+    if (interrupted && (status != 'completed') && (status != 'passed')) {
+        doLMSSetValue('cmi.core.exit', 'suspended');
     }
+
     return false; //do not submit the form
 }

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 4 - 0
main/lp/packaging/assets/bootstrap/bootstrap.min.css


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 0
main/lp/packaging/assets/jquery/jquery.min.js


+ 10 - 1
main/mySpace/session.php

@@ -60,6 +60,15 @@ if (api_is_drh() || api_is_session_admin() || api_is_platform_admin()) {
         );
     }
 
+    $menu_items[] = Display::url(
+        Display::return_icon('works.png', get_lang('WorksReport'), [], ICON_SIZE_MEDIUM),
+        api_get_path(WEB_CODE_PATH) . 'mySpace/works_in_session_report.php'
+    );
+    $menu_items[] = Display::url(
+        Display::return_icon('clock.png', get_lang('TeacherTimeReportBySession'), [], ICON_SIZE_MEDIUM),
+        api_get_path(WEB_CODE_PATH) . 'admin/teachers_time_by_session_report.php'
+    );
+
     $actionsLeft = '';
     $nb_menu_items = count($menu_items);
     if ($nb_menu_items > 1) {
@@ -82,7 +91,7 @@ if (api_is_drh() || api_is_session_admin() || api_is_platform_admin()) {
 
     $toolbar = Display::toolbarAction(
         'toolbar-session',
-        $content = array(0 => $actionsLeft, 1 => $actionsRight)
+        array($actionsLeft, $actionsRight)
     );
     echo $toolbar;
 

+ 1 - 7
main/mySpace/works_in_session_report.php

@@ -8,7 +8,6 @@
 require_once '../inc/global.inc.php';
 
 use \Chamilo\CoreBundle\Entity\Session;
-use \Doctrine\Common\Collections\Criteria;
 
 api_block_anonymous_users(true);
 
@@ -46,12 +45,7 @@ if ($session) {
     foreach ($sessionCourses as $sessionCourse) {
         $course = $sessionCourse->getCourse();
         $coursesInfo[$course->getId()] =  $course->getCode();
-        $criteria = Criteria::create()->where(
-            Criteria::expr()->eq("status", Session::STUDENT)
-        );
-        $userCourseSubscriptions = $session
-            ->getUserCourseSubscriptions()
-            ->matching($criteria);
+        $userCourseSubscriptions = $session->getUserCourseSubscriptionsByStatus($course, Session::STUDENT);
 
         foreach ($userCourseSubscriptions as $userCourseSubscription) {
             $user = $userCourseSubscription->getUser();

+ 19 - 0
main/template/default/admin/email_tester.tpl

@@ -0,0 +1,19 @@
+<div class="row">
+    <div class="col-sm-5">
+        {{ form }}
+    </div>
+    {% if not errors is empty %}
+        <div class="col-sm-7">
+            <h4 class="page-header">{{ 'Errors'|get_lang }}</h4>
+            <ul>
+                {% for error in errors %}
+                    <li>
+                        {{ 'Email: %s. %s ago'|format(error.mail, error.time) }}
+                        <pre>{{ error.reason|replace({'\n': '<br>'}) }}</pre>
+                    </li>
+                {% endfor %}
+            </ul>
+        </div>
+    {% endif %}
+</div>
+

+ 13 - 12
main/template/default/admin/teacher_time_report.tpl

@@ -22,19 +22,20 @@
             $('#daterange, [name="from"], [name="until"]').val('');
         });
     });
-</script>
-<div class="col-md-12">
-    <div class="actions">
-        <a href="{{ _p.web_main }}admin/teachers_time_by_session_report.php">
-            {{ 'session.png'|img(32, 'Sessions'|get_lang) }}
-        </a>
-        <div class="pull-right">
-            <a href="{{ _p.web_self ~ '?' ~ {'export':'pdf','from':selectedFrom,'until':selectedUntil,'course':selectedCourse,'session':selectedSession,'teacher':selectedTeacher}|url_encode }}">
-                {{ 'pdf.png' | img(32, 'ExportToPDF'|get_lang ) }}
-            </a>
-            <a href="{{ _p.web_self ~ '?' ~ {'export':'xls','from':selectedFrom,'until':selectedUntil,'course':selectedCourse,'session':selectedSession,'teacher':selectedTeacher}|url_encode }}">
-                {{ 'export_excel.png' | img(32, 'ExportExcel'|get_lang ) }}
+    </script>
+    <div class="col-md-12">
+        <div class="actions">
+            <a href="{{ _p.web_main }}admin/teachers_time_by_session_report.php">
+                {{ 'session.png'|img(32, 'Sessions'|get_lang) }}
             </a>
+            <div class="pull-right">
+                <a href="{{ _p.web_self ~ '?' ~ {'export':'pdf','from':selectedFrom,'until':selectedUntil,'course':selectedCourse,'session':selectedSession,'teacher':selectedTeacher}|url_encode }}">
+                    {{ 'pdf.png' | img(32, 'ExportToPDF'|get_lang ) }}
+                </a>
+                <a href="{{ _p.web_self ~ '?' ~ {'export':'xls','from':selectedFrom,'until':selectedUntil,'course':selectedCourse,'session':selectedSession,'teacher':selectedTeacher}|url_encode }}">
+                    {{ 'export_excel.png' | img(32, 'ExportExcel'|get_lang ) }}
+                </a>
+            </div>
         </div>
     </div>
     <h1 class="page-header">{{ 'TeacherTimeReport' | get_lang }}</h1>

+ 1 - 1
main/template/default/auth/session_catalog.tpl

@@ -1,4 +1,4 @@
-{% extends template ~ "/layout/main.tpl" %}
+{% extends template ~ "/layout/page.tpl" %}
 
 {% block body %}
     <script type="text/javascript">

+ 1 - 1
main/template/default/document/record_audio.tpl

@@ -54,7 +54,7 @@
 </div>
 
 <script>
-    $(document).on('ready', function () {
+    $(document).on('ready', function() {
         function useRecordRTC() {
             $('#record-audio-recordrtc').show();
 

+ 1 - 2
main/template/default/layout/course_navigation.tpl

@@ -2,8 +2,7 @@
 {% if show_header == true %}
 
     {% if show_course_shortcut is not null %}
-        <div class="col-md-12">
-            
+        <div class="nav-tools">
             {{ show_course_shortcut }}
         </div>
     {% endif %}

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

@@ -10,7 +10,7 @@
 {{ favico }}
 <link rel="apple-touch-icon" href="{{ _p.web }}apple-touch-icon.png" />
 <meta name="apple-mobile-web-app-capable" content="yes" />
-<meta name="Generator" content="{{ _s.software_name }} {{ _s.system_version|slice(0,1) }}" />
+<meta name="generator" content="{{ _s.software_name }} {{ _s.system_version|slice(0,1) }}" />
 {#  Use the latest engine in ie8/ie9 or use google chrome engine if available  #}
 {#  Improve usability in portal devices #}
 <meta name="viewport" content="width=device-width, initial-scale=1.0">

+ 15 - 0
main/template/default/layout/page_footer.tpl

@@ -70,6 +70,21 @@
         </div>
     </div>
 </div>
+{# Global modal, load content by AJAX call to href attribute on anchor tag with 'ajax' class #}
+<div class="modal fade" id="global-modal" tabindex="-1" role="dialog" aria-labelledby="global-modal-title" aria-hidden="true">
+    <div class="modal-dialog modal-lg">
+        <div class="modal-content">
+            <div class="modal-header">
+                <button type="button" class="close" data-dismiss="modal" aria-label="{{ "Close" | get_lang }}">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+                <h4 class="modal-title" id="global-modal-title">&nbsp;</h4>
+            </div>
+            <div class="modal-body">
+            </div>
+        </div>
+    </div>
+</div>
                 
 {% include template ~ '/layout/footer.js.tpl' %}
 

+ 24 - 1
main/template/default/skill/list.tpl

@@ -1,7 +1,20 @@
 <legend>
     <h1>{{ "ManageSkills" | get_lang }}</h1>
 </legend>
-
+<div class="row">
+    <div class="col-md-3" >
+        <select id="tag-filter" class="form-control">
+            <option value="0">{{ 'PleaseSelectAChoice' | get_lang }}</option>
+            {% for tag in tags %}
+                <option value="{{ tag.id }}">{{ tag.tag }}</option>
+            {% endfor %}
+        </select>
+    </div>
+    <div class="col-md-3">
+        <a id="filter-button" class="btn btn-default">{{ 'FilterByTags' | get_lang }}</a>
+    </div>
+</div>
+<br />
 <div class="table table-responsive">
     <table class="table table-hover table-striped">
         <thead>
@@ -62,3 +75,13 @@
         </tbody>
     </table>
 </div>
+
+<script>
+    $(document).ready(function() {
+        $("#tag-filter").val("{{ current_tag_id }}");
+        $("#filter-button").click(function() {
+            var tagId = $( "#tag-filter option:selected" ).val();
+            $(location).attr('href', '{{ _p.web_main }}admin/skill_list.php?tag_id='+tagId);
+        });
+    });
+</script>

+ 24 - 21
main/template/default/social/avatar_block.tpl

@@ -1,22 +1,25 @@
-<div class="social-profile text-center">
-    {% if show_group %}
-        <img src="{{ user_group_image.file }}" class="img-responsive">
-        <div class="caption">
-            <h4 class="group-title">
-                <a href="{{ _p.web_main ~ 'social/group_view.php?id=' ~ group_id }}">{{ user_group.name }}</a>
-            </h4>
-            <p class="group-description">{{ user_group.description }}</p>
-            {% if user_is_group_admin %}
-                <div id="edit_image">
-                    <a class="btn btn-default" href="{{ _p.web_main ~ 'social/group_edit.php?id=' ~ group_id }}">
-                        {{ 'EditGroup'|get_lang }}
-                    </a>
-                </div>
-            {% endif %}
-        </div>
-    {% elseif show_user %}
-        <a href="{{ user_image.big }}" class="expand-image">
-            <img class="img-responsive img-circle" src="{{ user_image.big }}">
-        </a>
-    {% endif %}
+<div class="sm-groups">
+    <div class="social-profile text-center">
+        {% if show_group %}
+            <img src="{{ user_group_image.file }}" class="img-responsive">
+            <div class="caption">
+                <h4 class="group-title">
+                    <a href="{{ _p.web_main ~ 'social/group_view.php?id=' ~ group_id }}">{{ user_group.name }}</a>
+                </h4>
+                <p class="group-description">{{ user_group.description }}</p>
+                {% if user_is_group_admin %}
+                    <div id="edit_image" class="buttom-subscribed">
+                        <a class="btn btn-default" href="{{ _p.web_main ~ 'social/group_edit.php?id=' ~ group_id }}">
+                            {{ 'EditGroup'|get_lang }}
+                        </a>
+                    </div>
+                    <br />
+                {% endif %}
+            </div>
+        {% elseif show_user %}
+            <a href="{{ user_image.big }}" class="expand-image">
+                <img class="img-responsive img-circle" src="{{ user_image.big }}">
+            </a>
+        {% endif %}
+    </div>
 </div>

+ 2 - 16
main/work/upload.php

@@ -90,7 +90,6 @@ $form->addElement('hidden', 'sec_token', $token);
 
 $succeed = false;
 if ($form->validate()) {
-
     if ($student_can_edit_in_session && $check) {
         $values = $form->getSubmitValues();
         // Process work
@@ -106,21 +105,8 @@ if ($form->validate()) {
         if ($is_allowed_to_edit) {
             $script = 'work_list_all.php';
         }
-        if (!$result) {
-            Session::write(
-                'message',
-                Display::return_message(get_lang('UploadError'), 'error')
-            );
-            header('Location: '.api_get_path(WEB_CODE_PATH).'work/'.$script.'?'.api_get_cidreq().'&id='.$work_id);
-            exit;
-        } else {
-            Session::write(
-                'message',
-                Display::return_message(get_lang('UplUploadSucceeded'), 'success')
-            );
-            header('Location: '.api_get_path(WEB_CODE_PATH).'work/'.$script.'?'.api_get_cidreq().'&id='.$work_id);
-            exit;
-        }
+        header('Location: '.api_get_path(WEB_CODE_PATH).'work/'.$script.'?'.api_get_cidreq().'&id='.$work_id);
+        exit;
     } else {
         // Bad token or can't add works
         Display::addFlash(

+ 14 - 22
main/work/work_list.php

@@ -1,8 +1,6 @@
 <?php
 /* For licensing terms, see /license.txt */
 
-use ChamiloSession as Session;
-
 require_once '../inc/global.inc.php';
 $current_course_tool  = TOOL_STUDENTPUBLICATION;
 
@@ -55,8 +53,6 @@ $interbreadcrumb[] = array(
 
 $documentsAddedInWork = getAllDocumentsFromWorkToString($workId, $courseInfo);
 
-Display :: display_header(null);
-
 $actionsLeft = '<a href="'.api_get_path(WEB_CODE_PATH).'work/work.php?'.api_get_cidreq().'&origin='.$origin.'">'.
     Display::return_icon('back.png', get_lang('BackToWorksList'), '', ICON_SIZE_MEDIUM).'</a>';
 
@@ -65,17 +61,17 @@ if (api_is_allowed_to_session_edit(false, true) && !empty($workId) && !api_is_in
     $url = api_get_path(WEB_CODE_PATH).'work/upload.php?'.api_get_cidreq().'&id='.$workId.'&origin='.$origin;
     $actionsRight = Display::url(Display::return_icon('upload_package.png', get_lang('UploadMyAssignment'), null, ICON_SIZE_MEDIUM) . get_lang('UploadMyAssignment'), $url, array('class'=>'btn-toolbar'));
 }
-echo Display::toolbarAction('toolbar-work', array(0 => $actionsLeft . $actionsRight));
+
+$tpl = new Template('');
+
+$content = Display::toolbarAction('toolbar-work', array($actionsLeft . $actionsRight));
 if (!empty($my_folder_data['title'])) {
-    echo Display::page_subheader($my_folder_data['title']);
+    $content .= Display::page_subheader($my_folder_data['title']);
 }
-echo Session::read('message');
-Session::erase('message');
+
 if (!empty($my_folder_data['description'])) {
     $contentWork = Security::remove_XSS($my_folder_data['description']);
-    $html = '';
-    $html .= Display::panel($contentWork, get_lang('Description'));
-    echo $html;
+    $content .= Display::panel($contentWork, get_lang('Description'));
 }
 
 $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : null;
@@ -94,7 +90,7 @@ switch ($action) {
 }
 
 $result = getWorkDateValidationStatus($work_data);
-echo $result['message'];
+$content .= $result['message'];
 $check_qualification = intval($my_folder_data['qualification']);
 
 if (!api_is_invitee()) {
@@ -145,20 +141,16 @@ if (!api_is_invitee()) {
     );
 
     $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_work_user_list&work_id='.$workId.'&type='.$type.'&'.api_get_cidreq();
-    ?>
+    $content .= '
         <script>
             $(function() {
-            <?php
-                echo Display::grid_js('results', $url, $columns, $column_model, $extra_params);
-            ?>
+                '.Display::grid_js('results', $url, $columns, $column_model, $extra_params).'            
             });
         </script>
-    <?php
+    ';
 
-    $html = '';
     $tableWork = Display::grid_html('results');
-    $html = Display::panel($tableWork);
-    echo $html;
+    $content .= Display::panel($tableWork);
 }
-
-Display :: display_footer();
+$tpl->assign('content', $content);
+$tpl->display_one_col_template();

+ 14 - 11
plugin/share_buttons/index.php

@@ -3,15 +3,18 @@
  * Controller for example date plugin
  * @package chamilo.plugin.share_buttons
  */
-echo '<div class="well">
-<!-- AddThis Button BEGIN -->
-<div class="addthis_toolbox addthis_default_style '.$plugin_info['icon_class'].' ">
-<a class="addthis_button_preferred_2"></a>
-<a class="addthis_button_preferred_3"></a>
-<a class="addthis_button_preferred_4"></a>
-<a class="addthis_button_compact"></a>
-<a class="addthis_counter addthis_bubble_style"></a>
-</div>
-<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#pubid=xa-4f69d6f847541385"></script>
+echo '
+<div class="well well-sm">
+    <!-- AddThis Button BEGIN -->
+    <div class="addthis_toolbox addthis_default_style ' . $plugin_info['icon_class'] . '">
+        <a class="addthis_button_preferred_1"></a>
+        <a class="addthis_button_preferred_2"></a>
+        <a class="addthis_button_preferred_3"></a>
+        <a class="addthis_button_preferred_4"></a>
+        <a class="addthis_button_compact"></a>
+        <a class="addthis_counter addthis_bubble_style"></a>
+    </div>
 <!-- AddThis Button END -->
-</div>';
+</div>
+<script type="text/javascript" src="//s7.addthis.com/js/250/addthis_widget.js"></script>
+';

+ 1 - 0
src/Chamilo/CoreBundle/Entity/ExtraField.php

@@ -24,6 +24,7 @@ class ExtraField extends BaseAttribute
     const CALENDAR_FIELD_TYPE = 5;
     const LP_FIELD_TYPE = 6;
     const LP_ITEM_FIELD_TYPE = 7;
+    const SKILL_FIELD_TYPE = 8;
 
     /**
      * @var integer

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels