aragonc 9 سال پیش
والد
کامیت
fa1d1bc920
45فایلهای تغییر یافته به همراه461 افزوده شده و 113 حذف شده
  1. 1 0
      .htaccess
  2. 2 0
      main/admin/settings.lib.php
  3. 7 1
      main/admin/user_add.php
  4. 1 1
      main/admin/user_edit.php
  5. 24 4
      main/auth/courses.php
  6. 11 5
      main/auth/courses_controller.php
  7. 15 2
      main/auth/sso/sso.Drupal.class.php
  8. 19 2
      main/auth/sso/sso.class.php
  9. 18 1
      main/course_progress/thematic.php
  10. 1 0
      main/exercice/calculated_answer.class.php
  11. 23 7
      main/exercice/exercise.class.php
  12. 1 1
      main/exercice/exercise_submit.php
  13. 12 2
      main/exercice/overview.php
  14. 2 2
      main/gradebook/index.php
  15. 10 2
      main/gradebook/lib/GradebookUtils.php
  16. 21 6
      main/inc/lib/course.lib.php
  17. 28 10
      main/inc/lib/document.lib.php
  18. 5 2
      main/inc/lib/exercise.lib.php
  19. 1 1
      main/inc/lib/group_portal_manager.lib.php
  20. 14 8
      main/inc/lib/internationalization.lib.php
  21. 53 5
      main/inc/lib/message.lib.php
  22. 13 5
      main/inc/lib/nanogong.lib.php
  23. 1 1
      main/inc/lib/social.lib.php
  24. 6 1
      main/inc/lib/template.lib.php
  25. 1 1
      main/inc/lib/usergroup.lib.php
  26. 2 1
      main/install/configuration.dist.php
  27. 6 1
      main/lang/english/trad4all.inc.php
  28. 5 1
      main/lang/spanish/trad4all.inc.php
  29. 8 1
      main/newscorm/learnpath.class.php
  30. 24 4
      main/session/index.php
  31. 28 2
      main/session/session_import.php
  32. 34 4
      main/social/group_view.php
  33. 0 1
      main/template/default/auth/confirm_session_subscription.tpl
  34. 2 2
      main/template/default/auth/courses_list.php
  35. 6 3
      main/template/default/layout/head.tpl
  36. 1 1
      main/template/default/user_portal/session.tpl
  37. 5 4
      main/webservices/registration.soap.php
  38. 9 9
      main/work/work.lib.php
  39. 1 1
      plugin/advanced_subscription/src/admin_view.php
  40. 10 0
      plugin/advanced_subscription/views/admin_view.tpl
  41. 3 0
      plugin/advanced_subscription/views/css/style.css
  42. 0 4
      plugin/courselegal/lang/english.php
  43. 19 2
      plugin/courselegal/lang/spanish.php
  44. 7 1
      plugin/courselegal/start.php
  45. 1 1
      src/Chamilo/CoreBundle/Component/Editor/Editor.php

+ 1 - 0
.htaccess

@@ -30,6 +30,7 @@ RewriteRule ^courses/([^/]+)/work/(.*)$ main/work/download.php?file=work/$2&cDir
 
 # Course upload files
 RewriteRule ^courses/([^/]+)/upload/(.*)$ app/courses/$1/upload/$2 [QSA,L]
+RewriteRule ^courses/([^/]+)/(.*)$ app/courses/$1/$2 [QSA,L]
 
 RewriteRule ^courses/([^/]+)/course-pic85x85.png$ app/courses/$1/course-pic85x85.png [QSA,L]
 RewriteRule ^courses/([^/]+)/course-pic.png$ app/courses/$1/course-pic.png [QSA,L]

+ 2 - 0
main/admin/settings.lib.php

@@ -183,6 +183,8 @@ function handle_plugins()
                     api_get_path(WEB_PLUGIN_PATH) . $plugin . "/readme.txt",
                     [
                         'class' => 'btn btn-default ajax',
+                        'data-title' => $plugin_info['title'],
+                        'data-size' => 'lg',
                         '_target' => '_blank'
                     ]
                 );

+ 7 - 1
main/admin/user_add.php

@@ -177,7 +177,13 @@ if (isset($extAuthSource) && count($extAuthSource) > 0) {
 }
 
 $group[] = $form->createElement('radio', 'password_auto', get_lang('Password'), get_lang('AutoGeneratePassword').'<br />', 1);
-$group[] = $form->createElement('radio', 'password_auto', 'id="radio_user_password"', null, 0);
+$group[] = $form->createElement(
+    'radio',
+    'password_auto',
+    'id="radio_user_password"',
+    get_lang('EnterPassword'),
+    0
+);
 $group[] = $form->createElement(
     'password',
     'password',

+ 1 - 1
main/admin/user_edit.php

@@ -194,7 +194,7 @@ if (isset($extAuthSource) && !empty($extAuthSource) && count($extAuthSource) > 0
 }
 $form->addElement('radio', 'reset_password', null, get_lang('AutoGeneratePassword'), 1);
 $group = array();
-$group[] =$form->createElement('radio', 'reset_password', null, null, 2);
+$group[] =$form->createElement('radio', 'reset_password', null, get_lang('EnterPassword'), 2);
 $group[] = $form->createElement(
     'password',
     'password',

+ 24 - 4
main/auth/courses.php

@@ -187,6 +187,10 @@ switch ($action) {
         $courses_controller->courses_list($action);
         break;
     case 'subscribe':
+        if (!$user_can_view_page) {
+            api_not_allowed(true);
+        }
+
         $courses_controller->courses_categories(
             $action,
             $categoryCode,
@@ -197,13 +201,17 @@ switch ($action) {
         );
         break;
     case 'display_random_courses':
-        if ($user_can_view_page) {
-            $courses_controller->courses_categories($action);
-        } else {
-            api_not_allowed();
+        if (!$user_can_view_page) {
+            api_not_allowed(true);
         }
+
+        $courses_controller->courses_categories($action);
         break;
     case 'display_courses':
+        if (!$user_can_view_page) {
+            api_not_allowed(true);
+        }
+
         $courses_controller->courses_categories(
             $action,
             $categoryCode,
@@ -214,9 +222,17 @@ switch ($action) {
         );
         break;
     case 'display_sessions':
+        if (!$user_can_view_page) {
+            api_not_allowed(true);
+        }
+
         $courses_controller->sessionsList($action, $nameTools, $limit);
         break;
     case 'subscribe_to_session':
+        if (!$user_can_view_page) {
+            api_not_allowed(true);
+        }
+
         $userId = api_get_user_id();
         $confirmed = isset($_GET['confirm']);
         $sessionId = intval($_GET['session_id']);
@@ -287,6 +303,10 @@ switch ($action) {
         //else show error message?
         break;
     case 'search_tag':
+        if (!$user_can_view_page) {
+            api_not_allowed(true);
+        }
+
         $courses_controller->sessionsListByCoursesTag($limit);
         break;
 }

+ 11 - 5
main/auth/courses_controller.php

@@ -501,7 +501,6 @@ class CoursesController
                 'a' => 'get_requirements',
                 'id' => intval($sessionId),
                 'type' => SequenceResource::SESSION_TYPE,
-                'modal_size' => 'md',
             ]);
 
             return Display::toolbarButton(
@@ -509,7 +508,11 @@ class CoursesController
                 $url,
                 'check-circle',
                 'primary',
-                ['class' => 'btn-lg btn-block ajax']
+                [
+                    'class' => 'btn-lg btn-block ajax',
+                    'data-title' => get_lang('CheckRequirements'),
+                    'data-size' => 'md'
+                ]
             );
         }
 
@@ -527,8 +530,7 @@ class CoursesController
             $url .= 'auth/courses.php?';
             $url .= http_build_query([
                 'action' => 'subscribe_to_session',
-                'session_id' => intval($sessionId),
-                'modal_size' => 'md',
+                'session_id' => intval($sessionId)
             ]);
 
             $result = Display::toolbarButton(
@@ -536,7 +538,11 @@ class CoursesController
                 $url,
                 'check-circle',
                 'primary',
-                ['class' => 'btn-lg btn-block ajax']
+                [
+                    'class' => 'btn-lg btn-block ajax',
+                    'data-title' => get_lang('AreYouSureToSubscribe'),
+                    'data-size' => 'md'
+                ]
             );
         } else {
             $url .= 'inc/email_editor.php?';

+ 15 - 2
main/auth/sso/sso.Drupal.class.php

@@ -44,6 +44,7 @@ class ssoDrupal
         $this->referer    = $this->protocol.$_SERVER['HTTP_HOST'].substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], 'sso'));
         $this->deauth_url = $this->protocol.$this->domain.$this->deauth_uri;
         $this->master_url = $this->protocol.$this->domain.$this->auth_uri;
+        $this->referrer_uri = base64_encode($_SERVER['REQUEST_URI']);
         $this->target     = api_get_path(WEB_PATH);
     }
 
@@ -70,7 +71,10 @@ class ssoDrupal
         // Redirect browser to the master URL
         $params = '';
         if (empty($_GET['no_redirect'])) {
-            $params = 'sso_referer='.urlencode($this->referer).'&sso_target='.urlencode($this->target).'&sso_challenge='.urlencode($_SESSION['sso_challenge']);
+            $params = 'sso_referer='.urlencode($this->referer).
+                '&sso_target='.urlencode($this->target).
+                '&sso_challenge='.urlencode($_SESSION['sso_challenge']).
+                '&sso_ruri='.urlencode($this->referrer_uri);
             if (strpos($this->master_url, "?") === false) {
                 $params = "?{$params}";
             } else {
@@ -144,7 +148,16 @@ class ssoDrupal
                                         Session::write('_user', $_user);
                                         Event::event_login($_user['user_id']);
                                         // Redirect to homepage
-                                        $sso_target = isset($sso['target']) ? $sso['target'] : api_get_path(WEB_PATH) . 'index.php';
+                                        $sso_target = '';
+                                        if (!empty($sso['ruri'])) {
+                                            //The referrer URI is *only* used if
+                                            // the user credentials are OK, which
+                                            // should be protection enough
+                                            // against evil URL spoofing...
+                                            $sso_target = api_get_path(WEB_PATH) . base64_decode($sso['ruri']);
+                                        } else {
+                                            $sso_target = isset($sso['target']) ? $sso['target'] : api_get_path(WEB_PATH) . 'index.php';
+                                        }
                                         header('Location: '. $sso_target);
                                         exit;
                                     } else {

+ 19 - 2
main/auth/sso/sso.class.php

@@ -22,6 +22,12 @@ class sso {
     public $deauth_uri; //    '/?q=logout',
     public $referer; // http://my.chamilo.com/main/auth/profile.php
 
+    /*
+     * referrer_uri: [some/path/inside/Chamilo], might be used by module to
+     * redirect the user to where he wanted to go initially in Chamilo
+     */
+    public $referrer_uri;
+
     /**
      * Instanciates the object, initializing all relevant URL strings
      */
@@ -38,6 +44,7 @@ class sso {
         $this->referer    = $this->protocol.$_SERVER['HTTP_HOST'].substr($_SERVER['REQUEST_URI'],0,strpos($_SERVER['REQUEST_URI'],'sso'));
         $this->deauth_url = $this->protocol.$this->domain.$this->deauth_uri;
         $this->master_url = $this->protocol.$this->domain.$this->auth_uri;
+        $this->referrer_uri = base64_encode($_SERVER['REQUEST_URI']);
         $this->target     = api_get_path(WEB_PATH);
     }
 
@@ -58,7 +65,8 @@ class sso {
         $tempKey = api_generate_password(32);
         $params = 'sso_referer='.urlencode($this->referer).
             '&sso_target='.urlencode($this->target).
-            '&sso_challenge='.$tempKey;
+            '&sso_challenge='.$tempKey.
+            '&sso_ruri='.urlencode($this->referrer_uri);
         Session::write('tempkey', $tempKey);
         if (strpos($this->master_url, "?") === false) {
             $params = "?$params";
@@ -152,7 +160,16 @@ class sso {
                                         Session::write('_user', $_user);
                                         Event::event_login($_user['user_id']);
                                         // Redirect to homepage
-                                        $sso_target = isset($sso['target']) ? $sso['target'] : api_get_path(WEB_PATH) .'.index.php';
+                                        $sso_target = '';
+                                        if (!empty($sso['ruri'])) {
+                                            //The referrer URI is *only* used if
+                                            // the user credentials are OK, which
+                                            // should be protection enough
+                                            // against evil URL spoofing...
+                                            $sso_target = api_get_path(WEB_PATH) . base64_decode($sso['ruri']);
+                                        } else {
+                                            $sso_target = isset($sso['target']) ? $sso['target'] : api_get_path(WEB_PATH) . 'index.php';
+                                        }
                                         header('Location: '. $sso_target);
                                         exit;
                                     } else {

+ 18 - 1
main/course_progress/thematic.php

@@ -180,7 +180,24 @@ if ($action == 'thematic_list') {
 
                     $edit_link = '';
                     if (api_is_allowed_to_edit(null, true)) {
-                        $edit_link   = '<a class="ajax" href="index.php?'.api_get_cidreq().'&action=thematic_advance_edit&thematic_id='.$thematic['id'].'&thematic_advance_id='.$thematic_advance['id'].'&display=no_header" >'.Display::return_icon('edit.png',get_lang('EditThematicAdvance'),array(),ICON_SIZE_SMALL).'</a>';
+                        $edit_link = Display::url(
+                            Display::return_icon(
+                                'edit.png',
+                                get_lang('EditThematicAdvance'),
+                                [],
+                                ICON_SIZE_SMALL
+                            ),
+                            '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')
+                            ]
+                        );
                         $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>';
 

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

@@ -141,6 +141,7 @@ class CalculatedAnswer extends Question
             api_get_path(WEB_PATH).'main/exercice/evalmathnotation.php',
             array(
                 'class' => 'btn ajax',
+                'data-title' => get_lang('NotationList'),
                 '_target' => '_blank'
             )
         );

+ 23 - 7
main/exercice/exercise.class.php

@@ -1851,15 +1851,31 @@ class Exercise
         $hotspot_get = isset($_POST['hotspot']) ? Security::remove_XSS($_POST['hotspot']):null;
 
         if ($this->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT && $this->type == ONE_PER_PAGE) {
-            $html .='<a
-                href="exercise_submit_modal.php?learnpath_id='.$safe_lp_id.'&learnpath_item_id='.$safe_lp_item_id.'&learnpath_item_view_id='.$safe_lp_item_view_id.'&origin='.$origin.'&hotspot='.$hotspot_get.'&nbrQuestions='.$nbrQuestions.'&num='.$questionNum.'&exerciseType='.$this->type.'&exerciseId='.$this->id.'&height=480&width=640&modal=true"
-                title=""
-                class="ajax btn btn-default">';
+            $urlTitle = get_lang('ContinueTest');
+
             if ($questionNum == count($this->questionList)) {
-                $html .= get_lang('EndTest').'</a>';
-            } else {
-                $html .= get_lang('ContinueTest').'</a>';
+                $urlTitle = get_lang('EndTest');
             }
+
+            $html .= Display::url(
+                $urlTitle,
+                'exercise_submit_modal.php?' . http_build_query([
+                    'learnpath_id' => $safe_lp_id,
+                    'learnpath_item_id' => $safe_lp_item_id,
+                    'learnpath_item_view_id' => $safe_lp_item_view_id,
+                    'origin' => $origin,
+                    'hotspot' => $hotspot_get,
+                    'nbrQuestions' => $nbrQuestions,
+                    'num' => $questionNum,
+                    'exerciseType' => $this->type,
+                    'exerciseId' => $this->id
+                ]),
+                [
+                    'class' => 'ajax btn btn-default',
+                    'data-title' => $urlTitle,
+                    'data-size' => 'md'
+                ]
+            );
             $html .='<br />';
         } else {
             // User

+ 1 - 1
main/exercice/exercise_submit.php

@@ -55,7 +55,7 @@ $htmlHeadXtra[] = api_get_js('d3/jquery.xcolor.js');
 
 //This library is necessary for the time control feature
 //tmlHeadXtra[] = api_get_css(api_get_path(WEB_LIBRARY_PATH).'javascript/epiclock/stylesheet/jquery.epiclock.css');
-//$htmlHeadXtra[] = api_get_css(api_get_path(WEB_LIBRARY_PATH).'javascript/epiclock/renderers/minute/epiclock.minute.css');
+$htmlHeadXtra[] = api_get_css(api_get_path(WEB_LIBRARY_PATH).'javascript/epiclock/renderers/minute/epiclock.minute.css');
 $htmlHeadXtra[] = api_get_js('epiclock/javascript/jquery.dateformat.min.js');
 $htmlHeadXtra[] = api_get_js('epiclock/javascript/jquery.epiclock.min.js');
 $htmlHeadXtra[] = api_get_js('epiclock/renderers/minute/epiclock.minute.js');

+ 12 - 2
main/exercice/overview.php

@@ -163,11 +163,21 @@ if (!empty($attempts)) {
             $attempt_result['exe_result'],
             $attempt_result['exe_weighting']
         );
-        $attempt_url = api_get_path(WEB_CODE_PATH) . 'exercice/result.php?' . api_get_cidreq() . '&id=' . $attempt_result['exe_id'] . '&modal_size=lg' . $url_suffix;
+        $attempt_url = api_get_path(WEB_CODE_PATH) . 'exercice/result.php?';
+        $attempt_url .= api_get_cidreq() . '&';
+        $attempt_url .= http_build_query([
+            'id' => $attempt_result['exe_id']
+        ]);
+        $attempt_url .= $url_suffix;
+
         $attempt_link = Display::url(
             get_lang('Show'),
             $attempt_url,
-            array('class' => $btn_class . 'btn btn-default')
+            [
+                'class' => $btn_class . 'btn btn-default',
+                'data-title' => get_lang('Show'),
+                'data-size' => 'lg'
+            ]
         );
 
         $teacher_revised = Display::label(get_lang('Validated'), 'success');

+ 2 - 2
main/gradebook/index.php

@@ -772,7 +772,7 @@ if ($category != '0') {
             );
             if (!empty($certificate)) {
                 echo Display::url(
-                    get_lang('CertificateToPdf'),
+                    get_lang('DownloadCertificatePdf'),
                     $certificate['pdf_url'],
                     ['class' => 'btn btn-default']
                 );
@@ -786,7 +786,7 @@ if ($category != '0') {
 
 if (!api_is_allowed_to_edit(null, true)) {
     echo Display::url(
-        get_lang('ReportToPdf'),
+        get_lang('DownloadReportPdf'),
         api_get_self()."?".api_get_self()."&action=export_table",
         ['class' => 'btn btn-default']
     );

+ 10 - 2
main/gradebook/lib/GradebookUtils.php

@@ -199,13 +199,21 @@ class GradebookUtils
                 Display::return_icon('view_more_stats.gif', get_lang('Show'), '', ICON_SIZE_SMALL) . '</a>';
 
             if (!api_is_allowed_to_edit(null, true)) {
-                $modify_icons .= '  <a class="ajax" href="personal_stats.php?selectcat='.$cat->get_id().'&'.api_get_cidreq().'">'.
+                $modify_icons .= Display::url(
                     Display::return_icon(
                         'stats.png',
                         get_lang('FlatView'),
                         '',
                         ICON_SIZE_SMALL
-                    ).'</a>';
+                    ),
+                    'personal_stats.php?' . http_build_query([
+                        'selectcat' => $cat->get_id()
+                    ]) . '&' . api_get_cidreq(),
+                    [
+                        'class' => 'ajax',
+                        'data-title' => get_lang('FlatView')
+                    ]
+                );
             }
 
             if (api_is_allowed_to_edit(null, true)) {

+ 21 - 6
main/inc/lib/course.lib.php

@@ -1841,11 +1841,14 @@ class CourseManager
                     $teacher['lastname']
                 );
                 if ($add_link_to_profile) {
-                    $url = api_get_path(WEB_AJAX_PATH) . 'user_manager.ajax.php?a=get_user_popup&resizable=0&height=500&user_id=' . $teacher['user_id'];
+                    $url = api_get_path(WEB_AJAX_PATH) . 'user_manager.ajax.php?a=get_user_popup&user_id=' . $teacher['user_id'];
                     $teacher_name = Display::url(
                         $teacher_name,
                         $url,
-                        array('class' => 'ajax')
+                        [
+                            'class' => 'ajax',
+                            'data-title' => $teacher_name
+                        ]
                     );
                 }
                 $list[] = $teacher_name;
@@ -1925,8 +1928,15 @@ class CourseManager
             foreach ($coachs_course as $coach_course) {
                 $coach_name = api_get_person_name($coach_course['firstname'], $coach_course['lastname']);
                 if ($add_link_to_profile) {
-                    $url = api_get_path(WEB_AJAX_PATH) . 'user_manager.ajax.php?a=get_user_popup&resizable=0&height=300&user_id=' . $coach_course['user_id'];
-                    $coach_name = Display::url($coach_name, $url, array('class' => 'ajax'));
+                    $url = api_get_path(WEB_AJAX_PATH) . 'user_manager.ajax.php?a=get_user_popup&user_id=' . $coach_course['user_id'];
+                    $coach_name = Display::url(
+                        $coach_name,
+                        $url,
+                        [
+                            'class' => 'ajax',
+                            'data-title' => $coach_name
+                        ]
+                    );
                 }
                 $course_coachs[] = $coach_name;
             }
@@ -4571,9 +4581,14 @@ class CourseManager
             if ($course_info['visibility'] == COURSE_VISIBILITY_OPEN_WORLD || in_array($course_info['real_id'],
                     $my_course_code_list)
             ) {
-                $my_course['extra_info']['description_button'] = Display::url(get_lang('Description'),
+                $my_course['extra_info']['description_button'] = Display::url(
+                    get_lang('Description'),
                     api_get_path(WEB_AJAX_PATH) . 'course_home.ajax.php?a=show_course_information&code=' . $course_info['code'],
-                    array('class' => 'btn btn-default btn-sm btn-block ajax'));
+                    [
+                        'class' => 'btn btn-default btn-sm btn-block ajax',
+                        'data-title' => get_lang('Description')
+                    ]
+                );
             }
 
             $my_course['extra_info']['teachers'] = CourseManager::get_teacher_list_from_course_code_to_string($course_info['code']);

+ 28 - 10
main/inc/lib/document.lib.php

@@ -323,11 +323,11 @@ class DocumentManager
         $len = filesize($full_file_name);
         // Fixing error when file name contains a ","
         $filename = str_replace(',', '', $filename);
+        global $_configuration;
 
         if ($forced) {
             // Force the browser to save the file instead of opening it
 
-            global $_configuration;
             if (isset($_configuration['enable_x_sendfile_headers']) &&
                 !empty($_configuration['enable_x_sendfile_headers'])) {
                 header("X-Sendfile: $filename");
@@ -364,15 +364,23 @@ class DocumentManager
             //header('Pragma: no-cache');
             switch ($content_type) {
                 case 'text/html':
-                    $encoding = @api_detect_encoding_html(file_get_contents($full_file_name));
-                    if (!empty($encoding)) {
-                        $content_type .= '; charset=' . $encoding;
+                    if (isset($_configuration['lp_fixed_encoding']) && $_configuration['lp_fixed_encoding'] === 'true') {
+                        $content_type .= '; charset=UTF-8';
+                    } else {
+                        $encoding = @api_detect_encoding_html(file_get_contents($full_file_name));
+                        if (!empty($encoding)) {
+                            $content_type .= '; charset=' . $encoding;
+                        }
                     }
                     break;
                 case 'text/plain':
-                    $encoding = @api_detect_encoding(strip_tags(file_get_contents($full_file_name)));
-                    if (!empty($encoding)) {
-                        $content_type .= '; charset=' . $encoding;
+                    if (isset($_configuration['lp_fixed_encoding']) && $_configuration['lp_fixed_encoding'] === 'true') {
+                        $content_type .= '; charset=UTF-8';
+                    } else {
+                        $encoding = @api_detect_encoding(strip_tags(file_get_contents($full_file_name)));
+                        if (!empty($encoding)) {
+                            $content_type .= '; charset=' . $encoding;
+                        }
                     }
                     break;
                 case 'application/vnd.dwg':
@@ -5253,13 +5261,23 @@ class DocumentManager
                     )
                 ) {
                     // Simpler version of showinframesmin.php with no headers
-                    $url = 'show_content.php?' . api_get_cidreq() . '&id=' . $document_data['id']. '&width=700&height=500';
+                    $url = 'show_content.php?' . api_get_cidreq() . '&id=' . $document_data['id'];
                     $class = 'ajax';
                     if ($visibility == false) {
                         $class = "ajax invisible";
                     }
-                    return '<a href="' . $url . '" class="' . $class . '" title="' . $tooltip_title_alt . '" style="float:left">' . $title . '</a>' .
-                    $force_download_html . $send_to . $copy_to_myfiles . $open_in_new_window_link . $pdf_icon;
+                    return Display::url(
+                        $title,
+                        $url,
+                        [
+                            'class' => $class,
+                            'title' => $tooltip_title_alt,
+                            'data-title' => $title,
+                            'style' => 'float: left;'
+                        ]
+                    )
+                        . $force_download_html . $send_to . $copy_to_myfiles
+                        . $open_in_new_window_link . $pdf_icon;
                 } else {
                     // For PDF Download the file.
                     $pdfPreview = null;

+ 5 - 2
main/inc/lib/exercise.lib.php

@@ -2048,11 +2048,14 @@ HTML;
                             $attempt_url = api_get_path(
                                     WEB_CODE_PATH
                                 ) . 'exercice/result.php?' . api_get_cidreq(
-                                ) . '&id=' . $results[$i]['exe_id'] . '&id_session=' . $sessionId . '&height=500&width=750';
+                                ) . '&id=' . $results[$i]['exe_id'] . '&id_session=' . $sessionId;
                             $attempt_link = Display::url(
                                 get_lang('Show'),
                                 $attempt_url,
-                                array('class' => 'ajax btn')
+                                [
+                                    'class' => 'ajax btn btn-default',
+                                    'data-title' => get_lang('Show')
+                                ]
                             );
                             $actions .= $attempt_link;
                         }

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

@@ -1256,7 +1256,7 @@ class GroupPortalManager
                 break;
             case GROUP_USER_PERMISSION_HRM:
                 $relation_group_title = get_lang('IAmAHRM');
-                $links .= '<li><a href="'.api_get_path(WEB_CODE_PATH).'social/message_for_group_form.inc.php?view_panel=1&height=400&width=610&&user_friend='.api_get_user_id().'&group_id='.$group_id.'&action=add_message_group" class="ajax" title="'.get_lang('ComposeMessage').'">'.Display::return_icon('compose_message.png', get_lang('NewTopic'), array('hspace' => '6')).'<span class="social-menu-text4" >'.get_lang('NewTopic').'</span></a></li>';
+                $links .= '<li><a href="'.api_get_path(WEB_CODE_PATH).'social/message_for_group_form.inc.php?view_panel=1&height=400&width=610&&user_friend='.api_get_user_id().'&group_id='.$group_id.'&action=add_message_group" class="ajax" data-title="'.get_lang('ComposeMessage').' title="'.get_lang('ComposeMessage').'">'.Display::return_icon('compose_message.png', get_lang('NewTopic'), array('hspace' => '6')).'<span class="social-menu-text4" >'.get_lang('NewTopic').'</span></a></li>';
                 $links .= '<li><a href="group_view.php?id='.$group_id.'">'.Display::return_icon('message_list.png', get_lang('MessageList'), array('hspace' => '6')).'<span class="'.($show == 'messages_list' ? 'social-menu-text-active' : 'social-menu-text4').'" >'.get_lang('MessageList').'</span></a></li>';
                 $links .= '<li><a href="group_invitation.php?id='.$group_id.'">'.Display::return_icon('invitation_friend.png', get_lang('InviteFriends'), array('hspace' => '6')).'<span class="'.($show == 'invite_friends' ? 'social-menu-text-active' : 'social-menu-text4').'" >'.get_lang('InviteFriends').'</span></a></li>';
                 $links .= '<li><a href="group_members.php?id='.$group_id.'">'.Display::return_icon('member_list.png', get_lang('MemberList'), array('hspace' => '6')).'<span class="'.($show == 'member_list' ? 'social-menu-text-active' : 'social-menu-text4').'" >'.get_lang('MemberList').'</span></a></li>';

+ 14 - 8
main/inc/lib/internationalization.lib.php

@@ -195,16 +195,22 @@ function api_get_interface_language($purified = false, $check_sub_language = fal
             $language_id = api_get_language_id($language_interface);
             $language_info = api_get_language_info($language_id);
 
-            if (!empty($language_id) &&
-                !empty($language_info) &&
-                !empty($language_info['parent_id'])) {
-
-                $language_info = api_get_language_info($language_info['parent_id']);
-                $parent_language_name = $language_info['english_name'];
-                if (!empty($parent_language_name)) {
-                    return $parent_language_name;
+            if (
+                !empty($language_id) &&
+                !empty($language_info)
+            ) {
+                if (!empty($language_info['parent_id'])) {
+                    $language_info = api_get_language_info($language_info['parent_id']);
+                    $parent_language_name = $language_info['english_name'];
+
+                    if (!empty($parent_language_name)) {
+                        return $parent_language_name;
+                    }
                 }
+
+                return $language_info['english_name'];
             }
+
             return 'english';
         } else {
             return $parent_language_name;

+ 53 - 5
main/inc/lib/message.lib.php

@@ -1270,10 +1270,58 @@ class MessageManager
         $topic_page_nr = isset($_GET['topics_page_nr']) ? intval($_GET['topics_page_nr']) : null;
         $links.= '<div id="message-reply-link">';
         if (($my_group_role == GROUP_USER_PERMISSION_ADMIN || $my_group_role == GROUP_USER_PERMISSION_MODERATOR) || $main_message['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='.$main_message['id'].'&action=edit_message_group&anchor_topic=topic_'.$main_message['id'].'&topics_page_nr='.$topic_page_nr.'&items_page_nr='.$items_page_nr.'&topic_id='.$main_message['id'].'" class="ajax btn" title="'.get_lang('Edit').'">';
-            $links.= Display :: return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>';
+            $urlEdit = api_get_path(WEB_CODE_PATH);
+            $urlEdit .= 'social/message_for_group_form.inc.php?';
+            $urlEdit .= http_build_query([
+                'user_friend' => $current_user_id,
+                'group_id' => $group_id,
+                'message_id' => $main_message['id'],
+                'action' => 'edit_message_group',
+                'anchor_topic' => 'topic_' . $main_message['id'],
+                'topics_page_nr' => $topic_page_nr,
+                'items_page_nr' => $items_page_nr,
+                'topic_id' => $main_message['id']
+            ]);
+
+            $links .= Display::url(
+                Display::return_icon(
+                    'edit.png',
+                    get_lang('Edit'),
+                    array(),
+                    ICON_SIZE_SMALL
+                ),
+                $urlEdit,
+                [
+                    'class' => 'ajax btn btn-default',
+                    'title' => get_lang('Edit'),
+                    'data-title' => get_lang('Edit')
+                ]
+            );
         }
-        $links.= '&nbsp;&nbsp;<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='.$main_message['id'].'&action=reply_message_group&anchor_topic=topic_'.$main_message['id'].'&topics_page_nr='.$topic_page_nr.'&items_page_nr='.$items_page_nr.'&topic_id='.$main_message['id'].'" class="ajax btn" title="'.get_lang('Reply').'">';
+
+        $urlReply = api_get_path(WEB_CODE_PATH);
+        $urlReply .= 'social/message_for_group_form.inc.php?';
+        $urlReply .= http_build_query([
+            'user_friend' => api_get_user_id(),
+            'group_id' => $group_id,
+            'message_id' => $main_message['id'],
+            'action' => 'reply_message_group',
+            'anchor_topic' => 'topic_' . $main_message['id'],
+            'topics_page_nr' => $topic_page_nr,
+            'topic_id' => $main_message['id']
+        ]);
+
+        $links .= Display::url(
+            Display::return_icon('talk.png', get_lang('Reply')),
+            $urlReply,
+            [
+                'class' => 'ajax btn btn-default',
+                'title' => get_lang('Reply'),
+                'data-title' => get_lang('Reply')
+            ]
+        );
+        
+        $links.= '&nbsp;&nbsp; &topics_page_nr='.$topic_page_nr.'&items_page_nr='.$items_page_nr.'&topic_id='.$main_message['id'].'" class="ajax btn" title="'.get_lang('Reply').'">';
         $links.= Display :: return_icon('talk.png', get_lang('Reply')).'</a>';
         $links.= '</div>';
 
@@ -1315,10 +1363,10 @@ class MessageManager
 
                 $links.= '<div id="message-reply-link">';
                 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" title="'.get_lang('Edit').'">'.
+                    $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" data-title="'.get_lang('Edit').'" title="'.get_lang('Edit').'">'.
                         Display :: return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>';
                 }
-                $links.= '&nbsp;&nbsp;<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" title="'.get_lang('Reply').'">';
+                $links.= '&nbsp;&nbsp;<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" data-title="'.get_lang('Reply').'" title="'.get_lang('Reply').'">';
                 $links.= Display :: return_icon('talk.png', get_lang('Reply')).'</a>';
                 $links.= '</div>';
 

+ 13 - 5
main/inc/lib/nanogong.lib.php

@@ -659,12 +659,20 @@ class Nanogong
     public function show_button()
     {
 		$params_string = $this->get_params(true);
-        $html = '<br />'.Display::url(
+
+        $url = api_get_path(WEB_AJAX_PATH)
+            . 'nanogong.ajax.php?a=show_form&'
+            . $params_string
+            . '&TB_iframe=true';
+
+        $html = '<br />';
+        $html = Display::url(
             get_lang('RecordAnswer'),
-            api_get_path(
-                WEB_AJAX_PATH
-            ).'nanogong.ajax.php?a=show_form&'.$params_string.'&TB_iframe=true&height=400&width=500',
-            array('class' => 'btn btn-default ajax')
+            $url,
+            [
+                'class' => 'btn btn-default ajax',
+                'data-title' => get_lang('RecordAnswer')
+            ]
         );
 		$html .= '<br /><br />'.Display::return_message(get_lang('UseTheMessageBelowToAddSomeComments'));
 		return $html;

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

@@ -1596,7 +1596,7 @@ class SocialManager extends UserManager
                     $friendHtml.= ' <span>'
                         .'<a href="'.api_get_path(WEB_CODE_PATH).'social/profile_friends_and_groups.inc.php'
                         .'?view=friends&height=390&width=610&user_id='.$user_id.'"'
-                        .'class="ajax" title="'.get_lang('SeeAll').'" >'.get_lang('SeeAll').'</a></span>';
+                        .'class="ajax" data-title="'.get_lang('SeeAll').'" title="'.get_lang('SeeAll').'" >'.get_lang('SeeAll').'</a></span>';
                 }
             }
 

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

@@ -248,7 +248,12 @@ class Template
                 $content = '<li class="help">';
                 $content .= Display::url(
                     Display::return_icon('help.large.png', get_lang('Help')),
-                    api_get_path(WEB_CODE_PATH).'help/help.php?open='.$help.'&height=400&width=600', array('class' => 'ajax'));
+                    api_get_path(WEB_CODE_PATH) . 'help/help.php?open=' . $help,
+                    [
+                        'class' => 'ajax',
+                        'data-title' => get_lang('Help')
+                    ]
+                );
                 $content .= '</li>';
             }
         }

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

@@ -2001,7 +2001,7 @@ class UserGroup extends Model
                 break;
             case GROUP_USER_PERMISSION_HRM:
                 $relation_group_title = get_lang('IAmAHRM');
-                $links .= '<li><a href="'.api_get_path(WEB_CODE_PATH).'social/message_for_group_form.inc.php?view_panel=1&height=400&width=610&&user_friend='.api_get_user_id().'&group_id='.$group_id.'&action=add_message_group" class="ajax" title="'.get_lang('ComposeMessage').'">'.
+                $links .= '<li><a href="'.api_get_path(WEB_CODE_PATH).'social/message_for_group_form.inc.php?view_panel=1&height=400&width=610&&user_friend='.api_get_user_id().'&group_id='.$group_id.'&action=add_message_group" class="ajax" title="'.get_lang('ComposeMessage').'" data-title="'.get_lang('ComposeMessage').'">'.
                             Display::return_icon('compose_message.png', get_lang('NewTopic'), array('hspace'=>'6')).'<span class="social-menu-text4" >'.get_lang('NewTopic').'</span></a></li>';
                 $links .=  '<li><a href="group_view.php?id='.$group_id.'">'.
                             Display::return_icon('message_list.png', get_lang('MessageList'), array('hspace'=>'6')).'<span class="'.($show=='messages_list'?'social-menu-text-active':'social-menu-text4').'" >'.get_lang('MessageList').'</span></a></li>';

+ 2 - 1
main/install/configuration.dist.php

@@ -213,4 +213,5 @@ $_configuration['system_stable'] = NEW_VERSION_STABLE;
     'language',
     'extra_fields'
 ];*/
-
+// Boost option to ignore encoding check for learning paths
+//$_configuration['lp_fixed_encoding'] = 'false';

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

@@ -5351,6 +5351,7 @@ $SendEmailToAdminComment = "Send an email to the platform administrator, each ti
 $UserTag = "User tag";
 $SelectSession = "Select session";
 $SpecialCourse = "Special course";
+$DurationInWords = "Duration in words";
 $MathASCIImathMLTitle = "ASCIIMathML mathematical editor";
 $MathASCIImathMLComment = "Enable ASCIIMathML mathematical editor";
 $YoutubeForStudentsTitle = "Allow learners to insert videos from YouTube";
@@ -6185,6 +6186,7 @@ $ChatFiles = "Chat conversations history";
 $Flash = "Flash";
 $Video = "Video";
 $Images = "Images";
+$UploadCorrections = "Upload corrections";
 $Text2AudioTitle = "Enable online services for text to speech conversion";
 $Text2AudioComment = "Online tool to convert text to speech. Uses speech synthesis technology to generate audio files saved into your course.";
 $ShowUsersFoldersTitle = "Show users folders in the documents tool";
@@ -7286,7 +7288,7 @@ $ShowOfficialCodeInExerciseResultListComment = "Whether to show the students' of
 $HidePrivateCoursesFromCourseCatalogTitle = "Hide private courses from catalogue";
 $HidePrivateCoursesFromCourseCatalogComment = "Whether to hide the private courses from the courses catalogue. This makes sense when you use the course catalogue mainly to allow students to auto-subscribe to the courses.";
 $CoursesCatalogueShowSessionsTitle = "Sessions and courses catalogue";
-$CoursesCatalogueShowSessionsComment = "Whether you want to show only courses, only sessions or both courses *and* sessions in the courses catalogue";
+$CoursesCatalogueShowSessionsComment = "Whether you want to show only courses, only sessions or both courses *and* sessions in the courses catalogue.";
 $AutoDetectLanguageCustomPagesTitle = "Enable language auto-detect in custom pages";
 $AutoDetectLanguageCustomPagesComment = "If you use custom pages, enable this if you want to have a language detector there present the page in the user's browser language, or disable to force the language to be the default platform language.";
 $LearningPathShowReducedReportTitle = "Learning paths: show reduced report";
@@ -7499,4 +7501,7 @@ $ResetPasswordTokenLimitTitle = "Time limit for password reset token";
 $ResetPasswordTokenLimitComment = "The number of seconds before the generated token automatically expires and cannot be used anymore (a new token needs to be generated).";
 $ViewMyCoursesListBySessionTitle = "View my courses by session";
 $ViewMyCoursesListBySessionComment = "Enable an additional 'My courses' page where sessions appear as part of courses, rather than the opposite.";
+$DownloadCertificatePdf = "Download certificate in PDF";
+$EnterPassword = "Enter password";
+$DownloadReportPdf = "Download report in PDF";
 ?>

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

@@ -5351,6 +5351,7 @@ $SendEmailToAdminComment = "Enviar un correo electrónico al administrador de la
 $UserTag = "Etiqueta de usuario";
 $SelectSession = "Seleccionar sesión";
 $SpecialCourse = "Curso especial";
+$DurationInWords = "Duración en texto";
 $MathASCIImathMLTitle = "Editor matemático ASCIIMathML";
 $MathASCIImathMLComment = "Habilitar el editor matemático ASCIIMathML";
 $YoutubeForStudentsTitle = "Permitir a los estudiantes insertar videos de YouTube";
@@ -7315,7 +7316,7 @@ $ShowOfficialCodeInExerciseResultListComment = "Activar para mostrar el código
 $HidePrivateCoursesFromCourseCatalogTitle = "Esconder los cursos privados del catálogo";
 $HidePrivateCoursesFromCourseCatalogComment = "Activar para esconder los cursos privados del catálogo de curso. Este parámetro tiene sentido cuando se usa el catálogo solo para permitir a los alumnos auto-inscribirse en los cursos (en este caso no tiene sentido mostrarles cursos a los cuales no pueden inscribirse).";
 $CoursesCatalogueShowSessionsTitle = "Catálogo de cursos y sesiones";
-$CoursesCatalogueShowSessionsComment = "Mostrar alternativamente solo los cursos, solo las sesions, o ámbos en el catálogo de cursos.";
+$CoursesCatalogueShowSessionsComment = "Mostrar alternativamente solo los cursos, solo las sesiones, o ambos en el catálogo de cursos.";
 $AutoDetectLanguageCustomPagesTitle = "Auto-detección de idiomas en custom pages";
 $AutoDetectLanguageCustomPagesComment = "Si usa los custom pages (páginas de bienvenida personalizadas), active este parámetro si desea activar el detector de idioma para presentar esta página de bienvenida en su idioma. Desactive para usar el idioma por defecto de la plataforma. A considerar si no tiene los términos de las páginas personalizadas traducidos para todos los idiomas, por ejemplo.";
 $LearningPathShowReducedReportTitle = "Lecciones: mostrar reporte reducido";
@@ -7524,4 +7525,7 @@ $ResetPasswordTokenLimitTitle = "Clave de reinicio de contraseña: límite de ti
 $ResetPasswordTokenLimitComment = "El número de segundos antes de que la llave generada se venza automáticamente y no pueda ser usada por nadie. En este caso, una nueva llave tiene que ser generada.";
 $ViewMyCoursesListBySessionTitle = "Ver las sesiones por curso";
 $ViewMyCoursesListBySessionComment = "Activa una página \"Mis cursos\" adicional en la cual las sesiones aparecen como partes del curso, en vez de lo contrario.";
+$DownloadCertificatePdf = "Descargar certificado en PDF";
+$EnterPassword = "Ingresar contraseña";
+$DownloadReportPdf = "Descargar reporte en PDF";
 ?>

+ 8 - 1
main/newscorm/learnpath.class.php

@@ -5555,7 +5555,14 @@ class learnpath
             //Link for the documents
             if ($arrLP[$i]['item_type'] == 'document') {
                 $url = api_get_self() . '?'.api_get_cidreq().'&action=view_item&mode=preview_document&id=' . $arrLP[$i]['id'] . '&lp_id=' . $this->lp_id;
-                $title_cut = Display::url($title_cut, $url, array('class' => 'ajax'));
+                $title_cut = Display::url(
+                    $title_cut,
+                    $url,
+                    array(
+                        'class' => 'ajax',
+                        'data-title' => $title_cut
+                    )
+                );
             }
 
             if (($i % 2) == 0) {

+ 24 - 4
main/session/index.php

@@ -11,6 +11,11 @@ use ChamiloSession as Session;
 $cidReset = true;
 
 require_once '../inc/global.inc.php';
+
+if (empty($_GET['session_id'])) {
+    api_not_allowed();
+}
+
 $session_id = isset($_GET['session_id']) ? intval($_GET['session_id']): null;
 
 $sessionField = new ExtraFieldValue('session');
@@ -26,10 +31,6 @@ if (!$allowVisitors) {
 $this_section = SECTION_COURSES;
 $htmlHeadXtra[] = api_get_jqgrid_js();
 
-if (empty($_GET['session_id'])) {
-    api_not_allowed();
-}
-
 $course_id  = isset($_GET['course_id'])  ? intval($_GET['course_id']) : null;
 
 $_SESSION['id_session'] = $session_id;
@@ -235,6 +236,25 @@ if (!api_is_allowed_to_session_edit()) {
 	api_not_allowed();
 }
 
+$entityManager = Database::getManager();
+$session = $entityManager->find('ChamiloCoreBundle:Session', $session_id);
+
+if (!empty($session)) {
+    $sessionCourses = $session->getCourses();
+
+    if (count($sessionCourses) === 1) {
+        $sessionCourse = $sessionCourses[0]->getCourse();
+
+        $courseUrl = $sessionCourse->getDirectory() . '/index.php?';
+        $courseUrl .= http_build_query([
+            'session_id' => $session->getId()
+        ]);
+
+        header('Location: ' . api_get_path(WEB_COURSE_PATH) . $courseUrl);
+        exit;
+    }
+}
+
 Display::display_header(get_lang('Session'));
 
 $session_select = array();

+ 28 - 2
main/session/session_import.php

@@ -552,8 +552,34 @@ if (!empty($error_message)) {
 $form = new FormValidator('import_sessions', 'post', api_get_self(), null, array('enctype' => 'multipart/form-data'));
 $form->addElement('hidden', 'formSent', 1);
 $form->addElement('file', 'import_file', get_lang('ImportFileLocation'));
-$form->addElement('radio', 'file_type', array(get_lang('FileType'), '<a href="example_session.csv" target="_blank">'.get_lang('ExampleCSVFile').'</a>'), 'CSV', 'csv');
-$form->addElement('radio', 'file_type', array(null, '<a href="example_session.xml" target="_blank">'.get_lang('ExampleXMLFile').'</a>'), 'XML', 'xml');
+$form->addElement(
+    'radio',
+    'file_type',
+    [
+        get_lang('FileType'),
+        Display::url(
+            get_lang('ExampleCSVFile'),
+            api_get_path(WEB_CODE_PATH) . 'admin/example_session.csv',
+            ['target' => '_blank']
+        )
+    ],
+    'CSV',
+    'csv'
+);
+$form->addElement(
+    'radio',
+    'file_type',
+    [
+        null,
+        Display::url(
+            get_lang('ExampleXMLFile'),
+            api_get_path(WEB_CODE_PATH) . 'admin/example_session.xml',
+            ['target' => '_blank']
+        )
+    ],
+    'XML',
+    'xml'
+);
 
 $form->addElement('checkbox', 'overwrite', null, get_lang('IfSessionExistsUpdate'));
 $form->addElement('checkbox', 'delete_users_not_in_list', null, get_lang('DeleteUsersNotInList'));

+ 34 - 4
main/social/group_view.php

@@ -181,11 +181,41 @@ if ($is_group_member || $group_info['visibility'] == GROUP_PERMISSION_OPEN) {
     $content = MessageManager::display_messages_for_group($group_id);
     if ($is_group_member) {
         if (empty($content)) {
-            $create_thread_link =  '<a href="'.api_get_path(WEB_CODE_PATH).'social/message_for_group_form.inc.php?view_panel=1&height=400&width=800&&user_friend='.api_get_user_id().'&group_id='.$group_id.'&action=add_message_group" class="ajax btn btn-default" title="'.get_lang('ComposeMessage').'">'.
-                get_lang('YouShouldCreateATopic').'</a></li>';
+            $createThreadUrl = api_get_path(WEB_CODE_PATH)
+                . 'social/message_for_group_form.inc.php?'
+                . http_build_query([
+                    'view_panel' => 1,
+                    'user_friend' => api_get_user_id(),
+                    'group_id' => $group_id,
+                    'action' => 'add_message_group'
+                ]);
+            $create_thread_link = Display::url(
+                get_lang('YouShouldCreateATopic'),
+                $createThreadUrl,
+                [
+                    'class' => 'ajax btn btn-default',
+                    'title' => get_lang('ComposeMessage'),
+                    'data-title' => get_lang('ComposeMessage')
+                ]
+            );
         } else {
-            $create_thread_link = '<a href="'.api_get_path(WEB_CODE_PATH).'social/message_for_group_form.inc.php?view_panel=1&height=400&width=610&&user_friend='.api_get_user_id().'&group_id='.$group_id.'&action=add_message_group" class="ajax btn btn-default" title="'.get_lang('ComposeMessage').'">'.
-                get_lang('NewTopic').'</a>';
+            $createThreadUrl = api_get_path(WEB_CODE_PATH)
+                . 'social/message_for_group_form.inc.php?'
+                . http_build_query([
+                    'view_panel' => 1,
+                    'user_friend' => api_get_user_id(),
+                    'group_id' => $group_id,
+                    'action' => add_message_group,
+                ]);
+            $create_thread_link = Display::url(
+                get_lang('NewTopic'),
+                $createThreadUrl,
+                [
+                    'class' => 'ajax btn btn-default',
+                    'title' => get_lang('ComposeMessage'),
+                    'data-title' => get_lang('ComposeMessage')
+                ]
+            );
         }
     }
     $members = $usergroup->get_users_by_group($group_id, true);

+ 0 - 1
main/template/default/auth/confirm_session_subscription.tpl

@@ -1,4 +1,3 @@
-<p class="text-center lead">{{ 'AreYouSureToSubscribe'|get_lang }}</p>
 <div class="row">
     <div class="col-sm-3 col-sm-offset-3">
         <a href="{{ _p.web_main }}auth/courses.php?{{ {'action':'subscribe_to_session', 'session_id':session_id, 'confirm':'1'}|url_encode() }}" class="btn btn-success btn-block">{{ 'Yes'|get_lang }}</a>

+ 2 - 2
main/template/default/auth/courses_list.php

@@ -124,7 +124,7 @@ if (!empty($user_course_categories)) {
                         if (api_get_setting('show_courses_descriptions_in_catalog') == 'true') {
                             $icon_title = get_lang('CourseDetails') . ' - ' . $course['title'];
                     ?>
-                    <a href="<?php echo api_get_path(WEB_CODE_PATH); ?>inc/ajax/course_home.ajax.php?a=show_course_information&code=<?php echo $course['code'] ?>" title="<?php echo $icon_title ?>" class="ajax">
+                    <a href="<?php echo api_get_path(WEB_CODE_PATH); ?>inc/ajax/course_home.ajax.php?a=show_course_information&code=<?php echo $course['code'] ?>" data-title="<?php echo $icon_title ?>" title="<?php echo $icon_title ?>" class="ajax">
                         <?php echo Display::return_icon('info.png', $icon_title,'','22') ?>
                        <?php } ?>
                     </a>
@@ -223,7 +223,7 @@ if (!empty($courses_without_category)) {
             if (api_get_setting('show_courses_descriptions_in_catalog') == 'true') {
             $icon_title = get_lang('CourseDetails') . ' - ' . $course['title'];
             ?>
-            <a href="<?php echo api_get_path(WEB_CODE_PATH); ?>inc/ajax/course_home.ajax.php?a=show_course_information&code=<?php echo $course['code'] ?>" title="<?php echo $icon_title ?>" class="ajax">
+            <a href="<?php echo api_get_path(WEB_CODE_PATH); ?>inc/ajax/course_home.ajax.php?a=show_course_information&code=<?php echo $course['code'] ?>" data-title="<?php echo $icon_title ?>" title="<?php echo $icon_title ?>" class="ajax">
                 <?php echo Display::return_icon('info.png', $icon_title, '','22'); ?>
             </a>
             <?php } ?>

+ 6 - 3
main/template/default/layout/head.tpl

@@ -334,12 +334,14 @@ $(function() {
         e.preventDefault();
 
         var contentUrl = this.href,
-            loadModalContent = $.get(contentUrl);
+            loadModalContent = $.get(contentUrl),
+            self = $(this);
 
         $.when(loadModalContent).done(function(modalContent) {
             var modalDialog = $('#global-modal').find('.modal-dialog'),
-                modalSize = get_url_params(contentUrl, 'modal_size'),
-                modalWidth = get_url_params(contentUrl, 'width');
+                modalSize = self.data('size') || get_url_params(contentUrl, 'modal_size'),
+                modalWidth = self.data('width') || get_url_params(contentUrl, 'width'),
+                modalTitle = self.data('title') || ' ';
 
             modalDialog.removeClass('modal-lg modal-sm').css('width', '');
 
@@ -356,6 +358,7 @@ $(function() {
                 modalDialog.css('width', modalWidth + 'px');
             }
 
+            $('#global-modal').find('.modal-title').text(modalTitle);
             $('#global-modal').find('.modal-body').html(modalContent);
 
             $('#global-modal').modal('show');

+ 1 - 1
main/template/default/user_portal/session.tpl

@@ -87,7 +87,7 @@
                                         {% for coach in item.coaches %}
                                             {{ loop.index > 1 ? ' | ' }}
 
-                                            <a href="{{ _p.web_ajax ~ 'user_manager.ajax.php?' ~ {'a': 'get_user_popup', 'user_id': coach.user_id}|url_encode() }}" class="ajax">
+                                            <a href="{{ _p.web_ajax ~ 'user_manager.ajax.php?' ~ {'a': 'get_user_popup', 'user_id': coach.user_id}|url_encode() }}" data-title="{{ coach.full_name }}" class="ajax">
                                                 {{ coach.full_name }}
                                             </a>
                                         {% endfor %}

+ 5 - 4
main/webservices/registration.soap.php

@@ -1797,7 +1797,7 @@ function WSEditUserWithPicture($params)
     $official_code = '';
     $phone = $params['phone'];
     $picture_url = $params['picture_url'];
-    $picture_uri = '';
+    $pictureUri = '';
 
     $active = 1;
     $creator_id = null;
@@ -1825,7 +1825,7 @@ function WSEditUserWithPicture($params)
     // Make sure the file download was OK by checking the HTTP headers for OK
     if (strpos(get_headers($picture_url)[0], "OK")) {
         file_put_contents($tempDir . $filename, file_get_contents($picture_url));
-        $picture_uri = UserManager::update_user_picture($user_id, $filename, $tempDir . $filename);
+        $pictureUri = UserManager::update_user_picture($user_id, $filename, $tempDir . $filename);
     }
 
     if ($user_id == 0) {
@@ -1878,7 +1878,7 @@ function WSEditUserWithPicture($params)
     $is_admin = Database::num_rows($resadmin);
 
     if (empty($status)) {
-        $status = 5;
+        $status = $user->getStatus();
     }
 
     if ($is_admin) {
@@ -1896,7 +1896,8 @@ function WSEditUserWithPicture($params)
         ->setPhone($phone)
         ->setExpirationDate($expiration_date)
         ->setHrDeptId($hr_dept_id)
-        ->setActive(true);
+        ->setActive(true)
+        ->setPictureUri($pictureUri);;
 
     if (!is_null($creator_id)) {
         $user->setCreatorId($creator_id);

+ 9 - 9
main/work/work.lib.php

@@ -3714,7 +3714,7 @@ function processWorkForm($workInfo, $values, $courseInfo, $sessionId, $groupId,
  *       'allow_text_assignment' => 0/1/2,
  * @todo Rename createAssignment or createWork, or something like that
  */
-function addDir($params, $user_id, $courseInfo, $group_id, $session_id)
+function addDir($formValues, $user_id, $courseInfo, $group_id, $session_id)
 {
     $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
 
@@ -3725,7 +3725,7 @@ function addDir($params, $user_id, $courseInfo, $group_id, $session_id)
     $base_work_dir = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/work';
     $course_id = $courseInfo['real_id'];
 
-    $directory = api_replace_dangerous_char($params['new_dir']);
+    $directory = api_replace_dangerous_char($formValues['new_dir']);
     $directory = disable_dangerous_file($directory);
     $created_dir = create_unexisting_work_directory($base_work_dir, $directory);
 
@@ -3736,20 +3736,20 @@ function addDir($params, $user_id, $courseInfo, $group_id, $session_id)
         $params = [
             'c_id' => $course_id,
             'url' => $dirName,
-            'title' => $params['new_dir'],
-            'description' => $params['description'],
+            'title' => $formValues['new_dir'],
+            'description' => $formValues['description'],
             'author' => '',
             'active' => '1',
             'accepted' => '1',
             'filetype' => 'folder',
             'post_group_id' => $group_id,
             'sent_date' => $today,
-            'qualification' => $params['qualification'] != '' ? $params['qualification'] : '',
+            'qualification' => $formValues['qualification'] != '' ? $formValues['qualification'] : '',
             'parent_id' => '',
             'qualificator_id' => '',
-            'weight' => $params['weight'],
+            'weight' => $formValues['weight'],
             'session_id' => $session_id,
-            'allow_text_assignment' => $params['allow_text_assignment'],
+            'allow_text_assignment' => $formValues['allow_text_assignment'],
             'contains_file' => 0,
             'user_id' => $user_id,
         ];
@@ -3770,7 +3770,7 @@ function addDir($params, $user_id, $courseInfo, $group_id, $session_id)
                 $group_id
             );
 
-            updatePublicationAssignment($id, $params, $courseInfo, $group_id);
+            updatePublicationAssignment($id, $formValues, $courseInfo, $group_id);
 
             if (api_get_course_setting('email_alert_students_on_new_homework') == 1) {
                 send_email_on_homework_creation(api_get_course_id());
@@ -3974,7 +3974,7 @@ function updatePublicationAssignment($workId, $params, $courseInfo, $groupId)
                     $courseInfo['code'],
                     LINK_STUDENTPUBLICATION,
                     $workId,
-                    $params['dir_name'],
+                    $params['new_dir'],
                     (float)$params['weight'],
                     (float)$params['qualification'],
                     $params['description'],

+ 1 - 1
plugin/advanced_subscription/src/admin_view.php

@@ -69,7 +69,7 @@ if (!empty($sessionId)) {
         $data['studentUserId'] = $studentId;
 
         $fieldValue = new ExtraFieldValue('user');
-        $areaField = $foo->get_values_by_handler_and_field_variable($studentId, 'area', true);
+        $areaField = $fieldValue->get_values_by_handler_and_field_variable($studentId, 'area', true);
 
         $student['area'] = $areaField['value'];
         $student['userLink'] = api_get_path(WEB_CODE_PATH).'social/profile.php?u='.$studentId;

+ 10 - 0
plugin/advanced_subscription/views/admin_view.tpl

@@ -26,6 +26,10 @@
             <p class="separate-badge">
                 <span class="badge badge-recom">{{ session.recommended_number_of_participants }}</span>
                 {{ "RecommendedNumberOfParticipants" | get_plugin_lang('AdvancedSubscriptionPlugin') }}</p>
+            <p class="separate-badge">
+                <span class="badge badge-info">{{ session.nbr_users }}</span>
+                {{ 'UsersNumber'|get_lang }}
+            </p>
             <h4>{{ "PublicationEndDate" | get_plugin_lang('AdvancedSubscriptionPlugin') }}</h4> <p>{{ session.publication_end_date }}</p>
             <h4>{{ "Mode" | get_plugin_lang('AdvancedSubscriptionPlugin') }}</h4> <p>{{ session.mode }}</p>
         </div>
@@ -77,6 +81,12 @@
                             >
                                 {{ 'RejectInfinitive' | get_plugin_lang('AdvancedSubscriptionPlugin') }}
                             </a>
+                            {% else %}
+                                {% if student.status == approveAdmin%}
+                                    <span class="label label-success">{{ 'Accepted'|get_lang }}</span>
+                                {% elseif student.status == disapproveAdmin %}
+                                    <span class="label label-danger">{{ 'Rejected'|get_lang }}</span>
+                                {% endif %}
                             {% endif %}
                         </td>
                     </tr>

+ 3 - 0
plugin/advanced_subscription/views/css/style.css

@@ -20,6 +20,9 @@
     background-color:#88aa00 ;
     font-size: 20px;
 }
+.badge-info {
+    font-size: 20px;
+}
 .separate-badge{
     margin-bottom: 20px;
     margin-top: 20px;

+ 0 - 4
plugin/courselegal/lang/english.php

@@ -21,7 +21,3 @@ $strings['SendOnlyWarning'] = 'Send only notification';
 $strings['SendAgreementFile'] = 'Send notification and attach the agreement';
 $strings['NoSendWarning'] = 'Do not send notification';
 $strings['TheAgreementIsAttachedInThisEmail'] = 'A copy of the agreement document is attached to this email';
-
-
-
-

+ 19 - 2
plugin/courselegal/lang/spanish.php

@@ -1,6 +1,23 @@
 <?php
 
-$strings['plugin_title'] = "Course agreements";
-$strings['plugin_comment'] = "Course agreements";
+$strings['plugin_title'] = "Acuerdo de curso";
+$strings['plugin_comment'] = "Agrega un acuerdo a cada curso (funciona con cursos en sesiones de formación)";
 $strings['tool_enable'] = 'Activar la configuración del plugin en los cursos';
 $strings['tool_enable_help'] = 'Una vez activado, tendrá que configurar el plugin dentro de la página de configuración del curso, y luego desde la página principal del curso (un botón aparecerá solo al profesor)';
+
+$strings['CourseLegal'] = 'Acuerdo legal de curso';
+$strings['WebAgreement'] = 'Acuerdo por Web';
+$strings['MailAgreement'] = 'Acuerdo por correo electrónico';
+$strings['MailAgreementWasSentWithClickX'] = 'Haga clic en el siguiente enlace para confirmar que está de acuerdo con los términos y condiciones para acceder al curso %s: <br /> %s';
+$strings['AgreementUpdated'] = 'Acuerdo actualizado';
+$strings['AgreementWasUpdatedClickHere'] = 'El acuerdo fue actualizado. Haga clic aquí: %s';
+$strings['YouNeedToConfirmYourAgreementCheckYourEmail'] = 'Usted necesita confirmar que está de acuerdo. Revise su correo electrónico, por favor';
+$strings['DeleteFile'] = 'Eliminar archivo adjuntado';
+$strings['RemoveAllUserAgreements'] = 'Eliminar todos los acuerdos de usuarios anteriores';
+$strings['WarnAllUsersByEmail'] = 'Notificar a todos los usuarios por corro electrónico';
+$strings['WarnAllUsersByEmailAndSendAttachment'] = 'Notificar a todos los usuarios por correo electrónico y enviarles el acuerdo adjuntado';
+$strings['ReSendMailAgreementLink'] = 'Enviar un correo electrónico con el enlace al acuerdo de nuevo.';
+$strings['SendOnlyWarning'] = 'Enviar solamente notificación';
+$strings['SendAgreementFile'] = 'Enviar notificación y adjuntar el acuerdo';
+$strings['NoSendWarning'] = 'No enviar notificación';
+$strings['TheAgreementIsAttachedInThisEmail'] = 'Una copia de este documento de acuerdo es adjuntado a este correo electrónico.';

+ 7 - 1
plugin/courselegal/start.php

@@ -23,7 +23,13 @@ $form = new FormValidator('plugin', 'post', $url);
 $form->addElement('header', $legal->get_lang('CourseLegal'));
 $form->addElement('hidden', 'session_id', $sessionId);
 $form->addElement('hidden', 'c_id', $courseId);
-$form->addElement('textarea', 'content', get_lang('Text'));
+$form->addHtmlEditor(
+    'content',
+    get_lang('Text'),
+    true,
+    false,
+    ['ToolbarSet' => 'TermsAndConditions']
+);
 $form->addElement('file', 'uploaded_file', get_lang('File'));
 $file = $legal->getCurrentFile($courseId, $sessionId);
 

+ 1 - 1
src/Chamilo/CoreBundle/Component/Editor/Editor.php

@@ -241,6 +241,6 @@ class Editor
      */
     public function getLocale()
     {
-        return 'en';
+        return api_get_language_isocode();
     }
 }