Test Setup Failed
Push — master ( 4e700f...c7183e )
by Julito
63:12
created

Template::addHTTPSecurityHeaders()   D

Complexity

Conditions 10
Paths 512

Size

Total Lines 50
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 28
nc 512
nop 0
dl 0
loc 50
rs 4
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CoreBundle\Framework\Container;
5
6
/**
7
 * Class Template
8
 *
9
 * @author Julio Montoya <[email protected]>
10
 *
11
 *
12
 * In Chamilo 2 files inside main/ (classic chamilo files) are
13
 * wrapped by a Symfony2 controller LegacyController::classicAction
14
 * This controller will handle the breadcrumb, the template rendering
15
 * and everything as a normal Symfony2 action.
16
 *
17
 * Example:
18
 * Chamilo 1.x
19
 * my.chamilo.net/main/admin/user_list.php
20
 *
21
 * Chamilo 2.x
22
 * (dev mode)
23
 * my.chamilo.net/web/app_dev.php/main/admin/user_list.php
24
 * (production mode)
25
 * my.chamilo.net/web/main/admin/user_list.php
26
 *
27
 * All twig settings are loaded as Twig Extensions and Listeners see:
28
 *
29
 * src/Chamilo/CoreBundle/Twig/Extension/ChamiloExtension.php
30
 *
31
 * src/Chamilo/CoreBundle/EventListener/LegacyListener.php
32
 *
33
 *
34
 */
35
class Template
36
{
37
    /**
38
     * The Template folder name see main/template
39
     * @var string
40
     */
41
    public $templateFolder = 'default';
42
43
    /**
44
     * The theme that will be used: chamilo, public_admin, chamilo_red, etc
45
     * This variable is set from the database
46
     * @var string
47
     */
48
    public $theme = '';
49
50
    /**
51
     * @var string
52
     */
53
    public $preview_theme = '';
54
    public $title = null;
55
    public $show_header;
56
    public $show_footer;
57
    public $help;
58
    public $menu_navigation = array(); //Used in the userportal.lib.php function: return_navigation_course_links()
59
    public $show_learnpath = false; // This is a learnpath section or not?
60
    public $plugin = null;
61
    public $course_id = null;
62
    public $user_is_logged_in = false;
63
    public $twig = null;
64
65
    /* Loads chamilo plugins */
66
    public $load_plugins = false;
67
    public static $params = array();
68
    public $force_plugin_load = false;
69
70
    /**
71
     *
72
     * @param string $title
73
     * @param bool $show_header
74
     * @param bool $show_footer
75
     * @param bool $show_learnpath
76
     * @param bool $hide_global_chat
77
     * @param bool $load_plugins
78
     * @param bool $sendHeaders send http headers or not
79
     */
80
    public function __construct(
81
        $title = '',
82
        $show_header = true,
83
        $show_footer = true,
84
        $show_learnpath = false,
85
        $hide_global_chat = false,
86
        $load_plugins = true,
87
        $sendHeaders = true
88
    ) {
89
90
        if ($show_header == false) {
91
            Container::$legacyTemplate = '@ChamiloTheme/Layout/layout_one_col_no_content.html.twig';
92
        }
93
94
        return;
95
        // Page title
96
        $this->title = $title;
0 ignored issues
show
Unused Code introduced by
// Page title $this->title = $title; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
97
98
        $this->show_learnpath = $show_learnpath;
99
100
        if (empty($this->show_learnpath)) {
101
            $origin = api_get_origin();
102
            if ($origin === 'learnpath') {
103
                $this->show_learnpath = true;
104
                $show_footer = false;
105
                $show_header = false;
106
            }
107
        }
108
        $this->hide_global_chat = $hide_global_chat;
109
        $this->load_plugins = $load_plugins;
110
111
        $template_paths = array(
112
            api_get_path(SYS_CODE_PATH).'template/overrides', // user defined templates
113
            api_get_path(SYS_CODE_PATH).'template', //template folder
114
            api_get_path(SYS_PLUGIN_PATH) // plugin folder
115
        );
116
117
        $urlId = api_get_current_access_url_id();
118
119
        $cache_folder = api_get_path(SYS_ARCHIVE_PATH).'twig/'.$urlId.'/';
120
121
        if (!is_dir($cache_folder)) {
122
            mkdir($cache_folder, api_get_permissions_for_new_directories(), true);
123
        }
124
125
        $loader = new Twig_Loader_Filesystem($template_paths);
126
127
        //Setting Twig options depending on the server see http://twig.sensiolabs.org/doc/api.html#environment-options
128
        if (api_get_setting('server_type') == 'test') {
129
            $options = array(
130
                //'cache' => api_get_path(SYS_ARCHIVE_PATH), //path to the cache folder
131
                'autoescape' => false,
132
                'debug' => true,
133
                'auto_reload' => true,
134
                'optimizations' => 0,
135
                // turn on optimizations with -1
136
                'strict_variables' => false,
137
                //If set to false, Twig will silently ignore invalid variables
138
            );
139
        } else {
140
            $options = array(
141
                'cache' => $cache_folder,
142
                //path to the cache folder
143
                'autoescape' => false,
144
                'debug' => false,
145
                'auto_reload' => false,
146
                'optimizations' => -1,
147
                // turn on optimizations with -1
148
                'strict_variables' => false
149
                //If set to false, Twig will silently ignore invalid variables
150
            );
151
        }
152
153
        $this->twig = new Twig_Environment($loader, $options);
154
155
        $this->twig->addFilter('get_plugin_lang', new Twig_Filter_Function('get_plugin_lang'));
0 ignored issues
show
Deprecated Code introduced by
The class Twig_Filter_Function has been deprecated with message: since 1.12 (to be removed in 2.0)

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
156
        $this->twig->addFilter('get_lang', new Twig_Filter_Function('get_lang'));
0 ignored issues
show
Deprecated Code introduced by
The class Twig_Filter_Function has been deprecated with message: since 1.12 (to be removed in 2.0)

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
157
        $this->twig->addFilter('get_path', new Twig_Filter_Function('api_get_path'));
0 ignored issues
show
Deprecated Code introduced by
The class Twig_Filter_Function has been deprecated with message: since 1.12 (to be removed in 2.0)

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
158
        $this->twig->addFilter('get_setting', new Twig_Filter_Function('api_get_setting'));
0 ignored issues
show
Deprecated Code introduced by
The class Twig_Filter_Function has been deprecated with message: since 1.12 (to be removed in 2.0)

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
159
        $this->twig->addFilter('var_dump', new Twig_Filter_Function('var_dump'));
0 ignored issues
show
Deprecated Code introduced by
The class Twig_Filter_Function has been deprecated with message: since 1.12 (to be removed in 2.0)

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
160
        //$this->twig->addFilter('return_logo', new Twig_Filter_Function('return_logo'));
161
        $this->twig->addFilter('return_message', new Twig_Filter_Function('Display::return_message_and_translate'));
0 ignored issues
show
Deprecated Code introduced by
The class Twig_Filter_Function has been deprecated with message: since 1.12 (to be removed in 2.0)

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
162
        $this->twig->addFilter('display_page_header', new Twig_Filter_Function('Display::page_header_and_translate'));
0 ignored issues
show
Deprecated Code introduced by
The class Twig_Filter_Function has been deprecated with message: since 1.12 (to be removed in 2.0)

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
163
        $this->twig->addFilter(
164
            'display_page_subheader',
165
            new Twig_Filter_Function('Display::page_subheader_and_translate')
0 ignored issues
show
Deprecated Code introduced by
The class Twig_Filter_Function has been deprecated with message: since 1.12 (to be removed in 2.0)

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
166
        );
167
        $this->twig->addFilter('icon', new Twig_Filter_Function('Template::get_icon_path'));
0 ignored issues
show
Deprecated Code introduced by
The class Twig_Filter_Function has been deprecated with message: since 1.12 (to be removed in 2.0)

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
168
        $this->twig->addFilter('img', new Twig_Filter_Function('Template::get_image'));
0 ignored issues
show
Deprecated Code introduced by
The class Twig_Filter_Function has been deprecated with message: since 1.12 (to be removed in 2.0)

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
169
        $this->twig->addFilter('format_date', new Twig_Filter_Function('Template::format_date'));
0 ignored issues
show
Deprecated Code introduced by
The class Twig_Filter_Function has been deprecated with message: since 1.12 (to be removed in 2.0)

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
170
        $this->twig->addFilter('api_get_local_time', new Twig_Filter_Function('api_get_local_time'));
0 ignored issues
show
Deprecated Code introduced by
The class Twig_Filter_Function has been deprecated with message: since 1.12 (to be removed in 2.0)

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
171
        // a combination of the two previous functions
172
        $this->twig->addFilter('local_format_date', new Twig_Filter_Function('api_convert_and_format_date'));
0 ignored issues
show
Deprecated Code introduced by
The class Twig_Filter_Function has been deprecated with message: since 1.12 (to be removed in 2.0)

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
173
        $this->twig->addFilter('user_info', new Twig_Filter_Function('api_get_user_info'));
0 ignored issues
show
Deprecated Code introduced by
The class Twig_Filter_Function has been deprecated with message: since 1.12 (to be removed in 2.0)

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
174
        $this->twig->addFilter('get_configuration_value', new Twig_Filter_Function('api_get_configuration_value'));
0 ignored issues
show
Deprecated Code introduced by
The class Twig_Filter_Function has been deprecated with message: since 1.12 (to be removed in 2.0)

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
175
176
        /*
177
          $lexer = new Twig_Lexer($this->twig, array(
178
          //'tag_comment'  => array('{*', '*}'),
179
          //'tag_comment'  => array('{#', '#}'),
180
          //'tag_block'    => array('{', '}'),
181
          //'tag_variable' => array('{$', '}'),
182
          ));
183
          $this->twig->setLexer($lexer); */
184
185
        //Setting system variables
186
        $this->set_system_parameters();
187
188
        //Setting user variables
189
        $this->set_user_parameters();
190
191
        //Setting course variables
192
        $this->set_course_parameters();
193
194
        //Setting administrator variables
195
        $this->setAdministratorParams();
196
197
        $this->setCSSEditor();
198
199
        //header and footer are showed by default
200
        $this->set_footer($show_footer);
201
        $this->set_header($show_header);
202
203
        $this->set_header_parameters($sendHeaders);
204
        $this->set_footer_parameters();
205
206
        $defaultStyle = api_get_configuration_value('default_template');
207
        if (!empty($defaultStyle)) {
208
            $this->templateFolder = $defaultStyle;
209
        }
210
211
        $this->assign('template', $this->templateFolder);
212
        $this->assign('locale', api_get_language_isocode());
213
214
        $this->assign('css_styles', $this->theme);
215
        $this->assign('login_class', null);
216
217
        $this->setLoginForm();
218
219
        // Chamilo plugins
220
        if ($this->show_header) {
221
            if ($this->load_plugins) {
222
223
                $this->plugin = new AppPlugin();
224
225
                //1. Showing installed plugins in regions
226
                $pluginRegions = $this->plugin->get_plugin_regions();
227
                foreach ($pluginRegions as $region) {
228
                    $this->set_plugin_region($region);
229
                }
230
231
                //2. Loading the course plugin info
232
                global $course_plugin;
233
                if (isset($course_plugin) && !empty($course_plugin) && !empty($this->course_id)) {
234
                    //Load plugin get_langs
235
                    $this->plugin->load_plugin_lang_variables($course_plugin);
236
                }
237
            }
238
        }
239
    }
240
241
    /**
242
     * @param string $image
243
     * @param int $size
244
     *
245
     * @return string
246
     */
247
    public static function get_icon_path($image, $size = ICON_SIZE_SMALL)
248
    {
249
        return Display::return_icon($image, '', array(), $size, false, true);
250
    }
251
252
    /**
253
     * @param string $image
254
     * @param int $size
255
     * @param string $name
256
     * @return string
257
     */
258
    public static function get_image($image, $size = ICON_SIZE_SMALL, $name)
259
    {
260
        return Display::return_icon($image, $name, array(), $size);
261
    }
262
263
    /**
264
     * @param string $timestamp
265
     * @param string $format
266
     *
267
     * @return string
268
     */
269
    public static function format_date($timestamp, $format = null)
270
    {
271
        return api_format_date($timestamp, $format);
272
    }
273
274
    /**
275
     * Return the item's url key:
276
     *
277
     *      c_id=xx&id=xx
278
     *
279
     * @param object $item
280
     * @return string
281
     */
282
    public static function key($item)
283
    {
284
        $id     = isset($item->id) ? $item->id : null;
285
        $c_id   = isset($item->c_id) ? $item->c_id : null;
286
        $result = '';
287
        if ($c_id) {
288
            $result = "c_id=$c_id";
289
        }
290
        if ($id) {
291
            if ($result) {
292
                $result .= "&amp;id=$id";
293
            } else {
294
                $result .= "&amp;id=$id";
295
            }
296
        }
297
        return $result;
298
    }
299
300
    /**
301
     * @param string $helpInput
302
     */
303
    public function setHelp($helpInput = null)
304
    {
305
        if (!empty($helpInput)) {
306
            $help = $helpInput;
307
        } else {
308
            $help = $this->help;
309
        }
310
311
        $content = '';
312
        if (api_get_setting('enable_help_link') == 'true') {
313
            if (!empty($help)) {
314
                $help = Security::remove_XSS($help);
315
                $content = '<div class="help">';
316
                $content .= Display::url(
317
                    Display::return_icon('help.large.png', get_lang('Help')),
318
                    api_get_path(WEB_CODE_PATH) . 'help/help.php?open=' . $help,
319
                    [
320
                        'class' => 'ajax',
321
                        'data-title' => get_lang('Help')
322
                    ]
323
                );
324
                $content .= '</div>';
325
            }
326
        }
327
        $this->assign('help_content', $content);
328
    }
329
330
    /**
331
     * Use template system to parse the actions menu
332
     * @todo finish it!
333
     **/
334
    public function set_actions($actions)
335
    {
336
        $action_string = '';
337
        if (!empty($actions)) {
338
            foreach ($actions as $action) {
339
                $action_string .= $action;
340
            }
341
        }
342
        $this->assign('actions', $actions);
343
    }
344
345
    /**
346
     * Render the template
347
     * @param string $template The template path
348
     * @param boolean $clearFlashMessages Clear the $_SESSION variables for flash messages
349
     */
350
    public function display($template, $clearFlashMessages = true)
351
    {
352
        Container::$legacyTemplate = $template;
353
        //echo $this->twig->render($template, $this->params);
354
    }
355
356
    /**
357
     * Shortcut to display a 1 col layout (index.php)
358
     * */
359
    public function display_one_col_template()
360
    {
361
        Container::$legacyTemplate = '@ChamiloTheme/Layout/layout_one_col.html.twig';
362
    }
363
364
    /**
365
     * Shortcut to display a 2 col layout (userportal.php)
366
     **/
367
    public function display_two_col_template()
368
    {
369
        Container::$legacyTemplate = '@ChamiloTheme/Layout/layout_two_col.html.twig';
370
    }
371
372
    /**
373
     * Displays an empty template
374
     */
375
    public function display_blank_template()
376
    {
377
        Container::$legacyTemplate = '@ChamiloTheme/Layout/no_layout.html.twig';
378
    }
379
380
    /**
381
     * Displays an empty template
382
     */
383
    public function display_no_layout_template()
384
    {
385
        Container::$legacyTemplate = '@ChamiloTheme/Layout/no_layout.html.twig';
386
    }
387
388
    /**
389
     * Sets the footer visibility
390
     * @param bool true if we show the footer
391
     */
392
    public function set_footer($status)
393
    {
394
        $this->show_footer = $status;
395
        $this->assign('show_footer', $status);
396
    }
397
398
    /**
399
     * return true if toolbar has to be displayed for user
400
     * @return bool
401
     */
402
    public static function isToolBarDisplayedForUser()
403
    {
404
        //Toolbar
405
        $show_admin_toolbar = api_get_setting('show_admin_toolbar');
406
        $show_toolbar = false;
407
408
        switch ($show_admin_toolbar) {
409
            case 'do_not_show':
410
                break;
411
            case 'show_to_admin':
412
                if (api_is_platform_admin()) {
413
                    $show_toolbar = true;
414
                }
415
                break;
416
            case 'show_to_admin_and_teachers':
417
                if (api_is_platform_admin() || api_is_allowed_to_edit()) {
418
                    $show_toolbar = true;
419
                }
420
                break;
421
            case 'show_to_all':
422
                $show_toolbar = true;
423
                break;
424
        }
425
        return $show_toolbar;
426
    }
427
428
    /**
429
     * Sets the header visibility
430
     * @param bool true if we show the header
431
     */
432
    public function set_header($status)
433
    {
434
        $this->show_header = $status;
435
        $this->assign('show_header', $status);
436
437
        $show_toolbar = 0;
438
439
        if (self::isToolBarDisplayedForUser()) {
440
            $show_toolbar = 1;
441
        }
442
443
        $this->assign('show_toolbar', $show_toolbar);
444
445
        //Only if course is available
446
        $show_course_shortcut        = null;
447
        $show_course_navigation_menu = null;
448
449
        if (!empty($this->course_id) && $this->user_is_logged_in) {
450
451
            if (api_get_setting('show_toolshortcuts') != 'false') {
452
                //Course toolbar
453
                $show_course_shortcut = CourseHome::show_navigation_tool_shortcuts();
454
            }
455
            if (api_get_setting('show_navigation_menu') != 'false') {
456
                //Course toolbar
457
                $show_course_navigation_menu = CourseHome::show_navigation_menu();
458
            }
459
        }
460
        $this->assign('show_course_shortcut', $show_course_shortcut);
461
        $this->assign('show_course_navigation_menu', $show_course_navigation_menu);
462
    }
463
464
    /**
465
     * @param string $name
466
     *
467
     * @return string
468
     */
469
    public function get_template($name)
470
    {
471
        if ($name == 'layout/layout_1_col.tpl') {
472
            $name = '@ChamiloTheme/Layout/layout_1_col.html.twig';
473
        }
474
475
        if ($name == 'layout/layout_2_col.tpl') {
476
            $name = '@ChamiloTheme/Layout/layout_2_col.html.twig';
477
        }
478
479
        /**
480
         * In Chamilo 1.x we use the tpl extension.
481
         * In Chamilo 2.x we use twig but using the Symfony2 bridge
482
         * In order to don't change all legacy main calls we just replace
483
         * tpl with html.twig (the new template location should be:
484
         * (src/Chamilo/CoreBundle/Resources/views/default/layout)
485
         */
486
        $name = str_replace('.tpl', '.html.twig', $name);
487
488
        return '@ChamiloCore/'.$this->templateFolder.'/'.$name;
489
    }
490
491
    /**
492
     * Set course parameters
493
     */
494
    private function set_course_parameters()
495
    {
496
        //Setting course id
497
        $course = api_get_course_info();
498
        if (empty($course)) {
499
            $this->assign('course_is_set', false);
500
            return;
501
        }
502
        $this->assign('course_is_set', true);
503
        $this->course_id = $course['id'];
504
        $_c = array(
505
            'id' => $course['id'],
506
            'code' => $course['code'],
507
            'title' => $course['name'],
508
            'visibility' => $course['visibility'],
509
            'language' => $course['language'],
510
            'directory' => $course['directory'],
511
            'session_id' => api_get_session_id(),
512
            'user_is_teacher' => api_is_course_admin(),
513
            'student_view' => (!empty($_GET['isStudentView']) && $_GET['isStudentView'] == 'true'),
514
        );
515
        $this->assign('course_code', $course['code']);
516
        $this->assign('_c', $_c);
517
    }
518
519
    /**
520
     * Set user parameters
521
     */
522
    private function set_user_parameters()
523
    {
524
        $user_info = array();
525
        $user_info['logged'] = 0;
526
        $this->user_is_logged_in = false;
527
        if (api_user_is_login()) {
528
            $user_info = api_get_user_info(api_get_user_id(), true);
529
            $user_info['logged'] = 1;
530
531
            $user_info['is_admin'] = 0;
532
            if (api_is_platform_admin()) {
533
                $user_info['is_admin'] = 1;
534
            }
535
536
            $user_info['messages_count'] = MessageManager::getCountNewMessages();
537
            $this->user_is_logged_in = true;
538
        }
539
        // Setting the $_u array that could be use in any template
540
        $this->assign('_u', $user_info);
541
    }
542
543
    /**
544
     * Set system parameters
545
     */
546
    private function set_system_parameters()
547
    {
548
        global $_configuration;
549
        $this->theme = api_get_visual_theme();
550
551
        //Here we can add system parameters that can be use in any template
552
        $_s = array(
553
            'software_name' => $_configuration['software_name'],
554
            'system_version' => $_configuration['system_version'],
555
            'site_name' => api_get_setting('siteName'),
556
            'institution' => api_get_setting('Institution'),
557
            'date' => api_format_date('now', DATE_FORMAT_LONG),
558
            'timezone' => api_get_timezone(),
559
            'gamification_mode' => api_get_setting('gamification_mode')
560
        );
561
        $this->assign('_s', $_s);
562
    }
563
564
    /**
565
     * Set legacy twig globals in order to be hook in the LegacyListener.php
566
     * @return array
567
     */
568
    public static function getGlobals()
569
    {
570
        $_p = array(
571
            'web' => api_get_path(WEB_PATH),
572
            'web_relative' => api_get_path(REL_PATH),
573
            'web_course' => api_get_path(WEB_COURSE_PATH),
574
            'web_main' => api_get_path(WEB_CODE_PATH),
575
            'web_css' => api_get_path(WEB_CSS_PATH),
576
            //'web_css_theme' => api_get_path(WEB_CSS_PATH) . 'themes/' . $this->theme . '/',
577
            'web_ajax' => api_get_path(WEB_AJAX_PATH),
578
            'web_img' => api_get_path(WEB_IMG_PATH),
579
            'web_plugin' => api_get_path(WEB_PLUGIN_PATH),
580
            'web_plugin_asset' => api_get_path(WEB_PLUGIN_ASSET_PATH),
581
            'web_lib' => api_get_path(WEB_LIBRARY_PATH),
582
            'web_upload' => api_get_path(WEB_UPLOAD_PATH),
583
            'web_self' => api_get_self(),
584
            'web_query_vars' => api_htmlentities($_SERVER['QUERY_STRING']),
585
            'web_self_query_vars' => api_htmlentities($_SERVER['REQUEST_URI']),
586
            'web_cid_query' => api_get_cidreq(),
587
        );
588
589
        $_s = array(
590
            'software_name' => api_get_configuration_value('software_name'),
591
            'system_version' => api_get_configuration_value('system_version'),
592
            'site_name' => api_get_setting('siteName'),
593
            'institution' => api_get_setting('Institution'),
594
            'date' => api_format_date('now', DATE_FORMAT_LONG),
595
            'timezone' => api_get_timezone(),
596
            'gamification_mode' => api_get_setting('gamification_mode')
597
        );
598
599
        //$user_info = api_get_user_info();
600
601
        return [
602
            '_p' => $_p,
603
            '_s' => $_s,
604
     //       '_u' => $user_info,
605
            'template' => 'default' // @todo setup template folder in config.yml;
606
        ];
607
    }
608
609
    /**
610
     * Set theme, include mainstream CSS files
611
     * @return void
612
     * @see setCssCustomFiles() for additional CSS sheets
613
     */
614
    public function setCssFiles()
615
    {
616
        return;
617
        global $disable_js_and_css_files;
0 ignored issues
show
Unused Code introduced by
global $disable_js_and_css_files; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
618
        $css = array();
619
620
        $this->theme = api_get_visual_theme();
621
622
        if (!empty($this->preview_theme)) {
623
            $this->theme = $this->preview_theme;
624
        }
625
626
        // Default CSS Bootstrap
627
        $bowerCSSFiles = [
628
            'bootstrap-daterangepicker/daterangepicker-bs3.css',
629
            'fontawesome/css/font-awesome.min.css',
630
            'jquery-ui/themes/smoothness/theme.css',
631
            'jquery-ui/themes/smoothness/jquery-ui.min.css',
632
            'mediaelement/build/mediaelementplayer.min.css',
633
            'jqueryui-timepicker-addon/dist/jquery-ui-timepicker-addon.min.css',
634
            'bootstrap/dist/css/bootstrap.min.css',
635
            'jquery.scrollbar/jquery.scrollbar.css',
636
        ];
637
638
        foreach ($bowerCSSFiles as $file) {
639
            $css[] = api_get_path(WEB_PATH).'web/assets/'.$file;
640
        }
641
        $css[] = api_get_path(WEB_LIBRARY_PATH) . 'javascript/bootstrap-select/css/bootstrap-select.min.css';
642
        $css[] = api_get_path(WEB_LIBRARY_PATH) . 'javascript/chosen/chosen.css';
643
        $css[] = api_get_path(WEB_LIBRARY_PATH) . 'javascript/tag/style.css';
644
645
        if (api_is_global_chat_enabled()) {
646
            $css[] = api_get_path(WEB_LIBRARY_PATH) . 'javascript/chat/css/chat.css';
647
        }
648
649
        //THEME CSS STYLE
650
        // $css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'responsive.css');
651
652
        $css_file_to_string = null;
653
        foreach ($css as $file) {
654
            $css_file_to_string .= api_get_css($file);
655
        }
656
657
        if (!$disable_js_and_css_files) {
658
            $this->assign('css_static_file_to_string', $css_file_to_string);
659
        }
660
    }
661
662
    /**
663
     *
664
     */
665
    public function setCSSEditor()
666
    {
667
        return;
668
        $cssEditor = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'editor.css');
0 ignored issues
show
Unused Code introduced by
$cssEditor = api_get_cdn..._PATH) . 'editor.css'); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
669
        if (is_file(api_get_path(SYS_CSS_PATH).'themes/'.$this->theme.'/editor.css')) {
670
            $cssEditor = api_get_path(WEB_CSS_PATH).'themes/'.$this->theme.'/editor.css';
671
        }
672
673
        $this->assign('cssEditor', $cssEditor);
674
    }
675
676
    /**
677
     * Prepare custom CSS to be added at the very end of the <head> section
678
     * @return void
679
     * @see setCssFiles() for the mainstream CSS files
680
     */
681
    public function setCssCustomFiles()
682
    {
683
        return;
684
        global $disable_js_and_css_files;
0 ignored issues
show
Unused Code introduced by
global $disable_js_and_css_files; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
685
        // Base CSS
686
687
        $css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'base.css');
688
689 View Code Duplication
        if ($this->show_learnpath) {
690
            $css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'scorm.css');
691
            if (is_file(api_get_path(SYS_CSS_PATH).'themes/'.$this->theme.'/learnpath.css')) {
692
                $css[] = api_get_path(WEB_CSS_PATH).'themes/'.$this->theme.'/learnpath.css';
693
            }
694
        }
695
696 View Code Duplication
        if (is_file(api_get_path(SYS_CSS_PATH).'themes/'.$this->theme.'/editor.css')) {
697
            $css[] = api_get_path(WEB_CSS_PATH).'themes/'.$this->theme.'/editor.css';
698
        }else{
699
            $css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'editor.css');
700
        }
701
702
        $css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'themes/'.$this->theme.'/default.css');
703
704
        $css_file_to_string = null;
705
        foreach ($css as $file) {
706
            $css_file_to_string .= api_get_css($file);
707
        }
708
        // @todo move this somewhere else. Special fix when using tablets in order to see the text near icons
709
        if (SHOW_TEXT_NEAR_ICONS == true) {
710
            //hack in order to fix the actions buttons
711
            $css_file_to_string .= '<style>
712
                .td_actions a {
713
                    float:left;
714
                    width:100%;
715
                }
716
                .forum_message_left a {
717
                    float:left;
718
                    width:100%;
719
                }
720
                </style>';
721
        }
722
723
        $navigator_info = api_get_navigator();
724
        if ($navigator_info['name'] == 'Internet Explorer' && $navigator_info['version'] == '6') {
725
            $css_file_to_string .= 'img, div { behavior: url('.api_get_path(WEB_LIBRARY_PATH).'javascript/iepngfix/iepngfix.htc) } '."\n";
726
        }
727
728
        if (!$disable_js_and_css_files) {
729
            $this->assign('css_custom_file_to_string', $css_file_to_string);
730
731
            $style_print = '';
732
            if (is_readable(api_get_path(SYS_CSS_PATH).$this->theme.'/print.css')) {
733
                $style_print = api_get_css(api_get_cdn_path(api_get_path(WEB_CSS_PATH) . $this->theme . '/print.css'),
734
                    'print');
735
            }
736
            $this->assign('css_style_print', $style_print);
737
        }
738
739
        // Logo
740
        /*$logo = return_logo($this->theme);
741
        $this->assign('logo', $logo);*/
742
743
        $this->assign('show_media_element', 1);
744
    }
745
746
    /**
747
     * Declare and define the template variable that will be used to load
748
     * javascript libraries in the header.
749
     */
750
    public function set_js_files()
751
    {
752
        global $disable_js_and_css_files, $htmlHeadXtra;
753
754
        $isoCode = api_get_language_isocode();
755
756
        $selectLink = 'bootstrap-select/js/i18n/defaults-' . $isoCode . '_' . strtoupper($isoCode) . '.min.js';
757
758
        if ($isoCode == 'en') {
759
            $selectLink = 'bootstrap-select/js/i18n/defaults-' . $isoCode . '_US.min.js';
760
        }
761
        // JS files
762
        $js_files = array(
763
            'chosen/chosen.jquery.min.js',
764
            'bootstrap-select/js/bootstrap-select.min.js',
765
            $selectLink
766
        );
767
768
        $viewBySession = api_get_setting('my_courses_view_by_session') === 'true';
769
770 View Code Duplication
        if (api_is_global_chat_enabled() || $viewBySession) {
771
            // Do not include the global chat in LP
772
            if ($this->show_learnpath == false &&
773
                $this->show_footer == true &&
774
                $this->hide_global_chat == false
775
            ) {
776
                $js_files[] = 'chat/js/chat.js';
777
            }
778
        }
779
780
        if (api_get_setting('accessibility_font_resize') == 'true') {
781
            $js_files[] = 'fontresize.js';
782
        }
783
784
        // Do not use minified version - generates errors (at least in the skills wheel)
785
        $js_files[] = 'tag/jquery.fcbkcomplete.js';
786
787
        $js_file_to_string = null;
788
789
        $bowerJsFiles = [
790
            'modernizr/modernizr.js',
791
            'jquery/dist/jquery.min.js',
792
            'bootstrap/dist/js/bootstrap.min.js',
793
            'jquery-ui/jquery-ui.min.js',
794
            'moment/min/moment-with-locales.min.js',
795
            'bootstrap-daterangepicker/daterangepicker.js',
796
            'jquery-timeago/jquery.timeago.js',
797
            'mediaelement/build/mediaelement-and-player.min.js',
798
            'jqueryui-timepicker-addon/dist/jquery-ui-timepicker-addon.min.js',
799
            'image-map-resizer/js/imageMapResizer.min.js',
800
            'jquery.scrollbar/jquery.scrollbar.min.js',
801
            'readmore-js/readmore.min.js'
802
        ];
803
        if (CHAMILO_LOAD_WYSIWYG == true) {
804
            $bowerJsFiles[] = 'ckeditor/ckeditor.js';
805
        }
806
807
        if (api_get_setting('include_asciimathml_script') == 'true') {
808
            $bowerJsFiles[] = 'MathJax/MathJax.js?config=AM_HTMLorMML';
809
        }
810
811
        if ($isoCode != 'en') {
812
            $bowerJsFiles[] = 'jqueryui-timepicker-addon/dist/i18n/jquery-ui-timepicker-' . $isoCode . '.js';
813
            $bowerJsFiles[] = 'jquery-ui/ui/minified/i18n/datepicker-' . $isoCode . '.min.js';
814
        }
815
816
        foreach ($bowerJsFiles as $file) {
817
            $js_file_to_string .= '<script type="text/javascript" src="'.api_get_path(WEB_PATH).'web/assets/'.$file.'"></script>'."\n";
818
        }
819
820
        foreach ($js_files as $file) {
821
            $js_file_to_string .= api_get_js($file);
822
        }
823
824
        // Loading email_editor js
825
        if (!api_is_anonymous() && api_get_setting('allow_email_editor') == 'true') {
826
            $template = $this->get_template('mail_editor/email_link.js.tpl');
827
            $js_file_to_string .= $this->fetch($template);
828
        }
829
830
        if (!$disable_js_and_css_files) {
831
            $this->assign('js_file_to_string', $js_file_to_string);
832
833
            //Adding jquery ui by default
834
            $extra_headers = api_get_jquery_ui_js();
835
836
            //$extra_headers = '';
837
            if (isset($htmlHeadXtra) && $htmlHeadXtra) {
838
                foreach ($htmlHeadXtra as & $this_html_head) {
839
                    $extra_headers .= $this_html_head."\n";
840
                }
841
            }
842
            $this->assign('extra_headers', $extra_headers);
843
        }
844
    }
845
846
    /**
847
     * Special function to declare last-minute JS libraries which depend on
848
     * other things to be declared first. In particular, it might be useful
849
     * under IE9 with compatibility mode, which for some reason is getting
850
     * upset when a variable is used in a function (even if not used yet)
851
     * when this variable hasn't been defined yet.
852
     */
853
    public function set_js_files_post()
854
    {
855
        global $disable_js_and_css_files, $htmlHeadXtra;
856
        $js_files = array();
857 View Code Duplication
        if (api_is_global_chat_enabled()) {
858
            //Do not include the global chat in LP
859
            if ($this->show_learnpath == false && $this->show_footer == true && $this->hide_global_chat == false) {
860
                $js_files[] = 'chat/js/chat.js';
861
            }
862
        }
863
        $js_file_to_string = null;
864
865
        foreach ($js_files as $js_file) {
866
            $js_file_to_string .= api_get_js($js_file);
867
        }
868
        if (!$disable_js_and_css_files) {
869
            $this->assign('js_file_to_string_post', $js_file_to_string);
870
        }
871
    }
872
873
    /**
874
     * Set header parameters
875
     * @param bool $sendHeaders send headers
876
     */
877
    private function set_header_parameters($sendHeaders)
878
    {
879
880
        global $httpHeadXtra, $interbreadcrumb, $language_file, $_configuration, $this_section;
881
        $_course = api_get_course_info();
882
        $help = $this->help;
883
        $nameTools = $this->title;
884
        //$navigation = return_navigation_array();
885
        $navigation = [];
886
        //$this->menu_navigation = $navigation['menu_navigation'];
887
888
        $this->assign('system_charset', api_get_system_encoding());
889
890
        if (isset($httpHeadXtra) && $httpHeadXtra) {
891
            foreach ($httpHeadXtra as & $thisHttpHead) {
892
                header($thisHttpHead);
893
            }
894
        }
895
896
        $this->assign(
897
        'online_button',
898
            Display::return_icon('statusonline.png', null, [], ICON_SIZE_ATOM)
899
        );
900
        $this->assign(
901
            'offline_button',
902
            Display::return_icon('statusoffline.png', null, [], ICON_SIZE_ATOM)
903
        );
904
905
        // Get language iso-code for this page - ignore errors
906
        $this->assign('document_language', api_get_language_isocode());
907
908
        $course_title = isset($_course['name']) ? $_course['name'] : null;
909
910
        $title_list = array();
911
912
        $title_list[] = api_get_setting('Institution');
913
        $title_list[] = api_get_setting('siteName');
914
915
        if (!empty($course_title)) {
916
            $title_list[] = $course_title;
917
        }
918
        if ($nameTools != '') {
919
            $title_list[] = $nameTools;
920
        }
921
922
        $title_string = '';
923
        for ($i = 0; $i < count($title_list); $i++) {
924
            $title_string .= $title_list[$i];
925
            if (isset($title_list[$i + 1])) {
926
                $item = trim($title_list[$i + 1]);
927
                if (!empty($item)) {
928
                    $title_string .= ' - ';
929
                }
930
            }
931
        }
932
933
        $this->assign('title_string', $title_string);
934
935
        //Setting the theme and CSS files
936
        $css = $this->setCssFiles();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $css is correct as $this->setCssFiles() (which targets Template::setCssFiles()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
937
        $this->set_js_files();
938
        $this->setCssCustomFiles($css);
939
        //$this->set_js_files_post();
940
941
        $browser = api_browser_support('check_browser');
942
        if ($browser[0] == 'Internet Explorer' && $browser[1] >= '11') {
943
            $browser_head = '<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9" />';
944
            $this->assign('browser_specific_head', $browser_head);
945
        }
946
947
        // Implementation of prefetch.
948
        // See http://cdn.chamilo.org/main/img/online.png for details
949
        $prefetch = '';
950
        if (!empty($_configuration['cdn_enable'])) {
951
            $prefetch .= '<meta http-equiv="x-dns-prefetch-control" content="on">';
952
            foreach ($_configuration['cdn'] as $host => $exts) {
953
                $prefetch .= '<link rel="dns-prefetch" href="'.$host.'">';
954
            }
955
        }
956
957
        $this->assign('prefetch', $prefetch);
958
        $this->assign('text_direction', api_get_text_direction());
959
        $this->assign('section_name', 'section-'.$this_section);
960
961
        //Defaul root chamilo favicon
962
        $favico = '<link rel="shortcut icon" href="' . api_get_path(WEB_PATH) . 'favicon.ico" type="image/x-icon" />';
963
964
        //Added to verify if in the current Chamilo Theme exist a favicon
965
        $favicoThemeUrl = api_get_path(SYS_CSS_PATH) . 'themes/' . $this->theme . '/images/';
966
967
        //If exist pick the current chamilo theme favicon
968
        if (is_file($favicoThemeUrl . 'favicon.ico')) {
969
            $favico = '<link rel="shortcut icon" href="' . api_get_path(WEB_CSS_PATH). 'themes/' . $this->theme . '/images/favicon.ico" type="image/x-icon" />';
970
        }
971
972
        if (api_is_multiple_url_enabled()) {
973
            $access_url_id = api_get_current_access_url_id();
974
            if ($access_url_id != -1) {
975
                $url_info  = api_get_access_url($access_url_id);
976
                $url       = api_remove_trailing_slash(preg_replace('/https?:\/\//i', '', $url_info['url']));
977
                $clean_url = api_replace_dangerous_char($url);
978
                $clean_url = str_replace('/', '-', $clean_url);
979
                $clean_url .= '/';
980
                $homep           = api_get_path(REL_PATH).'home/'.$clean_url; //homep for Home Path
981
                $icon_real_homep = api_get_path(SYS_APP_PATH).'home/'.$clean_url;
982
983
                //we create the new dir for the new sites
984
                if (is_file($icon_real_homep.'favicon.ico')) {
985
                    $favico = '<link rel="shortcut icon" href="'.$homep.'favicon.ico" type="image/x-icon" />';
986
                }
987
            }
988
        }
989
990
        $this->assign('favico', $favico);
991
        $this->setHelp();
992
993
        //@todo move this in the template
994
        $rightFloatMenu = '';
995
        $iconBug = Display::return_icon('bug.png', get_lang('ReportABug'), [], ICON_SIZE_LARGE);
996
        if (api_get_setting('show_link_bug_notification') == 'true' && $this->user_is_logged_in) {
997
            $rightFloatMenu = '<div class="report">
998
		<a href="https://github.com/chamilo/chamilo-lms/wiki/How-to-report-issues" target="_blank">
999
                    '. $iconBug . '
1000
                </a>
1001
		</div>';
1002
        }
1003
1004
        if (api_get_setting('show_link_ticket_notification') == 'true' && $this->user_is_logged_in) {
1005
            // by default is project_id = 1
1006
            $iconTicket = Display::return_icon('bug.png', get_lang('Ticket'), [], ICON_SIZE_LARGE);
1007
            $courseInfo = api_get_course_info();
1008
            $courseParams = '';
1009
            if (!empty($courseInfo)) {
1010
                $courseParams = api_get_cidreq();
1011
            }
1012
            $url = api_get_path(WEB_CODE_PATH).'ticket/tickets.php?project_id=1&'.$courseParams;
1013
            $rightFloatMenu .= '<div class="report">
1014
		        <a href="'.$url.'" target="_blank">
1015
                    '. $iconTicket . '
1016
                </a>
1017
		    </div>';
1018
        }
1019
1020
        $this->assign('bug_notification', $rightFloatMenu);
1021
1022
        //$notification = returnNotificationMenu();
1023
        $this->assign('notification_menu', '');
1024
1025
        $resize = '';
1026
        if (api_get_setting('accessibility_font_resize') == 'true') {
1027
            $resize .= '<div class="resize_font">';
1028
            $resize .= '<div class="btn-group">';
1029
            $resize .= '<a title="'.get_lang('DecreaseFontSize').'" href="#" class="decrease_font btn btn-default"><em class="fa fa-font"></em></a>';
1030
            $resize .= '<a title="'.get_lang('ResetFontSize').'" href="#" class="reset_font btn btn-default"><em class="fa fa-font"></em></a>';
1031
            $resize .= '<a title="'.get_lang('IncreaseFontSize').'" href="#" class="increase_font btn btn-default"><em class="fa fa-font"></em></a>';
1032
            $resize .= '</div>';
1033
            $resize .= '</div>';
1034
        }
1035
        $this->assign('accessibility', $resize);
1036
1037
        // Preparing values for the menu
1038
1039
        // Logout link
1040
        $hideLogout = api_get_setting('hide_logout_button');
1041
        if ($hideLogout === 'true') {
1042
            $this->assign('logout_link', null);
1043
        } else {
1044
            $this->assign('logout_link', api_get_path(WEB_PATH).'index.php?logout=logout&uid='.api_get_user_id());
1045
        }
1046
1047
        //Profile link
1048
        if (api_get_setting('allow_social_tool') == 'true') {
1049
            $profile_url  = api_get_path(WEB_CODE_PATH).'social/home.php';
1050
1051
        } else {
1052
            $profile_url  = api_get_path(WEB_CODE_PATH).'auth/profile.php';
1053
1054
        }
1055
1056
        $this->assign('profile_url', $profile_url);
1057
1058
        //Message link
1059
        $message_link = null;
1060
        $message_url  = null;
1061
        if (api_get_setting('allow_message_tool') == 'true') {
1062
            $message_url  = api_get_path(WEB_CODE_PATH).'messages/inbox.php';
1063
            $message_link = '<a href="'.api_get_path(WEB_CODE_PATH).'messages/inbox.php">'.get_lang('Inbox').'</a>';
1064
        }
1065
        $this->assign('message_link', $message_link);
1066
        $this->assign('message_url', $message_url);
1067
1068
        // Certificate Link
1069
1070
        $allow = api_get_configuration_value('hide_my_certificate_link');
1071
        if ($allow === false) {
1072
            $certificateUrl = api_get_path(WEB_CODE_PATH).'gradebook/my_certificates.php';
1073
            $certificateLink = Display::url(
1074
                get_lang('MyCertificates'),
1075
                $certificateUrl
1076
            );
1077
            $this->assign('certificate_link', $certificateLink);
1078
            $this->assign('certificate_url', $certificateUrl);
1079
        }
1080
1081
        $institution = api_get_setting('Institution');
1082
        $portal_name = empty($institution) ? api_get_setting('siteName') : $institution;
1083
1084
        $this->assign('portal_name', $portal_name);
1085
1086
        //Menu
1087
        //$menu = menuArray();
1088
        $this->assign('menu', '');
1089
1090
        // Setting notifications
1091
        $count_unread_message = 0;
1092
        if (api_get_setting('allow_message_tool') == 'true') {
1093
            // get count unread message and total invitations
1094
            $count_unread_message = MessageManager::get_number_of_messages(true);
1095
        }
1096
1097
        $total_invitations = 0;
1098
        if (api_get_setting('allow_social_tool') == 'true') {
1099
            $number_of_new_messages_of_friend = SocialManager::get_message_number_invitation_by_user_id(
1100
                api_get_user_id()
1101
            );
1102
            $usergroup = new UserGroup();
1103
            $group_pending_invitations = $usergroup->get_groups_by_user(
1104
                api_get_user_id(),
1105
                GROUP_USER_PERMISSION_PENDING_INVITATION,
1106
                false
1107
            );
1108
            if (!empty($group_pending_invitations)) {
1109
                $group_pending_invitations = count($group_pending_invitations);
1110
            } else {
1111
                $group_pending_invitations = 0;
1112
            }
1113
            $total_invitations = intval($number_of_new_messages_of_friend) + $group_pending_invitations + intval($count_unread_message);
1114
        }
1115
        $total_invitations = (!empty($total_invitations) ? Display::badge($total_invitations) : null);
1116
1117
        $this->assign('user_notifications', $total_invitations);
1118
1119
1120
        // Block Breadcrumb
1121
        //$breadcrumb = return_breadcrumb($interbreadcrumb, $language_file, $nameTools);
1122
        $breadcrumb  = '';
1123
        $this->assign('breadcrumb', $breadcrumb);
1124
1125
        //Extra content
1126
        $extra_header = null;
1127
        if (!api_is_platform_admin()) {
1128
            $extra_header = trim(api_get_setting('header_extra_content'));
1129
        }
1130
        $this->assign('header_extra_content', $extra_header);
1131
1132
        if ($sendHeaders) {
1133
            header('Content-Type: text/html; charset='.api_get_system_encoding());
1134
            header(
1135
                'X-Powered-By: '.$_configuration['software_name'].' '.substr($_configuration['system_version'], 0, 1)
1136
            );
1137
        }
1138
1139
        $socialMeta = '';
1140
        $metaTitle = api_get_setting('meta_title');
1141
        if (!empty($metaTitle)) {
1142
            $socialMeta .= '<meta name="twitter:card" content="summary" />' . "\n";
1143
            $metaSite = api_get_setting('meta_twitter_site');
1144
            if (!empty($metaSite)) {
1145
                $socialMeta .= '<meta name="twitter:site" content="' . $metaSite . '" />' . "\n";
1146
                $metaCreator = api_get_setting('meta_twitter_creator');
1147
                if (!empty($metaCreator)) {
1148
                    $socialMeta .= '<meta name="twitter:creator" content="' . $metaCreator . '" />' . "\n";
1149
                }
1150
            }
1151
1152
            // The user badge page emits its own meta tags, so if this is
1153
            // enabled, ignore the global ones
1154
            $userId = isset($_GET['user']) ? intval($_GET['user']) : 0;
1155
            $skillId = isset($_GET['skill']) ? intval($_GET['skill']) : 0;
1156
1157
            if (!$userId && !$skillId) {
1158
                // no combination of user and skill ID has been defined,
1159
                // so print the normal OpenGraph meta tags
1160
                $socialMeta .= '<meta property="og:title" content="' . $metaTitle . '" />' . "\n";
1161
                $socialMeta .= '<meta property="og:url" content="' . api_get_path(WEB_PATH) . '" />' . "\n";
1162
1163
                $metaDescription = api_get_setting('meta_description');
1164
                if (!empty($metaDescription)) {
1165
                    $socialMeta .= '<meta property="og:description" content="' . $metaDescription . '" />' . "\n";
1166
                }
1167
1168
                $metaImage = api_get_setting('meta_image_path');
1169
                if (!empty($metaImage)) {
1170
                    if (is_file(api_get_path(SYS_PATH) . $metaImage)) {
1171
                        $path = api_get_path(WEB_PATH) . $metaImage;
1172
                        $socialMeta .= '<meta property="og:image" content="' . $path . '" />' . "\n";
1173
                    }
1174
                }
1175
            }
1176
        }
1177
1178
        $this->assign('social_meta', $socialMeta);
1179
    }
1180
1181
    /**
1182
     * Set footer parameters
1183
     */
1184
    private function set_footer_parameters()
1185
    {
1186
        if (api_get_setting('show_administrator_data') === 'true') {
1187
            $firstName = api_get_setting('administratorName');
1188
            $lastName = api_get_setting('administratorSurname');
1189
1190
            if (!empty($firstName) && !empty($lastName)) {
1191
                $name = api_get_person_name($firstName, $lastName);
1192
            } else {
1193
                $name = $lastName;
1194
                if (empty($lastName)) {
1195
                    $name = $firstName;
1196
                }
1197
            }
1198
1199
            $adminName = '';
1200
            // Administrator name
1201
            if (!empty($name)) {
1202
                $adminName = get_lang('Manager').' : '.
1203
                    Display::encrypted_mailto_link(
1204
                        api_get_setting('emailAdministrator'),
1205
                        $name
1206
                    );
1207
            }
1208
            $this->assign('administrator_name', $adminName);
1209
        }
1210
1211
        // Loading footer extra content
1212
        if (!api_is_platform_admin()) {
1213
            $extra_footer = trim(api_get_setting('footer_extra_content'));
1214
            if (!empty($extra_footer)) {
1215
                $this->assign('footer_extra_content', $extra_footer);
1216
            }
1217
        }
1218
1219
        // Tutor name
1220
        if (api_get_setting('show_tutor_data') == 'true') {
1221
            // Course manager
1222
            $courseId = api_get_course_int_id();
1223
            $id_session = api_get_session_id();
1224
            if (!empty($courseId)) {
1225
                $tutor_data = '';
1226
                if ($id_session != 0) {
1227
                    $coachs_email = CourseManager::get_email_of_tutor_to_session(
1228
                        $id_session,
1229
                        $courseId
1230
                    );
1231
                    $email_link = array();
1232
                    foreach ($coachs_email as $coach) {
1233
                        $email_link[] = Display::encrypted_mailto_link($coach['email'], $coach['complete_name']);
1234
                    }
1235
                    if (count($coachs_email) > 1) {
1236
                        $tutor_data .= get_lang('Coachs').' : ';
1237
                        $tutor_data .= array_to_string($email_link, CourseManager::USER_SEPARATOR);
1238
                    } elseif (count($coachs_email) == 1) {
1239
                        $tutor_data .= get_lang('Coach').' : ';
1240
                        $tutor_data .= array_to_string($email_link, CourseManager::USER_SEPARATOR);
1241
                    } elseif (count($coachs_email) == 0) {
1242
                        $tutor_data .= '';
1243
                    }
1244
                }
1245
                $this->assign('session_teachers', $tutor_data);
1246
            }
1247
        }
1248
1249
        if (api_get_setting('show_teacher_data') == 'true') {
1250
            // course manager
1251
            $courseId = api_get_course_int_id();
1252
            if (!empty($courseId)) {
1253
                $teacher_data = '';
1254
                $mail = CourseManager::get_emails_of_tutors_to_course($courseId);
1255
                if (!empty($mail)) {
1256
                    $teachers_parsed = array();
1257
                    foreach ($mail as $value) {
1258
                        foreach ($value as $email => $name) {
1259
                            $teachers_parsed[] = Display::encrypted_mailto_link($email, $name);
1260
                        }
1261
                    }
1262
                    $label = get_lang('Teacher');
1263
                    if (count($mail) > 1) {
1264
                        $label = get_lang('Teachers');
1265
                    }
1266
                    $teacher_data .= $label.' : '.array_to_string($teachers_parsed, CourseManager::USER_SEPARATOR);
1267
                }
1268
                $this->assign('teachers', $teacher_data);
1269
            }
1270
        }
1271
    }
1272
1273
    /**
1274
     * Show footer js template.
1275
     */
1276
    public function show_footer_js_template()
1277
    {
1278
        $tpl = $this->get_template('layout/footer.js.tpl');
1279
        $this->display($tpl);
1280
    }
1281
1282
    /**
1283
     * Sets the plugin content in a template variable
1284
     * @param string $pluginRegion
1285
     * @return null
1286
     */
1287
    public function set_plugin_region($pluginRegion)
1288
    {
1289
        if (!empty($pluginRegion)) {
1290
            $regionContent = $this->plugin->load_region($pluginRegion, $this, $this->force_plugin_load);
1291
1292
            $pluginList = $this->plugin->get_installed_plugins();
1293 View Code Duplication
            foreach ($pluginList as $plugin_name) {
1294
1295
                // The plugin_info variable is available inside the plugin index
1296
                $pluginInfo = $this->plugin->getPluginInfo($plugin_name);
1297
1298
                if (isset($pluginInfo['is_course_plugin']) && $pluginInfo['is_course_plugin']) {
1299
                    $courseInfo = api_get_course_info();
1300
1301
                    if (!empty($courseInfo)) {
1302
                        if (isset($pluginInfo['obj']) && $pluginInfo['obj'] instanceof Plugin) {
1303
                            /** @var Plugin $plugin */
1304
                            $plugin = $pluginInfo['obj'];
1305
                            $regionContent .= $plugin->renderRegion($pluginRegion);
1306
                        }
1307
                    }
1308
                } else {
1309
                    continue;
1310
                }
1311
            }
1312
1313
            if (!empty($regionContent)) {
1314
                $this->assign('plugin_'.$pluginRegion, $regionContent);
1315
            } else {
1316
                $this->assign('plugin_'.$pluginRegion, null);
1317
            }
1318
        }
1319
        return null;
1320
    }
1321
1322
    /**
1323
     * @param string $template
1324
     * @return string
1325
     */
1326
    public function fetch($template = null)
1327
    {
1328
        $template = str_replace('.tpl', '.html.twig', $template);
1329
        $template = \Chamilo\CoreBundle\Framework\Container::getTwig()->load($template);
1330
        return $template->render(self::$params);
1331
    }
1332
1333
    /**
1334
     * @param string $variable
1335
     * @param mixed $value
1336
     */
1337
    public function assign($variable, $value = '')
1338
    {
1339
        self::$params[$variable] = $value;
1340
    }
1341
1342
    /**
1343
     * Adds a body class for login pages
1344
     */
1345
    public function setLoginBodyClass()
1346
    {
1347
        $this->assign('login_class', 'section-login');
1348
    }
1349
1350
    /**
1351
     * The theme that will be used if the database is not working.
1352
     * @return string
1353
     */
1354
    public static function getThemeFallback()
1355
    {
1356
        $theme = api_get_configuration_value('theme_fallback');
1357
        if (empty($theme)) {
1358
            $theme = 'chamilo';
1359
        }
1360
        return $theme;
1361
    }
1362
1363
    /**
1364
     * @param bool|true $setLoginForm
1365
     */
1366
    public function setLoginForm($setLoginForm = true)
1367
    {
1368
        global $loginFailed;
1369
        $userId = api_get_user_id();
1370
        if (!($userId) || api_is_anonymous($userId)) {
1371
            // Only display if the user isn't logged in.
1372
            $this->assign(
1373
                'login_language_form',
1374
                api_display_language_form(true)
1375
            );
1376
            if ($setLoginForm) {
1377
                $this->assign('login_form', $this->displayLoginForm());
1378
1379
                if ($loginFailed) {
1380
                    $this->assign('login_failed', $this::handleLoginFailed());
1381
                }
1382
            }
1383
        }
1384
    }
1385
1386
    /**
1387
     * @return string
1388
     */
1389
    public function handleLoginFailed()
1390
    {
1391
        $message = get_lang('InvalidId');
1392
1393
        if (!isset($_GET['error'])) {
1394
            if (api_is_self_registration_allowed()) {
1395
                $message = get_lang('InvalidForSelfRegistration');
1396
            }
1397
        } else {
1398
            switch ($_GET['error']) {
1399
                case '':
1400
                    if (api_is_self_registration_allowed()) {
1401
                        $message = get_lang('InvalidForSelfRegistration');
1402
                    }
1403
                    break;
1404
                case 'account_expired':
1405
                    $message = get_lang('AccountExpired');
1406
                    break;
1407
                case 'account_inactive':
1408
                    $message = get_lang('AccountInactive');
1409
                    break;
1410
                case 'user_password_incorrect':
1411
                    $message = get_lang('InvalidId');
1412
                    break;
1413
                case 'access_url_inactive':
1414
                    $message = get_lang('AccountURLInactive');
1415
                    break;
1416
                case 'wrong_captcha':
1417
                    $message = get_lang('TheTextYouEnteredDoesNotMatchThePicture');
1418
                    break;
1419
                case 'blocked_by_captcha':
1420
                    $message = get_lang('AccountBlockedByCaptcha');
1421
                    break;
1422
                case 'multiple_connection_not_allowed':
1423
                    $message = get_lang('MultipleConnectionsAreNotAllow');
1424
                    break;
1425
                case 'unrecognize_sso_origin':
1426
                    //$message = get_lang('SSOError');
1427
                    break;
1428
            }
1429
        }
1430
        return Display::return_message($message, 'error');
1431
    }
1432
1433
    /**
1434
     * @return string
1435
     */
1436
    public function displayLoginForm()
1437
    {
1438
        $form = new FormValidator(
1439
            'formLogin',
1440
            'POST',
1441
            null,
1442
            null,
1443
            null,
1444
            FormValidator::LAYOUT_BOX_NO_LABEL
1445
        );
1446
1447
        $form->addText(
1448
            'login',
1449
            get_lang('UserName'),
1450
            true,
1451
            array(
1452
                'id' => 'login',
1453
                'autofocus' => 'autofocus',
1454
                'icon' => 'user fa-fw',
1455
                'placeholder' => get_lang('UserName'),
1456
                'autocapitalize' => 'none'
1457
            )
1458
        );
1459
1460
        $form->addElement(
1461
            'password',
1462
            'password',
1463
            get_lang('Pass'),
1464
            array(
1465
                'id' => 'password',
1466
                'icon' => 'lock fa-fw',
1467
                'placeholder' => get_lang('Pass'),
1468
                'autocapitalize' => 'none',
1469
            )
1470
        );
1471
1472
        // Captcha
1473
        $captcha = api_get_setting('allow_captcha');
1474
        $allowCaptcha = $captcha === 'true';
1475
1476
        if ($allowCaptcha) {
1477
            $useCaptcha = isset($_SESSION['loginFailed']) ? $_SESSION['loginFailed'] : null;
1478
            if ($useCaptcha) {
1479
                $ajax = api_get_path(WEB_AJAX_PATH).'form.ajax.php?a=get_captcha';
1480
                $options = array(
1481
                    'width' => 250,
1482
                    'height' => 90,
1483
                    'callback'     => $ajax.'&var='.basename(__FILE__, '.php'),
1484
                    'sessionVar'   => basename(__FILE__, '.php'),
1485
                    'imageOptions' => array(
1486
                        'font_size' => 20,
1487
                        'font_path' => api_get_path(SYS_FONTS_PATH) . 'opensans/',
1488
                        'font_file' => 'OpenSans-Regular.ttf',
1489
                        //'output' => 'gif'
1490
                    )
1491
                );
1492
1493
                // Minimum options using all defaults (including defaults for Image_Text):
1494
                //$options = array('callback' => 'qfcaptcha_image.php');
1495
1496
                $captcha_question = $form->addElement('CAPTCHA_Image', 'captcha_question', '', $options);
1497
                $form->addHtml(get_lang('ClickOnTheImageForANewOne'));
1498
1499
                $form->addElement('text', 'captcha', get_lang('EnterTheLettersYouSee'));
1500
                $form->addRule('captcha', get_lang('EnterTheCharactersYouReadInTheImage'), 'required', null, 'client');
1501
                $form->addRule('captcha', get_lang('TheTextYouEnteredDoesNotMatchThePicture'), 'CAPTCHA', $captcha_question);
1502
            }
1503
        }
1504
1505
        $form->addButton('submitAuth', get_lang('LoginEnter'), null, 'primary', null, 'btn-block');
1506
1507
        $html = $form->returnForm();
1508
        if (api_get_setting('openid_authentication') == 'true') {
1509
            include_once 'main/auth/openid/login.php';
1510
            $html .= '<div>'.openid_form().'</div>';
1511
        }
1512
1513
        return $html;
1514
    }
1515
1516
    /**
1517
     * Set administrator variables
1518
     */
1519
    private function setAdministratorParams()
1520
    {
1521
        $_admin = [
1522
            'email' => api_get_setting('emailAdministrator'),
1523
            'surname' => api_get_setting('administratorSurname'),
1524
            'name' => api_get_setting('administratorName'),
1525
            'telephone' => api_get_setting('administratorTelephone')
1526
        ];
1527
1528
        $this->assign('_admin', $_admin);
1529
    }
1530
1531
    /**
1532
     * Manage specific HTTP headers security
1533
     * @return void (prints headers directly)
1534
     */
1535
    private function addHTTPSecurityHeaders()
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
1536
    {
1537
        // Implementation of HTTP headers security, as suggested and checked
1538
        // by https://securityheaders.io/
1539
        // Enable these settings in configuration.php to use them on your site
1540
        // Strict-Transport-Security
1541
        $setting = api_get_configuration_value('security_strict_transport');
1542
        if (!empty($setting)) {
1543
            header('Strict-Transport-Security: '.$setting);
1544
        }
1545
        // Content-Security-Policy
1546
        $setting = api_get_configuration_value('security_content_policy');
1547
        if (!empty($setting)) {
1548
            header('Content-Security-Policy: '.$setting);
1549
        }
1550
        $setting = api_get_configuration_value('security_content_policy_report_only');
1551
        if (!empty($setting)) {
1552
            header('Content-Security-Policy-Report-Only: '.$setting);
1553
        }
1554
        // Public-Key-Pins
1555
        $setting = api_get_configuration_value('security_public_key_pins');
1556
        if (!empty($setting)) {
1557
            header('Public-Key-Pins: '.$setting);
1558
        }
1559
        $setting = api_get_configuration_value('security_public_key_pins_report_only');
1560
        if (!empty($setting)) {
1561
            header('Public-Key-Pins-Report-Only: '.$setting);
1562
        }
1563
        // X-Frame-Options
1564
        $setting = api_get_configuration_value('security_x_frame_options');
1565
        if (!empty($setting)) {
1566
            header('X-Frame-Options: '.$setting);
1567
        }
1568
        // X-XSS-Protection
1569
        $setting = api_get_configuration_value('security_xss_protection');
1570
        if (!empty($setting)) {
1571
            header('X-XSS-Protection: '.$setting);
1572
        }
1573
        // X-Content-Type-Options
1574
        $setting = api_get_configuration_value('security_x_content_type_options');
1575
        if (!empty($setting)) {
1576
            header('X-Content-Type-Options: '.$setting);
1577
        }
1578
        // Referrer-Policy
1579
        $setting = api_get_configuration_value('security_referrer_policy');
1580
        if (!empty($setting)) {
1581
            header('Referrer-Policy: '.$setting);
1582
        }
1583
        // end of HTTP headers security block
1584
    }
1585
1586
    public static function getParams()
1587
    {
1588
        return self::$params;
1589
    }
1590
}
1591