Răsfoiți Sursa

Merge pull request #2539 from AngelFQC/1.11.x

Fix CKEditor styles when creating HTML documents or single blocks - refs BT#14381
Julio Montoya 6 ani în urmă
părinte
comite
ea39005ff9

+ 36 - 0
app/Resources/public/css/document.css

@@ -0,0 +1,36 @@
+/*
+Stylesheet for HTML documents created with CKEditor.
+
+This stylesheet must import editor_content.css file
+*/
+@import url(./editor_content.css);
+
+body {
+    color: #666;
+    font-family: 'Open Sans', sans-serif;
+    line-height: 30px;
+    padding: 1em;
+}
+
+blockquote {
+    background: #f9f9f9;
+    border-left: 8px solid #ccc;
+    display: inline-block;
+    font: 14px/20px italic Times, serif;
+    margin: 1.5em 10px;
+    padding: 0.5em 10px;
+    quotes: "\201C" "\201D" "\2018" "\2019";
+}
+
+blockquote:before {
+    color: #ccc;
+    content: open-quote;
+    font-size: 4em;
+    line-height: 0.1em;
+    margin-right: 0.25em;
+    vertical-align: -0.4em;
+}
+
+blockquote p {
+    display: inline;
+}

+ 2 - 0
app/Resources/public/css/editor.css

@@ -1,4 +1,6 @@
 /*
+    Deprecated stylesheet. Use document.css.
+
     Theme Name: Frame Scorm
     URI Project: http://www.chamilo.org
     Description: Styles main base of Chamilo LMS appearance, works with Bootstrap 3.0.x

+ 216 - 0
app/Resources/public/css/editor_content.css

@@ -0,0 +1,216 @@
+/*
+Stylesheet for HTML blocks created with CKEditor to embed in Chamilo pages.
+*/
+
+@font-face {
+    font-family: 'Open Sans';
+    font-style: normal;
+    font-weight: 300;
+    src: local('Open Sans Light'),
+         local('OpenSans-Light'),
+         url(themes/chamilo/fonts/OpenSans-Light.woff2) format('woff2'),
+         url(themes/chamilo/fonts/OpenSans-Light.woff) format('woff');
+}
+
+@font-face {
+    font-family: 'Open Sans';
+    font-style: normal;
+    font-weight: 400;
+    src: local('Open Sans'),
+         local('OpenSans'),
+         url(themes/chamilo/fonts/OpenSans.woff2) format('woff2'),
+         url(themes/chamilo/fonts/OpenSans.woff) format('woff');
+}
+
+@font-face {
+    font-family: 'Open Sans';
+    font-style: normal;
+    font-weight: 600;
+    src: local('Open Sans Semibold'),
+         local('OpenSans-Semibold'),
+         url(themes/chamilo/fonts/OpenSans-Semibold.woff2) format('woff2'),
+         url(themes/chamilo/fonts/OpenSans-Semibold.woff) format('woff');
+}
+
+@font-face {
+    font-family: 'Open Sans';
+    font-style: normal;
+    font-weight: 700;
+    src: local('Open Sans Bold'),
+         local('OpenSans-Bold'),
+         url(themes/chamilo/fonts/OpenSans-Bold.woff2) format('woff2'),
+         url(themes/chamilo/fonts/OpenSans-Bold.woff) format('woff');
+}
+
+body {
+    font-family: 'Open Sans', sans-serif;
+}
+
+/* Hack for show Bootstrap alerts in CKEditor' style select */
+.cke_panel_listItem a > :first-child {
+    margin-bottom: 0;
+}
+
+.ck {
+    display: block;
+    font-feature-settings: normal;
+    font-kerning: auto;
+    font-language-override: normal;
+    font-size-adjust: none;
+    font-stretch: normal;
+    font-style: normal;
+    font-synthesis: weight style;
+    font-variant: normal;
+    font-weight: normal;
+    line-height: 1;
+}
+
+.ck-article {
+    color: #E95839;
+    background: url(../../main/img/document/border-title.png) repeat-x 0 80%;
+    font-weight: bold;
+    margin-bottom: 10px;
+    padding-bottom: 2%;
+    text-transform: uppercase;
+}
+
+.ck-article:before {
+    content: "\f15c";
+    font-family: FontAwesome;
+    font-weight: normal;
+    margin-right: 5px;
+}
+
+.ck-paragraph-box {
+    background-color: #F5EEE2;
+    line-height: 20px;
+    padding: 2% 3%;
+}
+
+.ck-title {
+    color: #000;
+    display: block;
+    font-weight: bold;
+}
+
+.ck-title2 {
+    color: #000;
+    font-weight: 500;
+    margin-top: 0;
+    padding-top: 0;
+    position: relative;
+}
+
+.ck-title2:after {
+    background-color: #E95839;
+    content: "";
+    display: block;
+    height: 2px;
+    margin: 10px 0 0;
+    width: 50px;
+}
+
+.ck-stand-out {
+    background-color: yellow;
+}
+
+.ck-style1 {
+    background: url(../../main/img/document/hr-1.png) repeat-x 0 0;
+    border: 0;
+    height: 6px;
+}
+
+.ck-style2 {
+    background: url(../../main/img/document/hr-2.png) repeat-x 0 0;
+    border: 0;
+    height: 6px;
+}
+
+.ck-style3 {
+    border-top: 1px dashed #8c8b8b;
+}
+
+.ck-style3:after {
+    background: #FFF;
+    color: #8c8b8b;
+    content: '\002702';
+    display: inline-block;
+    font-size: 18px;
+    left: 40px;
+    padding: 0 3px;
+    position: relative;
+    top: -12px;
+}
+
+.img-va-baseline {
+    vertical-align: baseline;
+}
+
+.img-va-top {
+    vertical-align: top;
+}
+
+.img-va-bottom {
+    vertical-align: bottom;
+}
+
+.img-va-middle {
+    vertical-align: middle;
+}
+
+.img-va-super {
+    vertical-align: super;
+}
+
+.img-va-sub {
+    vertical-align: sub;
+}
+
+.img-va-text-top {
+    vertical-align: text-top;
+}
+
+.img-va-text-bottom {
+    vertical-align: text-bottom;
+}
+
+figure.image {
+    border: 1px solid #ddd;
+    border-radius: 5px;
+    display: inline-block;
+    margin-bottom: 1em;
+    padding: 5px;
+}
+
+.cke_widget_image.pull-right,
+img.pull-right,
+figure.image.pull-right {
+    margin-left: 1em;
+}
+
+.cke_widget_image.pull-left,
+img.pull-left,
+figure.image.pull-left {
+    margin-right: 1em;
+}
+
+.text-center .img-responsive {
+    margin-left: auto;
+    margin-right: auto;
+}
+
+.cke_widget_image.pull-left figure.image,
+.cke_widget_image.pull-right figure.image,
+figure.image.pull-left,
+figure.image.pull-right {
+    display: block;
+}
+
+figure.image figcaption {
+    background-color: #f3f3f3;
+    border-radius: 0;
+    margin: 0;
+    padding-left: 5px;
+    padding-top: 0;
+    text-align: left;
+}

+ 2 - 2
main/document/document.php

@@ -744,8 +744,8 @@ if (isset($_GET['curdirpath']) && $_GET['curdirpath'] == '/certificates' &&
 
         // Remove media=screen to be available when printing a document
         $new_content_html = str_replace(
-            api_get_path(WEB_CSS_PATH).'editor.css" media="screen"',
-            api_get_path(WEB_CSS_PATH).'editor.css" ',
+            ' media="screen"',
+            '',
             $new_content_html
         );
 

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

@@ -645,8 +645,8 @@ class Certificate extends Model
 
             // Remove media=screen to be available when printing a document
             $certificateContent = str_replace(
-                api_get_path(WEB_CSS_PATH).'editor.css" media="screen"',
-                api_get_path(WEB_CSS_PATH).'editor.css" ',
+                ' media="screen"',
+                '',
                 $certificateContent
             );
 

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

@@ -1004,7 +1004,7 @@ EOT;
         $config['style'] = false;
         if ($fullPage) {
             $config['fullPage'] = true;
-            // Adds editor.css in ckEditor
+            // Adds editor_content.css in ckEditor
             $config['style'] = true;
         }
 

+ 14 - 1
main/inc/lib/javascript/ckeditor/config_js.php

@@ -1,6 +1,8 @@
 <?php
 /* For licensing terms, see /license.txt */
 
+use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
+
 require_once __DIR__.'/../../../global.inc.php';
 
 $moreButtonsInMaximizedMode = false;
@@ -9,7 +11,18 @@ if (api_get_setting('more_buttons_maximized_mode') === 'true') {
 }
 
 $template = new Template();
-$template->setStyleMenuInCkEditor();
+$template->assign(
+    'bootstrap_css',
+    api_get_path(WEB_PUBLIC_PATH).'assets/bootstrap/dist/css/bootstrap.min.css'
+);
+$template->assign(
+    'font_awesome_css',
+    api_get_path(WEB_PUBLIC_PATH).'assets/fontawesome/css/font-awesome.min.css'
+);
+$template->assign(
+    'css_editor',
+    ChamiloApi::getEditorBlockStylePath()
+);
 $template->assign('moreButtonsInMaximizedMode', $moreButtonsInMaximizedMode);
 $courseId = api_get_course_int_id();
 $courseCondition = '';

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

@@ -644,21 +644,6 @@ class Template
         $this->assign('video_features', $defaultFeatures);
     }
 
-    /**
-     * Sets the "styles" menu in ckEditor.
-     *
-     * Reads css/themes/xxx/editor.css if exists and shows it in the menu, otherwise it
-     * will take the default web/editor.css file
-     */
-    public function setStyleMenuInCkEditor()
-    {
-        $cssEditor = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'editor.css');
-        if (is_file(api_get_path(SYS_CSS_PATH).$this->themeDir.'editor.css')) {
-            $cssEditor = api_get_path(WEB_CSS_PATH).$this->themeDir.'editor.css';
-        }
-        $this->assign('css_editor', $cssEditor);
-    }
-
     /**
      * Prepare custom CSS to be added at the very end of the <head> section.
      *
@@ -678,6 +663,7 @@ class Template
         }
 
         $css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).$this->themeDir.'default.css');
+        $css[] = api_get_cdn_path(ChamiloApi::getEditorBlockStylePath());
 
         $css_file_to_string = null;
         foreach ($css as $file) {

+ 269 - 258
main/mySpace/myStudents.php

@@ -23,7 +23,8 @@ $courseInfo = api_get_course_info($course_code);
 $student_id = isset($_GET['student']) ? (int) $_GET['student'] : 0;
 $coachId = isset($_GET['id_coach']) ? (int) $_GET['id_coach'] : 0;
 $details = isset($_GET['details']) ? Security::remove_XSS($_GET['details']) : '';
-$currentUrl = api_get_self().'?student='.$student_id.'&course='.$course_code.'&id_session='.$sessionId.'&origin='.$origin.'&details='.$details;
+$currentUrl = api_get_self().'?student='.$student_id.'&course='.$course_code.'&id_session='.$sessionId
+    .'&origin='.$origin.'&details='.$details;
 $allowMessages = api_get_configuration_value('private_messages_about_user');
 
 if (empty($student_id)) {
@@ -325,10 +326,9 @@ switch ($action) {
 
             // @todo delete the stats.track_e_exercises records.
             // First implement this http://support.chamilo.org/issues/1334
-            Display::addFlash(Display::return_message(
-                get_lang('LPWasReset'),
-                'success'
-            ));
+            Display::addFlash(
+                Display::return_message(get_lang('LPWasReset'), 'success')
+            );
             Security::clear_token();
         }
         break;
@@ -368,7 +368,7 @@ if (api_is_session_admin() || api_is_drh()) {
 if (!empty($sessions_coached_by_user)) {
     foreach ($sessions_coached_by_user as $session_coached_by_user) {
         $sid = intval($session_coached_by_user['id']);
-        $courses_followed_by_coach = Tracking :: get_courses_followed_by_coach(api_get_user_id(), $sid);
+        $courses_followed_by_coach = Tracking::get_courses_followed_by_coach(api_get_user_id(), $sid);
         $courses_in_session_by_coach[$sid] = $courses_followed_by_coach;
     }
 }
@@ -445,17 +445,17 @@ $token = Security::get_token();
 
 // Actions bar
 echo '<div class="actions">';
-echo '<a href="javascript: window.history.go(-1);">'.
-        Display::return_icon('back.png', get_lang('Back'), '', ICON_SIZE_MEDIUM).'</a>';
+echo '<a href="javascript: window.history.go(-1);">'
+    .Display::return_icon('back.png', get_lang('Back'), '', ICON_SIZE_MEDIUM).'</a>';
 
-echo '<a href="javascript: void(0);" onclick="javascript: window.print();">'.
-        Display::return_icon('printer.png', get_lang('Print'), '', ICON_SIZE_MEDIUM).'</a>';
+echo '<a href="javascript: void(0);" onclick="javascript: window.print();">'
+    .Display::return_icon('printer.png', get_lang('Print'), '', ICON_SIZE_MEDIUM).'</a>';
 
-echo '<a href="'.api_get_self().'?'.Security::remove_XSS($_SERVER['QUERY_STRING']).'&export=csv">'.
-        Display::return_icon('export_csv.png', get_lang('ExportAsCSV'), '', ICON_SIZE_MEDIUM).'</a> ';
+echo '<a href="'.api_get_self().'?'.Security::remove_XSS($_SERVER['QUERY_STRING']).'&export=csv">'
+    .Display::return_icon('export_csv.png', get_lang('ExportAsCSV'), '', ICON_SIZE_MEDIUM).'</a> ';
 
-echo '<a href="'.api_get_self().'?'.Security::remove_XSS($_SERVER['QUERY_STRING']).'&export=xls">'.
-Display::return_icon('export_excel.png', get_lang('ExportAsXLS'), '', ICON_SIZE_MEDIUM).'</a> ';
+echo '<a href="'.api_get_self().'?'.Security::remove_XSS($_SERVER['QUERY_STRING']).'&export=xls">'
+    .Display::return_icon('export_excel.png', get_lang('ExportAsXLS'), '', ICON_SIZE_MEDIUM).'</a> ';
 
 if (!empty($user_info['email'])) {
     $send_mail = '<a href="mailto:'.$user_info['email'].'">'.
@@ -466,23 +466,25 @@ if (!empty($user_info['email'])) {
 echo $send_mail;
 if (!empty($student_id) && !empty($course_code)) {
     // Only show link to connection details if course and student were defined in the URL
-    echo '<a href="access_details.php?student='.$student_id.'&course='.$course_code.'&origin='.$origin.'&cidReq='.$course_code.'&id_session='.$sessionId.'">'.
-        Display::return_icon('statistics.png', get_lang('AccessDetails'), '', ICON_SIZE_MEDIUM).
-        '</a>';
+    echo '<a href="access_details.php?student='.$student_id.'&course='.$course_code.'&origin='.$origin.'&cidReq='
+        .$course_code.'&id_session='.$sessionId.'">'
+        .Display::return_icon('statistics.png', get_lang('AccessDetails'), '', ICON_SIZE_MEDIUM)
+        .'</a>';
 }
 
 $notebookTeacherEnable = api_get_plugin_setting('notebookteacher', 'enable_plugin_notebookteacher') === 'true';
 if ($notebookTeacherEnable && !empty($student_id) && !empty($course_code)) {
     // link notebookteacher
     $optionsLink = 'student_id='.$student_id.'&origin='.$origin.'&cidReq='.$course_code.'&id_session='.$sessionId;
-    echo '<a href="'.api_get_path(WEB_PLUGIN_PATH).'notebookteacher/src/index.php?'.$optionsLink.'">'.
-        Display::return_icon('notebookteacher.png', get_lang('Notebook'), '', ICON_SIZE_MEDIUM).
-    '</a>';
+    echo '<a href="'.api_get_path(WEB_PLUGIN_PATH).'notebookteacher/src/index.php?'.$optionsLink.'">'
+        .Display::return_icon('notebookteacher.png', get_lang('Notebook'), '', ICON_SIZE_MEDIUM)
+        .'</a>';
 }
 
 if (api_can_login_as($student_id)) {
-    echo '<a href="'.api_get_path(WEB_CODE_PATH).'admin/user_list.php?action=login_as&user_id='.$student_id.'&sec_token='.$token.'">'.
-        Display::return_icon('login_as.png', get_lang('LoginAs'), null, ICON_SIZE_MEDIUM).'</a>&nbsp;&nbsp;';
+    echo '<a href="'.api_get_path(WEB_CODE_PATH).'admin/user_list.php?action=login_as&user_id='.$student_id
+        .'&sec_token='.$token.'">'
+        .Display::return_icon('login_as.png', get_lang('LoginAs'), null, ICON_SIZE_MEDIUM).'</a>&nbsp;&nbsp;';
 }
 
 if (Skill::isAllowed($student_id, false)) {
@@ -607,12 +609,7 @@ $csv_content[] = [
 
 $coachs_name = '';
 $session_name = '';
-$table_title = Display::return_icon(
-    'user.png',
-    get_lang('User'),
-    [],
-    ICON_SIZE_SMALL
-).$user_info['complete_name'];
+$table_title = Display::return_icon('user.png', get_lang('User')).$user_info['complete_name'];
 
 echo Display::page_subheader($table_title);
 $userPicture = UserManager::getUserPicture($user_info['user_id'], USER_IMAGE_SIZE_BIG);
@@ -622,203 +619,207 @@ $userGroups = $userGroupManager->getNameListByUser(
     UserGroup::NORMAL_CLASS
 );
 ?>
-<div class="row">
-    <div class="col-sm-2">
-        <img src="<?php echo $userPicture; ?>" class="thumbnail img-responsive">
-    </div>
-    <div class="col-sm-5">
-        <table class="table table-striped table-hover">
-        <thead>
-            <tr>
-                <th colspan="2"><?php echo get_lang('Information'); ?></th>
-            </tr>
-        </thead>
-        <tbody>
-        <tr>
-            <td><?php echo get_lang('Name'); ?></td>
-            <td><?php echo $user_info['complete_name_with_message_link']; ?></td>
-        </tr>
-        <tr>
-            <td><?php echo get_lang('Email'); ?></td>
-            <td>
-                <?php
-                echo !empty($user_info['email'])
-                    ? '<a href="mailto:'.$user_info['email'].'">'.$user_info['email'].'</a>'
-                    : get_lang('NoEmail');
-                ?>
-            </td>
-        </tr>
-        <tr>
-            <td><?php echo get_lang('Tel'); ?></td>
-            <td><?php echo !empty($user_info['phone']) ? $user_info['phone'] : get_lang('NoTel'); ?></td>
-        </tr>
-        <tr>
-            <td><?php echo get_lang('OfficialCode'); ?></td>
-            <td><?php
-                echo !empty($user_info['official_code'])
-                    ? $user_info['official_code']
-                    : get_lang('NoOfficialCode');
-                ?></td>
-        </tr>
-        <tr>
-            <td><?php echo get_lang('OnLine'); ?></td>
-            <td><?php echo $online; ?></td>
-        </tr>
-        <?php
-        if (!empty($course_code)) {
-            ?>
-            <tr>
-                <td colspan="2">
+    <div class="row">
+        <div class="col-sm-2">
+            <img src="<?php echo $userPicture; ?>" class="thumbnail img-responsive">
+        </div>
+        <div class="col-sm-5">
+            <table class="table table-striped table-hover">
+                <thead>
+                <tr>
+                    <th colspan="2"><?php echo get_lang('Information'); ?></th>
+                </tr>
+                </thead>
+                <tbody>
+                <tr>
+                    <td><?php echo get_lang('Name'); ?></td>
+                    <td><?php echo $user_info['complete_name_with_message_link']; ?></td>
+                </tr>
+                <tr>
+                    <td><?php echo get_lang('Email'); ?></td>
+                    <td>
+                        <?php
+                        echo !empty($user_info['email'])
+                            ? '<a href="mailto:'.$user_info['email'].'">'.$user_info['email'].'</a>'
+                            : get_lang('NoEmail');
+                        ?>
+                    </td>
+                </tr>
+                <tr>
+                    <td><?php echo get_lang('Tel'); ?></td>
+                    <td><?php echo !empty($user_info['phone']) ? $user_info['phone'] : get_lang('NoTel'); ?></td>
+                </tr>
+                <tr>
+                    <td><?php echo get_lang('OfficialCode'); ?></td>
+                    <td><?php
+                        echo !empty($user_info['official_code'])
+                            ? $user_info['official_code']
+                            : get_lang('NoOfficialCode');
+                        ?></td>
+                </tr>
+                <tr>
+                    <td><?php echo get_lang('OnLine'); ?></td>
+                    <td><?php echo $online; ?></td>
+                </tr>
                 <?php
-                echo Display::url(
-                    get_lang('SeeAccesses'),
-                    'access_details.php?'.http_build_query([
-                        'student' => $student_id,
-                        'course' => $course_code,
-                        'origin' => $origin,
-                        'cidReq' => $course_code,
-                        'id_session' => $sessionId,
-                    ]),
-                    ['class' => 'btn btn-default']
-                ); ?>
-                </td>
-            </tr>
-        <?php
-        }
-        // Display timezone if the user selected one and if the admin allows the use of user's timezone
-        $timezone = null;
-        $timezone_user = UserManager::get_extra_user_data_by_field(
-            $user_info['user_id'],
-            'timezone'
-        );
-        $use_users_timezone = api_get_setting('use_users_timezone', 'timezones');
-        if ($timezone_user['timezone'] != null &&
-            $use_users_timezone == 'true'
-        ) {
-            $timezone = $timezone_user['timezone'];
-        }
-        if ($timezone !== null) {
-            ?>
-            <tr>
-                <td> <?php echo get_lang('Timezone').' : '.$timezone; ?> </td>
-            </tr>
-        <?php
-        }
-        ?>
-        </tbody>
-    </table>
-    </div>
-    <div class="col-sm-5">
-    <table class="table table-striped table-hover">
-        <thead>
-        <tr>
-            <th colspan="2" class="text-center"><?php echo get_lang('Tracking'); ?></th>
-        </tr>
-        </thead>
-        <tbody>
-        <tr><td align="right"><?php echo get_lang('FirstLoginInPlatform'); ?></td>
-            <td align="left"><?php echo $first_connection_date; ?></td>
-        </tr>
-        <tr>
-            <td align="right"><?php echo get_lang('LatestLoginInPlatform'); ?></td>
-            <td align="left"><?php echo $last_connection_date; ?></td>
-        </tr>
-        <?php
-        if ($details == 'true') {
-            ?>
-            <tr>
-                <td align="right"><?php echo get_lang('TimeSpentInTheCourse'); ?></td>
-                <td align="left"><?php echo $time_spent_on_the_course; ?></td>
-            </tr>
-            <tr>
-                <td align="right">
-                    <?php
-                    echo get_lang('Progress').' ';
-            Display:: display_icon(
-                        'info3.gif',
-                        get_lang('ScormAndLPProgressTotalAverage'),
-                        ['align' => 'absmiddle', 'hspace' => '3px']
-                    ); ?>
-                </td>
-                <td align="left"><?php echo $avg_student_progress.'%'; ?></td>
-             </tr>
-            <tr>
-                <td align="right">
+                if (!empty($course_code)) {
+                    ?>
+                    <tr>
+                        <td colspan="2">
+                            <?php
+                            echo Display::url(
+                                get_lang('SeeAccesses'),
+                                'access_details.php?'
+                                    .http_build_query(
+                                        [
+                                            'student' => $student_id,
+                                            'course' => $course_code,
+                                            'origin' => $origin,
+                                            'cidReq' => $course_code,
+                                            'id_session' => $sessionId,
+                                        ]
+                                    ),
+                                ['class' => 'btn btn-default']
+                            ); ?>
+                        </td>
+                    </tr>
                     <?php
-                    echo get_lang('Score').' ';
-            Display:: display_icon(
-                        'info3.gif',
-                        get_lang('ScormAndLPTestTotalAverage'),
-                        ['align' => 'absmiddle', 'hspace' => '3px']
-                    ); ?>
-                </td>
-                <td align="left">
-                <?php
-                if (is_numeric($avg_student_score)) {
-                    echo $avg_student_score.'%';
-                } else {
-                    echo $avg_student_score;
-                } ?>
-                </td>
-            </tr>
-        <?php
-        }
-
-        if (api_get_setting('allow_terms_conditions') === 'true') {
-            $isBoss = UserManager::userIsBossOfStudent(api_get_user_id(), $student_id);
-            if ($isBoss || api_is_platform_admin()) {
-                $extraFieldValue = new ExtraFieldValue('user');
-                $value = $extraFieldValue->get_values_by_handler_and_field_variable(
-                    $student_id,
-                    'legal_accept'
+                }
+                // Display timezone if the user selected one and if the admin allows the use of user's timezone
+                $timezone = null;
+                $timezone_user = UserManager::get_extra_user_data_by_field(
+                    $user_info['user_id'],
+                    'timezone'
                 );
-                $icon = Display::return_icon('accept_na.png');
-                if (isset($value['value']) && !empty($value['value'])) {
-                    list($legalId, $legalLanguageId, $legalTime) = explode(':', $value['value']);
-                    $icon = Display::return_icon('accept.png').' '.api_get_local_time($legalTime);
-                    $icon .= ' '.Display::url(
-                        get_lang('DeleteLegal'),
-                        api_get_self().'?action=delete_legal&student='.$student_id.'&course='.$course_code,
-                        ['class' => 'btn btn-danger btn-xs']
-                    );
-                } else {
-                    $icon .= ' '.Display::url(
-                        get_lang('SendLegal'),
-                        api_get_self().'?action=send_legal&student='.$student_id.'&course='.$course_code,
-                        ['class' => 'btn btn-primary btn-xs']
-                    );
+                $use_users_timezone = api_get_setting('use_users_timezone', 'timezones');
+                if ($timezone_user['timezone'] != null &&
+                    $use_users_timezone == 'true'
+                ) {
+                    $timezone = $timezone_user['timezone'];
                 }
-                echo '<tr>
-                    <td align="right">';
-                echo get_lang('LegalAccepted').' </td>  <td align="left">'.$icon;
-                echo '</td></tr>';
-            }
-        }
-        ?>
-        </tbody>
-    </table>
-    <?php if (!empty($userGroups)) {
-            ?>
-        <table class="table table-striped table-hover">
-            <thead>
+                if ($timezone !== null) {
+                    ?>
+                    <tr>
+                        <td> <?php echo get_lang('Timezone').' : '.$timezone; ?> </td>
+                    </tr>
+                    <?php
+                }
+                ?>
+                </tbody>
+            </table>
+        </div>
+        <div class="col-sm-5">
+            <table class="table table-striped table-hover">
+                <thead>
                 <tr>
-                    <th><?php echo get_lang('Classes'); ?></th>
+                    <th colspan="2" class="text-center"><?php echo get_lang('Tracking'); ?></th>
+                </tr>
+                </thead>
+                <tbody>
+                <tr>
+                    <td align="right"><?php echo get_lang('FirstLoginInPlatform'); ?></td>
+                    <td align="left"><?php echo $first_connection_date; ?></td>
                 </tr>
-            </thead>
-            <tbody>
-                <?php foreach ($userGroups as $class) {
-                ?>
                 <tr>
-                    <td><?php echo $class; ?></td>
+                    <td align="right"><?php echo get_lang('LatestLoginInPlatform'); ?></td>
+                    <td align="left"><?php echo $last_connection_date; ?></td>
                 </tr>
                 <?php
+                if ($details == 'true') {
+                    ?>
+                    <tr>
+                        <td align="right"><?php echo get_lang('TimeSpentInTheCourse'); ?></td>
+                        <td align="left"><?php echo $time_spent_on_the_course; ?></td>
+                    </tr>
+                    <tr>
+                        <td align="right">
+                            <?php
+                            echo get_lang('Progress').' ';
+                            Display::display_icon(
+                                'info3.gif',
+                                get_lang('ScormAndLPProgressTotalAverage'),
+                                ['align' => 'absmiddle', 'hspace' => '3px']
+                            ); ?>
+                        </td>
+                        <td align="left"><?php echo $avg_student_progress.'%'; ?></td>
+                    </tr>
+                    <tr>
+                        <td align="right">
+                            <?php
+                            echo get_lang('Score').' ';
+                            Display::display_icon(
+                                'info3.gif',
+                                get_lang('ScormAndLPTestTotalAverage'),
+                                ['align' => 'absmiddle', 'hspace' => '3px']
+                            ); ?>
+                        </td>
+                        <td align="left">
+                            <?php
+                            if (is_numeric($avg_student_score)) {
+                                echo $avg_student_score.'%';
+                            } else {
+                                echo $avg_student_score;
+                            } ?>
+                        </td>
+                    </tr>
+                    <?php
+                }
+
+                if (api_get_setting('allow_terms_conditions') === 'true') {
+                    $isBoss = UserManager::userIsBossOfStudent(api_get_user_id(), $student_id);
+                    if ($isBoss || api_is_platform_admin()) {
+                        $extraFieldValue = new ExtraFieldValue('user');
+                        $value = $extraFieldValue->get_values_by_handler_and_field_variable(
+                            $student_id,
+                            'legal_accept'
+                        );
+                        $icon = Display::return_icon('accept_na.png');
+                        if (isset($value['value']) && !empty($value['value'])) {
+                            list($legalId, $legalLanguageId, $legalTime) = explode(':', $value['value']);
+                            $icon = Display::return_icon('accept.png').' '.api_get_local_time($legalTime);
+                            $icon .= ' '.Display::url(
+                                    get_lang('DeleteLegal'),
+                                    api_get_self().'?action=delete_legal&student='.$student_id.'&course='.$course_code,
+                                    ['class' => 'btn btn-danger btn-xs']
+                                );
+                        } else {
+                            $icon .= ' '.Display::url(
+                                    get_lang('SendLegal'),
+                                    api_get_self().'?action=send_legal&student='.$student_id.'&course='.$course_code,
+                                    ['class' => 'btn btn-primary btn-xs']
+                                );
+                        }
+                        echo '<tr>
+                    <td align="right">';
+                        echo get_lang('LegalAccepted').' </td>  <td align="left">'.$icon;
+                        echo '</td></tr>';
+                    }
+                }
+                ?>
+                </tbody>
+            </table>
+            <?php if (!empty($userGroups)) {
+                ?>
+                <table class="table table-striped table-hover">
+                    <thead>
+                    <tr>
+                        <th><?php echo get_lang('Classes'); ?></th>
+                    </tr>
+                    </thead>
+                    <tbody>
+                    <?php foreach ($userGroups as $class) {
+                        ?>
+                        <tr>
+                            <td><?php echo $class; ?></td>
+                        </tr>
+                        <?php
+                    } ?>
+                    </tbody>
+                </table>
+                <?php
             } ?>
-            </tbody>
-        </table>
-    <?php
-        } ?>
+        </div>
     </div>
-</div>
 <?php
 
 $exportCourseList = [];
@@ -841,12 +842,7 @@ if (empty($details)) {
         $access_start_date = '';
         $access_end_date = '';
         $date_session = '';
-        $title = Display::return_icon(
-            'course.png',
-            get_lang('Courses'),
-            [],
-            ICON_SIZE_SMALL
-        ).' '.get_lang('Courses');
+        $title = Display::return_icon('course.png', get_lang('Courses')).' '.get_lang('Courses');
 
         $session_info = api_get_session_info($sId);
         if ($session_info) {
@@ -862,12 +858,8 @@ if (empty($details)) {
             if (!empty($access_start_date) && !empty($access_end_date)) {
                 $date_session = get_lang('From').' '.$access_start_date.' '.get_lang('Until').' '.$access_end_date;
             }
-            $title = Display::return_icon(
-                'session.png',
-                get_lang('Session'),
-                [],
-                ICON_SIZE_SMALL
-            ).' '.$session_name.($date_session ? ' ('.$date_session.')' : '');
+            $title = Display::return_icon('session.png', get_lang('Session'))
+                .' '.$session_name.($date_session ? ' ('.$date_session.')' : '');
         }
 
         // Courses
@@ -938,15 +930,15 @@ if (empty($details)) {
                     $attendances_faults_avg = '0/0 (0%)';
                     if (!empty($results_faults_avg['total'])) {
                         if (api_is_drh()) {
-                            $attendances_faults_avg =
-                                '<a title="'.get_lang('GoAttendance').'" href="'.api_get_path(WEB_CODE_PATH).'attendance/index.php?cidReq='.$courseCodeItem.'&id_session='.$sId.'&student_id='.$student_id.'">'.
-                                $results_faults_avg['faults'].'/'.$results_faults_avg['total'].' ('.$results_faults_avg['porcent'].'%)</a>';
+                            $attendances_faults_avg = '<a title="'.get_lang('GoAttendance').'" href="'.api_get_path(WEB_CODE_PATH)
+                                .'attendance/index.php?cidReq='.$courseCodeItem.'&id_session='.$sId.'&student_id='
+                                .$student_id.'">'
+                                .$results_faults_avg['faults'].'/'.$results_faults_avg['total'].' ('
+                                .$results_faults_avg['porcent'].'%)</a>';
                         } else {
-                            $attendances_faults_avg =
-                                $results_faults_avg['faults'].'/'.
-                                $results_faults_avg['total'].
-                                ' ('.$results_faults_avg['porcent'].'%)'
-                            ;
+                            $attendances_faults_avg = $results_faults_avg['faults'].'/'
+                                .$results_faults_avg['total']
+                                .' ('.$results_faults_avg['porcent'].'%)';
                         }
                         $totalAttendance[0] += $results_faults_avg['faults'];
                         $totalAttendance[1] += $results_faults_avg['total'];
@@ -1026,11 +1018,14 @@ if (empty($details)) {
                     <td >'.$scoretotal_display.'</td>';
 
                     if (!empty($coachId)) {
-                        echo '<td width="10"><a href="'.api_get_self().'?student='.$user_info['user_id'].'&details=true&course='.$courseInfoItem['code'].'&id_coach='.$coachId.'&origin='.$origin.'&id_session='.$sId.'#infosStudent">
-                        '.Display::return_icon('2rightarrow.png', get_lang('Details')).'</a></td>';
+                        echo '<td width="10"><a href="'.api_get_self().'?student='.$user_info['user_id']
+                            .'&details=true&course='.$courseInfoItem['code'].'&id_coach='.$coachId.'&origin='.$origin
+                            .'&id_session='.$sId.'#infosStudent">'
+                            .Display::return_icon('2rightarrow.png', get_lang('Details')).'</a></td>';
                     } else {
-                        echo '<td width="10"><a href="'.api_get_self().'?student='.$user_info['user_id'].'&details=true&course='.$courseInfoItem['code'].'&origin='.$origin.'&id_session='.$sId.'#infosStudent">
-                        '.Display::return_icon('2rightarrow.png', get_lang('Details')).'</a></td>';
+                        echo '<td width="10"><a href="'.api_get_self().'?student='.$user_info['user_id']
+                            .'&details=true&course='.$courseInfoItem['code'].'&origin='.$origin.'&id_session='.$sId.'#infosStudent">'
+                            .Display::return_icon('2rightarrow.png', get_lang('Details')).'</a></td>';
                     }
                     echo '</tr>';
                 }
@@ -1069,11 +1064,19 @@ if (empty($details)) {
             $exportCourseList[$sId][] = $csvRow;
             $sessionAction = Display::url(
                 Display::return_icon('export_csv.png', get_lang('ExportAsCSV'), [], ICON_SIZE_MEDIUM),
-                $currentUrl.'&'.http_build_query(['action' => 'export_one_session_row', 'export' => 'csv', 'session_to_export' => $sId])
+                $currentUrl
+                    .'&'
+                    .http_build_query(
+                        ['action' => 'export_one_session_row', 'export' => 'csv', 'session_to_export' => $sId]
+                    )
             );
             $sessionAction .= Display::url(
                 Display::return_icon('export_excel.png', get_lang('ExportAsXLS'), [], ICON_SIZE_MEDIUM),
-                $currentUrl.'&'.http_build_query(['action' => 'export_one_session_row', 'export' => 'xls', 'session_to_export' => $sId])
+                $currentUrl
+                    .'&'
+                    .http_build_query(
+                        ['action' => 'export_one_session_row', 'export' => 'xls', 'session_to_export' => $sId]
+                    )
             );
             echo $sessionAction;
         } else {
@@ -1278,7 +1281,7 @@ if (empty($details)) {
                     );
 
                     // Latest exercise results in a LP
-                    $score_latest = Tracking:: get_avg_student_score(
+                    $score_latest = Tracking::get_avg_student_score(
                         $student_id,
                         $course_code,
                         [$lp_id],
@@ -1368,7 +1371,8 @@ if (empty($details)) {
                         }
                         $link = Display::url(
                             Display::return_icon('2rightarrow.png', get_lang('Details')),
-                            'lp_tracking.php?cidReq='.$course_code.'&course='.$course_code.$from.'&origin='.$origin.'&lp_id='.$lp_id.'&student_id='.$user_info['user_id'].'&id_session='.$sessionId
+                            'lp_tracking.php?cidReq='.$course_code.'&course='.$course_code.$from.'&origin='.$origin
+                            .'&lp_id='.$lp_id.'&student_id='.$user_info['user_id'].'&id_session='.$sessionId
                         );
                         echo Display::tag('td', $link);
                     }
@@ -1376,16 +1380,19 @@ if (empty($details)) {
                     if (api_is_allowed_to_edit()) {
                         echo '<td>';
                         if ($any_result === true) {
-                            $url = 'myStudents.php?action=reset_lp&sec_token='.$token.'&cidReq='.$course_code.'&course='.$course_code.'&details='.$details.'&origin='.$origin.'&lp_id='.$lp_id.'&student='.$user_info['user_id'].'&details=true&id_session='.$sessionId;
+                            $url = 'myStudents.php?action=reset_lp&sec_token='.$token.'&cidReq='.$course_code.'&course='
+                                .$course_code.'&details='.$details.'&origin='.$origin.'&lp_id='.$lp_id.'&student='
+                                .$user_info['user_id'].'&details=true&id_session='.$sessionId;
                             echo Display::url(
-                                Display::return_icon(
-                                    'clean.png',
-                                    get_lang('Clean'),
-                                    '',
-                                    ICON_SIZE_SMALL
-                                ),
+                                Display::return_icon('clean.png', get_lang('Clean')),
                                 $url,
-                                ['onclick' => "javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('AreYouSureToDelete')))."')) return false;"]
+                                [
+                                    'onclick' => "javascript:if(!confirm('"
+                                        .addslashes(
+                                            api_htmlentities(get_lang('AreYouSureToDelete'))
+                                        )
+                                        ."')) return false;",
+                                ]
                             );
                         }
                         echo '</td>';
@@ -1517,19 +1524,22 @@ if (empty($details)) {
                     ORDER BY exe_date DESC
                     LIMIT 1';
                 $result_last_attempt = Database::query($sql);
-                if (Database:: num_rows($result_last_attempt) > 0) {
-                    $id_last_attempt = Database:: result($result_last_attempt, 0, 0);
+                if (Database::num_rows($result_last_attempt) > 0) {
+                    $id_last_attempt = Database::result($result_last_attempt, 0, 0);
                     if ($count_attempts > 0) {
-                        echo '<a href="../exercise/exercise_show.php?id='.$id_last_attempt.'&cidReq='.$course_code.'&id_session='.$sessionId.'&session_id='.$sessionId.'&student='.$student_id.'&origin='.(empty($origin) ? 'tracking' : $origin).'">
-                    '.Display::return_icon('quiz.png').'
-                 </a>';
+                        echo '<a href="../exercise/exercise_show.php?id='.$id_last_attempt.'&cidReq='.$course_code
+                            .'&id_session='.$sessionId.'&session_id='.$sessionId.'&student='.$student_id.'&origin='
+                            .(empty($origin) ? 'tracking' : $origin).'">'
+                            .Display::return_icon('quiz.png')
+                            .'</a>';
                     }
                 }
                 echo '</td>';
 
                 echo '<td>';
                 if ($count_attempts > 0) {
-                    $all_attempt_url = "../exercise/exercise_report.php?exerciseId=$exercise_id&cidReq=$course_code&filter_by_user=$student_id&id_session=$sessionId";
+                    $all_attempt_url = "../exercise/exercise_report.php?exerciseId=$exercise_id&"
+                        ."cidReq=$course_code&filter_by_user=$student_id&id_session=$sessionId";
                     echo Display::url(
                         Display::return_icon(
                             'test_results.png',
@@ -1640,7 +1650,8 @@ if (empty($details)) {
             echo '<tr>';
             echo '<td>'.$work->title.'</td>';
             $documentNumber = $key + 1;
-            $url = api_get_path(WEB_CODE_PATH).'work/view.php?cidReq='.$course_code.'&id_session='.$sessionId.'&id='.$results['id'];
+            $url = api_get_path(WEB_CODE_PATH).'work/view.php?cidReq='.$course_code.'&id_session='.$sessionId.'&id='
+                .$results['id'];
             echo '<td class="text-center"><a href="'.$url.'">('.$documentNumber.')</a></td>';
             $qualification = !empty($results['qualification']) ? $results['qualification'] : '-';
             echo '<td class="text-center">'.$qualification.'</td>';
@@ -1746,7 +1757,7 @@ if (empty($details)) {
     </tbody>
     </table>
     </div>
-<?php
+    <?php
 } //end details
 
 $allowAll = api_get_configuration_value('allow_teacher_access_student_skills');

+ 9 - 6
main/template/default/javascript/editor/ckeditor/config_js.tpl

@@ -32,22 +32,22 @@ CKEDITOR.editorConfig = function (config) {
         },
         {
             name : 'Alert Success',
-            element : 'p',
+            element : 'div',
             attributes : { 'class': 'alert alert-success' }
         },
         {
             name : 'Alert Info',
-            element : 'p',
+            element : 'div',
             attributes : { 'class': 'alert alert-info' }
         },
         {
             name : 'Alert Warning',
-            element : 'p',
+            element : 'div',
             attributes : { 'class': 'alert alert-warning' }
         },
         {
             name : 'Alert Danger',
-            element : 'p',
+            element : 'div',
             attributes : { 'class': 'alert alert-danger' }
         },
         {
@@ -109,8 +109,11 @@ CKEDITOR.editorConfig = function (config) {
     // Allows to use "class" attribute inside divs and spans.
     config.allowedContent = true;
     // Option to set the "styles" menu
-    config.contentsCss = '{{ css_editor }}';
-    config.customConfig = '{{ _p.web_main ~ 'inc/lib/javascript/ckeditor/config_js.php'}}';
+    config.contentsCss = [
+        '{{ bootstrap_css }}',
+        '{{ font_awesome_css }}',
+        '{{ css_editor }}',
+    ];
 };
 
 // Sets default target to "_blank" in link plugin

+ 1 - 1
plugin/customcertificate/src/print_certificate.php

@@ -109,7 +109,7 @@ $htmlText .= '
 $htmlText .= '
     <link rel="stylesheet"
         type="text/css"
-        href="'.api_get_path(WEB_CSS_PATH).'editor.css">';
+        href="'.api_get_path(WEB_CSS_PATH).'document.css">';
 $htmlText .= '<body>';
 foreach ($userList as $userInfo) {
     $studentId = $userInfo['user_id'];

+ 4 - 7
src/Chamilo/CoreBundle/Component/Editor/CkEditor/CkEditor.php

@@ -4,6 +4,7 @@
 namespace Chamilo\CoreBundle\Component\Editor\CkEditor;
 
 use Chamilo\CoreBundle\Component\Editor\Editor;
+use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
 
 //use Symfony\Component\Routing\Generator\UrlGenerator;
 
@@ -55,13 +56,9 @@ class CkEditor extends Editor
     {
         $style = '';
         if (trim($this->value) == '<html><head><title></title></head><body></body></html>' || $this->value == '') {
-            $cssFile = api_get_path(SYS_CSS_PATH).'themes/'.api_get_visual_theme().'/editor.css';
-            if (!is_file($cssFile)) {
-                $cssFile = api_get_path(WEB_CSS_PATH).'editor.css';
-            } else {
-                $cssFile = api_get_path(WEB_CSS_PATH).'themes/'.api_get_visual_theme().'/editor.css';
-            }
-            $style = '<link href="'.$cssFile.'" rel="stylesheet" type="text/css" />';
+            $style = api_get_css_asset('bootstrap/dist/css/bootstrap.min.css');
+            $style .= api_get_css_asset('fontawesome/css/font-awesome.min.css');
+            $style .= api_get_css(ChamiloApi::getEditorDocStylePath());
         }
 
         $html = '<textarea id="'.$this->getName().'" name="'.$this->getName().'" class="ckeditor">

+ 36 - 0
src/Chamilo/CoreBundle/Component/Utils/ChamiloApi.php

@@ -253,4 +253,40 @@ class ChamiloApi
 
         return $prefix.$text;
     }
+
+    /**
+     * Get the stylesheet path for HTML documents created with CKEditor.
+     *
+     * @return string
+     */
+    public static function getEditorDocStylePath()
+    {
+        $visualTheme = api_get_visual_theme();
+
+        $cssFile = api_get_path(SYS_CSS_PATH)."themes/$visualTheme/document.css";
+
+        if (is_file($cssFile)) {
+            return api_get_path(WEB_CSS_PATH)."themes/$visualTheme/document.css";
+        }
+
+        return api_get_path(WEB_CSS_PATH).'document.css';
+    }
+
+    /**
+     * Get the stylesheet path for HTML blocks created with CKEditor.
+     *
+     * @return string
+     */
+    public static function getEditorBlockStylePath()
+    {
+        $visualTheme = api_get_visual_theme();
+
+        $cssFile = api_get_path(SYS_CSS_PATH)."themes/$visualTheme/editor_content.css";
+
+        if (is_file($cssFile)) {
+            return api_get_path(WEB_CSS_PATH)."themes/$visualTheme/editor_content.css";
+        }
+
+        return api_get_path(WEB_CSS_PATH).'editor_content.css';
+    }
 }

+ 10 - 1
src/Chamilo/CoreBundle/Composer/ScriptHandler.php

@@ -222,7 +222,16 @@ class ScriptHandler
     {
         $appCss = __DIR__.'/../../../../app/Resources/public/css/';
         $newPath = __DIR__.'/../../../../web/css/';
-        $cssFiles = ['base.css', 'chat.css', 'editor.css', 'markdown.css', 'print.css', 'responsive.css', 'scorm.css'];
+        $cssFiles = [
+            'base.css',
+            'chat.css',
+            'document.css',
+            'editor_content.css',
+            'markdown.css',
+            'print.css',
+            'responsive.css',
+            'scorm.css',
+        ];
 
         $fs = new Filesystem();