Completed
Push — master ( f7178d...176486 )
by Julito
37:24
created

Template::display()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 2
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * Class Template
6
 *
7
 * @author Julio Montoya <[email protected]>
8
 *
9
 *
10
 * In Chamilo 2 files inside main/ (classic chamilo files) are
11
 * wrapped by a Symfony2 controller LegacyController::classicAction
12
 * This controller will handle the breadcrumb, the template rendering
13
 * and everything as a normal Symfony2 action.
14
 *
15
 * Example:
16
 * Chamilo 1.x
17
 * my.chamilo.net/main/admin/user_list.php
18
 *
19
 * Chamilo 2.x
20
 * (dev mode)
21
 * my.chamilo.net/web/app_dev.php/main/admin/user_list.php
22
 * (prod mod)
23
 * my.chamilo.net/web/main/admin/user_list.php
24
 *
25
 *
26
 */
27
class Template
28
{
29
    /**
30
     * The Template folder name see main/template
31
     * @var string
32
     */
33
    public $templateFolder = 'default';
34
35
    /**
36
     * The theme that will be used: chamilo, public_admin, chamilo_red, etc
37
     * This variable is set from the database
38
     * @var string
39
     */
40
    public $theme = '';
41
42
    /**
43
     * @var string
44
     */
45
    public $preview_theme = '';
46
    public $title = null;
47
    public $show_header;
48
    public $show_footer;
49
    public $help;
50
    public $menu_navigation = array(); //Used in the userportal.lib.php function: return_navigation_course_links()
51
    public $show_learnpath = false; // This is a learnpath section or not?
52
    public $plugin = null;
53
    public $course_id = null;
54
    public $user_is_logged_in = false;
55
    public $twig = null;
56
57
    /* Loads chamilo plugins */
58
    public $load_plugins = false;
59
    public $params = array();
60
    public $force_plugin_load = false;
61
62
    /**
63
     * @param string $title
64
     * @param bool $show_header
65
     * @param bool $show_footer
66
     * @param bool $show_learnpath
67
     * @param bool $hide_global_chat
68
     * @param bool $load_plugins
69
     * @param bool $sendHeaders send http headers or not
70
     */
71
    public function __construct(
72
        $title = '',
73
        $show_header = true,
74
        $show_footer = true,
75
        $show_learnpath = false,
76
        $hide_global_chat = false,
77
        $load_plugins = true,
78
        $sendHeaders = true
79
    ) {
80
81
        return;
82
        // Page title
83
        $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...
84
85
        $this->show_learnpath = $show_learnpath;
86
87
        if (empty($this->show_learnpath)) {
88
            $origin = api_get_origin();
89
            if ($origin === 'learnpath') {
90
                $this->show_learnpath = true;
91
                $show_footer = false;
92
                $show_header = false;
93
            }
94
        }
95
        $this->hide_global_chat = $hide_global_chat;
96
        $this->load_plugins = $load_plugins;
97
98
        $template_paths = array(
99
            api_get_path(SYS_CODE_PATH).'template/overrides', // user defined templates
100
            api_get_path(SYS_CODE_PATH).'template', //template folder
101
            api_get_path(SYS_PLUGIN_PATH) // plugin folder
102
        );
103
104
        $urlId = api_get_current_access_url_id();
105
106
        $cache_folder = api_get_path(SYS_ARCHIVE_PATH).'twig/'.$urlId.'/';
107
108
        if (!is_dir($cache_folder)) {
109
            mkdir($cache_folder, api_get_permissions_for_new_directories(), true);
110
        }
111
112
        $loader = new Twig_Loader_Filesystem($template_paths);
113
114
        //Setting Twig options depending on the server see http://twig.sensiolabs.org/doc/api.html#environment-options
115
        if (api_get_setting('server_type') == 'test') {
116
            $options = array(
117
                //'cache' => api_get_path(SYS_ARCHIVE_PATH), //path to the cache folder
118
                'autoescape' => false,
119
                'debug' => true,
120
                'auto_reload' => true,
121
                'optimizations' => 0,
122
                // turn on optimizations with -1
123
                'strict_variables' => false,
124
                //If set to false, Twig will silently ignore invalid variables
125
            );
126
        } else {
127
            $options = array(
128
                'cache' => $cache_folder,
129
                //path to the cache folder
130
                'autoescape' => false,
131
                'debug' => false,
132
                'auto_reload' => false,
133
                'optimizations' => -1,
134
                // turn on optimizations with -1
135
                'strict_variables' => false
136
                //If set to false, Twig will silently ignore invalid variables
137
            );
138
        }
139
140
        $this->twig = new Twig_Environment($loader, $options);
141
142
        $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...
143
        $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...
144
        $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...
145
        $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...
146
        $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...
147
        //$this->twig->addFilter('return_logo', new Twig_Filter_Function('return_logo'));
148
        $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...
149
        $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...
150
        $this->twig->addFilter(
151
            'display_page_subheader',
152
            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...
153
        );
154
        $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...
155
        $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...
156
        $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...
157
        $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...
158
159
        /*
160
          $lexer = new Twig_Lexer($this->twig, array(
161
          //'tag_comment'  => array('{*', '*}'),
162
          //'tag_comment'  => array('{#', '#}'),
163
          //'tag_block'    => array('{', '}'),
164
          //'tag_variable' => array('{$', '}'),
165
          ));
166
          $this->twig->setLexer($lexer); */
167
168
        //Setting system variables
169
        $this->set_system_parameters();
170
171
        //Setting user variables
172
        $this->set_user_parameters();
173
174
        //Setting course variables
175
        $this->set_course_parameters();
176
177
        //Setting administrator variables
178
        $this->setAdministratorParams();
179
180
        $this->setCSSEditor();
181
182
        //header and footer are showed by default
183
        $this->set_footer($show_footer);
184
        $this->set_header($show_header);
185
186
        $this->set_header_parameters($sendHeaders);
187
        $this->set_footer_parameters();
188
189
        $defaultStyle = api_get_configuration_value('default_template');
190
        if (!empty($defaultStyle)) {
191
            $this->templateFolder = $defaultStyle;
192
        }
193
194
        $this->assign('template', $this->templateFolder);
195
        $this->assign('locale', api_get_language_isocode());
196
197
        $this->assign('css_styles', $this->theme);
198
        $this->assign('login_class', null);
199
200
        $this->setLoginForm();
201
202
        // Chamilo plugins
203
        if ($this->show_header) {
204
            if ($this->load_plugins) {
205
206
                $this->plugin = new AppPlugin();
207
208
                //1. Showing installed plugins in regions
209
                $pluginRegions = $this->plugin->get_plugin_regions();
210
                foreach ($pluginRegions as $region) {
211
                    $this->set_plugin_region($region);
212
                }
213
214
                //2. Loading the course plugin info
215
                global $course_plugin;
216
                if (isset($course_plugin) && !empty($course_plugin) && !empty($this->course_id)) {
217
                    //Load plugin get_langs
218
                    $this->plugin->load_plugin_lang_variables($course_plugin);
219
                }
220
            }
221
        }
222
    }
223
224
    /**
225
     * @param string $image
226
     * @param int $size
227
     *
228
     * @return string
229
     */
230
    public static function get_icon_path($image, $size = ICON_SIZE_SMALL)
231
    {
232
        return Display::return_icon($image, '', array(), $size, false, true);
233
    }
234
235
    /**
236
     * @param string $image
237
     * @param int $size
238
     * @param string $name
239
     * @return string
240
     */
241
    public static function get_image($image, $size = ICON_SIZE_SMALL, $name)
242
    {
243
        return Display::return_icon($image, $name, array(), $size);
244
    }
245
246
    /**
247
     * @param string $timestamp
248
     * @param string $format
249
     *
250
     * @return string
251
     */
252
    public static function format_date($timestamp, $format = null)
253
    {
254
        return api_format_date($timestamp, $format);
255
    }
256
257
    /**
258
     * Return the item's url key:
259
     *
260
     *      c_id=xx&id=xx
261
     *
262
     * @param object $item
263
     * @return string
264
     */
265
    public static function key($item)
266
    {
267
        $id     = isset($item->id) ? $item->id : null;
268
        $c_id   = isset($item->c_id) ? $item->c_id : null;
269
        $result = '';
270
        if ($c_id) {
271
            $result = "c_id=$c_id";
272
        }
273
        if ($id) {
274
            if ($result) {
275
                $result .= "&amp;id=$id";
276
            } else {
277
                $result .= "&amp;id=$id";
278
            }
279
        }
280
        return $result;
281
    }
282
283
    /**
284
     * @param string $helpInput
285
     */
286
    public function setHelp($helpInput = null)
287
    {
288
        if (!empty($helpInput)) {
289
            $help = $helpInput;
290
        } else {
291
            $help = $this->help;
292
        }
293
294
        $content = '';
295
        if (api_get_setting('enable_help_link') == 'true') {
296
            if (!empty($help)) {
297
                $help = Security::remove_XSS($help);
298
                $content = '<div class="help">';
299
                $content .= Display::url(
300
                    Display::return_icon('help.large.png', get_lang('Help')),
301
                    api_get_path(WEB_CODE_PATH) . 'help/help.php?open=' . $help,
302
                    [
303
                        'class' => 'ajax',
304
                        'data-title' => get_lang('Help')
305
                    ]
306
                );
307
                $content .= '</div>';
308
            }
309
        }
310
        $this->assign('help_content', $content);
311
    }
312
313
    /**
314
     * Use template system to parse the actions menu
315
     * @todo finish it!
316
     **/
317
    public function set_actions($actions)
318
    {
319
        $action_string = '';
320
        if (!empty($actions)) {
321
            foreach ($actions as $action) {
322
                $action_string .= $action;
323
            }
324
        }
325
        $this->assign('actions', $actions);
326
    }
327
328
    /**
329
     * Shortcut to display a 1 col layout (index.php)
330
     * */
331
    public function display_one_col_template()
332
    {
333
        $tpl = $this->get_template('layout/layout_1_col.tpl');
334
        $this->display($tpl);
335
    }
336
337
    /**
338
     * Shortcut to display a 2 col layout (userportal.php)
339
     **/
340
    public function display_two_col_template()
341
    {
342
        $tpl = $this->get_template('layout/layout_2_col.tpl');
343
        $this->display($tpl);
344
    }
345
346
    /**
347
     * Displays an empty template
348
     */
349
    public function display_blank_template()
350
    {
351
        $tpl = $this->get_template('layout/blank.tpl');
352
        $this->display($tpl);
353
    }
354
355
    /**
356
     * Displays an empty template
357
     */
358
    public function display_no_layout_template()
359
    {
360
        $tpl = $this->get_template('layout/no_layout.tpl');
361
        $this->display($tpl);
362
    }
363
364
    /**
365
     * Sets the footer visibility
366
     * @param bool true if we show the footer
367
     */
368
    public function set_footer($status)
369
    {
370
        $this->show_footer = $status;
371
        $this->assign('show_footer', $status);
372
    }
373
374
    /**
375
     * return true if toolbar has to be displayed for user
376
     * @return bool
377
     */
378
    public static function isToolBarDisplayedForUser()
379
    {
380
        //Toolbar
381
        $show_admin_toolbar = api_get_setting('show_admin_toolbar');
382
        $show_toolbar = false;
383
384
        switch ($show_admin_toolbar) {
385
            case 'do_not_show':
386
                break;
387
            case 'show_to_admin':
388
                if (api_is_platform_admin()) {
389
                    $show_toolbar = true;
390
                }
391
                break;
392
            case 'show_to_admin_and_teachers':
393
                if (api_is_platform_admin() || api_is_allowed_to_edit()) {
394
                    $show_toolbar = true;
395
                }
396
                break;
397
            case 'show_to_all':
398
                $show_toolbar = true;
399
                break;
400
        }
401
        return $show_toolbar;
402
    }
403
404
    /**
405
     * Sets the header visibility
406
     * @param bool true if we show the header
407
     */
408
    public function set_header($status)
409
    {
410
        $this->show_header = $status;
411
        $this->assign('show_header', $status);
412
413
        $show_toolbar = 0;
414
415
        if (self::isToolBarDisplayedForUser()) {
416
            $show_toolbar = 1;
417
        }
418
419
        $this->assign('show_toolbar', $show_toolbar);
420
421
        //Only if course is available
422
        $show_course_shortcut        = null;
423
        $show_course_navigation_menu = null;
424
425
        if (!empty($this->course_id) && $this->user_is_logged_in) {
426
            if (api_get_setting('show_toolshortcuts') != 'false') {
427
                //Course toolbar
428
                $show_course_shortcut = CourseHome::show_navigation_tool_shortcuts();
429
            }
430
            if (api_get_setting('show_navigation_menu') != 'false') {
431
                //Course toolbar
432
                $show_course_navigation_menu = CourseHome::show_navigation_menu();
433
            }
434
        }
435
        $this->assign('show_course_shortcut', $show_course_shortcut);
436
        $this->assign('show_course_navigation_menu', $show_course_navigation_menu);
437
    }
438
439
    /**
440
     * @param string $name
441
     *
442
     * @return string
443
     */
444
    public function get_template($name)
445
    {
446
        if ($name == 'layout/layout_1_col.tpl') {
447
            $name = 'layout/layout_1_col.html.twig';
448
        }
449
450
        if ($name == 'layout/layout_2_col.tpl') {
451
            $name = 'layout/layout_2_col.html.twig';
452
        }
453
454
        /**
455
         * In Chamilo 1.x we use the tpl extension.
456
         * In Chamilo 2.x we use twig but using the Symfony2 bridge
457
         * In order to don't change all legacy main calls we just replace
458
         * tpl with html.twig (the new template location should be:
459
         * (src/Chamilo/CoreBundle/Resources/views/default/layout)
460
         */
461
        $name = str_replace('.tpl', '.html.twig');
462
        return $this->templateFolder.'/'.$name;
463
    }
464
465
    /**
466
     * Set course parameters
467
     */
468
    private function set_course_parameters()
469
    {
470
        //Setting course id
471
        $course = api_get_course_info();
472
        if (empty($course)) {
473
            $this->assign('course_is_set', false);
474
            return;
475
        }
476
        $this->assign('course_is_set', true);
477
        $this->course_id = $course['id'];
478
        $_c = array(
479
            'id' => $course['id'],
480
            'code' => $course['code'],
481
            'title' => $course['name'],
482
            'visibility' => $course['visibility'],
483
            'language' => $course['language'],
484
            'directory' => $course['directory'],
485
            'session_id' => api_get_session_id(),
486
            'user_is_teacher' => api_is_course_admin(),
487
            'student_view' => (!empty($_GET['isStudentView']) && $_GET['isStudentView'] == 'true'),
488
        );
489
        $this->assign('course_code', $course['code']);
490
        $this->assign('_c', $_c);
491
    }
492
493
    /**
494
     * Set user parameters
495
     */
496
    private function set_user_parameters()
497
    {
498
        $user_info = array();
499
        $user_info['logged'] = 0;
500
        $this->user_is_logged_in = false;
501
        if (api_user_is_login()) {
502
            $user_info = api_get_user_info(api_get_user_id(), true);
503
            $user_info['logged'] = 1;
504
505
            $user_info['is_admin'] = 0;
506
            if (api_is_platform_admin()) {
507
                $user_info['is_admin'] = 1;
508
            }
509
510
            $user_info['messages_count'] = MessageManager::get_new_messages();
511
            $this->user_is_logged_in = true;
512
        }
513
        // Setting the $_u array that could be use in any template
514
        $this->assign('_u', $user_info);
515
    }
516
517
    /**
518
     * Set system parameters
519
     */
520
    private function set_system_parameters()
521
    {
522
        global $_configuration;
523
        $this->theme = api_get_visual_theme();
524
        //Setting app paths/URLs
525
        $_p = array(
526
            'web' => api_get_path(WEB_PATH),
527
            'web_relative' => api_get_path(REL_PATH),
528
            'web_course' => api_get_path(WEB_COURSE_PATH),
529
            'web_main' => api_get_path(WEB_CODE_PATH),
530
            'web_css' => api_get_path(WEB_CSS_PATH),
531
            'web_css_theme' => api_get_path(WEB_CSS_PATH) . 'themes/' . $this->theme . '/',
532
            'web_ajax' => api_get_path(WEB_AJAX_PATH),
533
            'web_img' => api_get_path(WEB_IMG_PATH),
534
            'web_plugin' => api_get_path(WEB_PLUGIN_PATH),
535
            'web_lib' => api_get_path(WEB_LIBRARY_PATH),
536
            'web_upload' => api_get_path(WEB_UPLOAD_PATH),
537
            'web_self' => api_get_self(),
538
            'web_query_vars' => api_htmlentities($_SERVER['QUERY_STRING']),
539
            'web_self_query_vars' => api_htmlentities($_SERVER['REQUEST_URI']),
540
            'web_cid_query' => api_get_cidreq(),
541
        );
542
        $this->assign('_p', $_p);
543
544
        //Here we can add system parameters that can be use in any template
545
        $_s = array(
546
            'software_name' => $_configuration['software_name'],
547
            'system_version' => $_configuration['system_version'],
548
            'site_name' => api_get_setting('siteName'),
549
            'institution' => api_get_setting('Institution'),
550
            'date' => api_format_date('now', DATE_FORMAT_LONG),
551
            'timezone' => api_get_timezone(),
552
            'gamification_mode' => api_get_setting('gamification_mode')
553
        );
554
        $this->assign('_s', $_s);
555
    }
556
557
    /**
558
     * Set legacy twig globals in order to be hook in the LegacyListener.php
559
     * @return array
560
     */
561
    public static function getGlobals()
562
    {
563
        $_p = array(
564
            'web' => api_get_path(WEB_PATH),
565
            'web_relative' => api_get_path(REL_PATH),
566
            'web_course' => api_get_path(WEB_COURSE_PATH),
567
            'web_main' => api_get_path(WEB_CODE_PATH),
568
            'web_css' => api_get_path(WEB_CSS_PATH),
569
            //'web_css_theme' => api_get_path(WEB_CSS_PATH) . 'themes/' . $this->theme . '/',
570
            'web_ajax' => api_get_path(WEB_AJAX_PATH),
571
            'web_img' => api_get_path(WEB_IMG_PATH),
572
            'web_plugin' => api_get_path(WEB_PLUGIN_PATH),
573
            'web_lib' => api_get_path(WEB_LIBRARY_PATH),
574
            'web_upload' => api_get_path(WEB_UPLOAD_PATH),
575
            'web_self' => api_get_self(),
576
            'web_query_vars' => api_htmlentities($_SERVER['QUERY_STRING']),
577
            'web_self_query_vars' => api_htmlentities($_SERVER['REQUEST_URI']),
578
            'web_cid_query' => api_get_cidreq(),
579
        );
580
581
        $_s = array(
582
            'software_name' => api_get_configuration_value('software_name'),
583
            'system_version' => api_get_configuration_value('system_version'),
584
            'site_name' => api_get_setting('siteName'),
585
            'institution' => api_get_setting('Institution'),
586
            'date' => api_format_date('now', DATE_FORMAT_LONG),
587
            'timezone' => api_get_timezone(),
588
            'gamification_mode' => api_get_setting('gamification_mode')
589
        );
590
591
        $user_info = array();
592
        $user_info['logged'] = 0;
593
        //$this->user_is_logged_in = false;
594
        if (api_user_is_login()) {
595
            $user_info = api_get_user_info(api_get_user_id(), true);
596
            $user_info['logged'] = 1;
597
            $user_info['is_admin'] = 0;
598
            /*if (api_is_platform_admin()) {
599
                $user_info['is_admin'] = 1;
600
            }*/
601
            //$user_info['messages_count'] = MessageManager::get_new_messages();
602
603
        }
604
605
        return [
606
            '_p' => $_p,
607
            '_s' => $_s,
608
            '_u' => $user_info,
609
            'plugin_main_top' => '',
610
            'plugin_content_top' => '',
611
            'plugin_content_bottom' => '',
612
            'plugin_main_bottom' => '',
613
            'plugin_main_top' => '',
614
            'breadcrumb' => '',
615
            'plugin_main_top' => '',
616
            'plugin_main_top' => '',
617
            'plugin_main_top' => '',
618
            'plugin_main_top' => '',
619
            'template' => 'default' // @todo setup template folder in config.yml;
620
        ];
621
    }
622
623
    /**
624
     * Set theme, include mainstream CSS files
625
     * @return void
626
     * @see setCssCustomFiles() for additional CSS sheets
627
     */
628
    public function setCssFiles()
629
    {
630
        return;
631
        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...
632
        $css = array();
633
634
        $this->theme = api_get_visual_theme();
635
636
        if (!empty($this->preview_theme)) {
637
            $this->theme = $this->preview_theme;
638
        }
639
640
        // Default CSS Bootstrap
641
        $bowerCSSFiles = [
642
            'bootstrap-daterangepicker/daterangepicker-bs3.css',
643
            'fontawesome/css/font-awesome.min.css',
644
            'jquery-ui/themes/smoothness/theme.css',
645
            'jquery-ui/themes/smoothness/jquery-ui.min.css',
646
            'mediaelement/build/mediaelementplayer.min.css',
647
            'jqueryui-timepicker-addon/dist/jquery-ui-timepicker-addon.min.css',
648
            'bootstrap/dist/css/bootstrap.min.css',
649
            'jquery.scrollbar/jquery.scrollbar.css',
650
        ];
651
652
        foreach ($bowerCSSFiles as $file) {
653
            $css[] = api_get_path(WEB_PATH).'web/assets/'.$file;
654
        }
655
        $css[] = api_get_path(WEB_LIBRARY_PATH) . 'javascript/bootstrap-select/css/bootstrap-select.min.css';
656
        $css[] = api_get_path(WEB_LIBRARY_PATH) . 'javascript/chosen/chosen.css';
657
        $css[] = api_get_path(WEB_LIBRARY_PATH) . 'javascript/tag/style.css';
658
659
        if (api_is_global_chat_enabled()) {
660
            $css[] = api_get_path(WEB_LIBRARY_PATH) . 'javascript/chat/css/chat.css';
661
        }
662
663
        //THEME CSS STYLE
664
        // $css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'responsive.css');
665
666
        $css_file_to_string = null;
667
        foreach ($css as $file) {
668
            $css_file_to_string .= api_get_css($file);
669
        }
670
671
        if (!$disable_js_and_css_files) {
672
            $this->assign('css_static_file_to_string', $css_file_to_string);
673
        }
674
    }
675
676
    /**
677
     *
678
     */
679
    public function setCSSEditor()
680
    {
681
        return;
682
        $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...
683
        if (is_file(api_get_path(SYS_CSS_PATH).'themes/'.$this->theme.'/editor.css')) {
684
            $cssEditor = api_get_path(WEB_CSS_PATH).'themes/'.$this->theme.'/editor.css';
685
        }
686
687
        $this->assign('cssEditor', $cssEditor);
688
    }
689
690
    /**
691
     * Prepare custom CSS to be added at the very end of the <head> section
692
     * @return void
693
     * @see setCssFiles() for the mainstream CSS files
694
     */
695
    public function setCssCustomFiles()
696
    {
697
        return;
698
        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...
699
        // Base CSS
700
701
        $css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'base.css');
702
703 View Code Duplication
        if ($this->show_learnpath) {
704
            $css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'scorm.css');
705
            if (is_file(api_get_path(SYS_CSS_PATH).'themes/'.$this->theme.'/learnpath.css')) {
706
                $css[] = api_get_path(WEB_CSS_PATH).'themes/'.$this->theme.'/learnpath.css';
707
            }
708
        }
709
710 View Code Duplication
        if (is_file(api_get_path(SYS_CSS_PATH).'themes/'.$this->theme.'/editor.css')) {
711
            $css[] = api_get_path(WEB_CSS_PATH).'themes/'.$this->theme.'/editor.css';
712
        }else{
713
            $css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'editor.css');
714
        }
715
716
        $css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'themes/'.$this->theme.'/default.css');
717
718
        $css_file_to_string = null;
719
        foreach ($css as $file) {
720
            $css_file_to_string .= api_get_css($file);
721
        }
722
        // @todo move this somewhere else. Special fix when using tablets in order to see the text near icons
723
        if (SHOW_TEXT_NEAR_ICONS == true) {
724
            //hack in order to fix the actions buttons
725
            $css_file_to_string .= '<style>
726
                .td_actions a {
727
                    float:left;
728
                    width:100%;
729
                }
730
                .forum_message_left a {
731
                    float:left;
732
                    width:100%;
733
                }
734
                </style>';
735
        }
736
737
        $navigator_info = api_get_navigator();
738
        if ($navigator_info['name'] == 'Internet Explorer' && $navigator_info['version'] == '6') {
739
            $css_file_to_string .= 'img, div { behavior: url('.api_get_path(WEB_LIBRARY_PATH).'javascript/iepngfix/iepngfix.htc) } '."\n";
740
        }
741
742
        if (!$disable_js_and_css_files) {
743
            $this->assign('css_custom_file_to_string', $css_file_to_string);
744
745
            $style_print = '';
746
            if (is_readable(api_get_path(SYS_CSS_PATH).$this->theme.'/print.css')) {
747
                $style_print = api_get_css(api_get_cdn_path(api_get_path(WEB_CSS_PATH) . $this->theme . '/print.css'),
748
                    'print');
749
            }
750
            $this->assign('css_style_print', $style_print);
751
        }
752
753
        // Logo
754
        /*$logo = return_logo($this->theme);
755
        $this->assign('logo', $logo);*/
756
757
        $this->assign('show_media_element', 1);
758
    }
759
760
    /**
761
     * Declare and define the template variable that will be used to load
762
     * javascript libraries in the header.
763
     */
764
    public function set_js_files()
765
    {
766
        global $disable_js_and_css_files, $htmlHeadXtra;
767
768
        $isoCode = api_get_language_isocode();
769
770
        $selectLink = 'bootstrap-select/js/i18n/defaults-' . $isoCode . '_' . strtoupper($isoCode) . '.min.js';
771
772
        if ($isoCode == 'en') {
773
            $selectLink = 'bootstrap-select/js/i18n/defaults-' . $isoCode . '_US.min.js';
774
        }
775
        // JS files
776
        $js_files = array(
777
            'chosen/chosen.jquery.min.js',
778
            'bootstrap-select/js/bootstrap-select.min.js',
779
            $selectLink
780
        );
781
782
        $viewBySession = api_get_setting('my_courses_view_by_session') === 'true';
783
784 View Code Duplication
        if (api_is_global_chat_enabled() || $viewBySession) {
785
            // Do not include the global chat in LP
786
            if ($this->show_learnpath == false &&
787
                $this->show_footer == true &&
788
                $this->hide_global_chat == false
789
            ) {
790
                $js_files[] = 'chat/js/chat.js';
791
            }
792
        }
793
794
        if (api_get_setting('accessibility_font_resize') == 'true') {
795
            $js_files[] = 'fontresize.js';
796
        }
797
798
        // Do not use minified version - generates errors (at least in the skills wheel)
799
        $js_files[] = 'tag/jquery.fcbkcomplete.js';
800
801
        $js_file_to_string = null;
802
803
        $bowerJsFiles = [
804
            'modernizr/modernizr.js',
805
            'jquery/dist/jquery.min.js',
806
            'bootstrap/dist/js/bootstrap.min.js',
807
            'jquery-ui/jquery-ui.min.js',
808
            'moment/min/moment-with-locales.min.js',
809
            'bootstrap-daterangepicker/daterangepicker.js',
810
            'jquery-timeago/jquery.timeago.js',
811
            'mediaelement/build/mediaelement-and-player.min.js',
812
            'jqueryui-timepicker-addon/dist/jquery-ui-timepicker-addon.min.js',
813
            'image-map-resizer/js/imageMapResizer.min.js',
814
            'jquery.scrollbar/jquery.scrollbar.min.js',
815
            'readmore-js/readmore.min.js'
816
        ];
817
        if (CHAMILO_LOAD_WYSIWYG == true) {
818
            $bowerJsFiles[] = 'ckeditor/ckeditor.js';
819
        }
820
821
        if (api_get_setting('include_asciimathml_script') == 'true') {
822
            $bowerJsFiles[] = 'MathJax/MathJax.js?config=AM_HTMLorMML';
823
        }
824
825
        if ($isoCode != 'en') {
826
            $bowerJsFiles[] = 'jqueryui-timepicker-addon/dist/i18n/jquery-ui-timepicker-' . $isoCode . '.js';
827
            $bowerJsFiles[] = 'jquery-ui/ui/minified/i18n/datepicker-' . $isoCode . '.min.js';
828
        }
829
830
        foreach ($bowerJsFiles as $file) {
831
            $js_file_to_string .= '<script type="text/javascript" src="'.api_get_path(WEB_PATH).'web/assets/'.$file.'"></script>'."\n";
832
        }
833
834
        foreach ($js_files as $file) {
835
            $js_file_to_string .= api_get_js($file);
836
        }
837
838
        // Loading email_editor js
839
        if (!api_is_anonymous() && api_get_setting('allow_email_editor') == 'true') {
840
            $js_file_to_string .= $this->fetch('default/mail_editor/email_link.js.tpl');
841
        }
842
843
        if (!$disable_js_and_css_files) {
844
            $this->assign('js_file_to_string', $js_file_to_string);
845
846
            //Adding jquery ui by default
847
            $extra_headers = api_get_jquery_ui_js();
848
849
            //$extra_headers = '';
850
            if (isset($htmlHeadXtra) && $htmlHeadXtra) {
851
                foreach ($htmlHeadXtra as & $this_html_head) {
852
                    $extra_headers .= $this_html_head."\n";
853
                }
854
            }
855
            $this->assign('extra_headers', $extra_headers);
856
        }
857
    }
858
859
    /**
860
     * Special function to declare last-minute JS libraries which depend on
861
     * other things to be declared first. In particular, it might be useful
862
     * under IE9 with compatibility mode, which for some reason is getting
863
     * upset when a variable is used in a function (even if not used yet)
864
     * when this variable hasn't been defined yet.
865
     */
866
    public function set_js_files_post()
867
    {
868
        global $disable_js_and_css_files, $htmlHeadXtra;
869
        $js_files = array();
870 View Code Duplication
        if (api_is_global_chat_enabled()) {
871
            //Do not include the global chat in LP
872
            if ($this->show_learnpath == false && $this->show_footer == true && $this->hide_global_chat == false) {
873
                $js_files[] = 'chat/js/chat.js';
874
            }
875
        }
876
        $js_file_to_string = null;
877
878
        foreach ($js_files as $js_file) {
879
            $js_file_to_string .= api_get_js($js_file);
880
        }
881
        if (!$disable_js_and_css_files) {
882
            $this->assign('js_file_to_string_post', $js_file_to_string);
883
        }
884
    }
885
886
    /**
887
     * Set header parameters
888
     * @param bool $sendHeaders send headers
889
     */
890
    private function set_header_parameters($sendHeaders)
891
    {
892
893
        global $httpHeadXtra, $interbreadcrumb, $language_file, $_configuration, $this_section;
894
        $_course = api_get_course_info();
895
        $help = $this->help;
896
        $nameTools = $this->title;
897
        //$navigation = return_navigation_array();
898
        $navigation = [];
899
        //$this->menu_navigation = $navigation['menu_navigation'];
900
901
        $this->assign('system_charset', api_get_system_encoding());
902
903
        if (isset($httpHeadXtra) && $httpHeadXtra) {
904
            foreach ($httpHeadXtra as & $thisHttpHead) {
905
                header($thisHttpHead);
906
            }
907
        }
908
909
        $this->assign('online_button', Display::return_icon('statusonline.png', null, null, ICON_SIZE_ATOM));
910
        $this->assign('offline_button',Display::return_icon('statusoffline.png', null, null, ICON_SIZE_ATOM));
911
912
        // Get language iso-code for this page - ignore errors
913
        $this->assign('document_language', api_get_language_isocode());
914
915
        $course_title = isset($_course['name']) ? $_course['name'] : null;
916
917
        $title_list = array();
918
919
        $title_list[] = api_get_setting('Institution');
920
        $title_list[] = api_get_setting('siteName');
921
922
        if (!empty($course_title)) {
923
            $title_list[] = $course_title;
924
        }
925
        if ($nameTools != '') {
926
            $title_list[] = $nameTools;
927
        }
928
929
        $title_string = '';
930
        for ($i = 0; $i < count($title_list); $i++) {
931
            $title_string .= $title_list[$i];
932
            if (isset($title_list[$i + 1])) {
933
                $item = trim($title_list[$i + 1]);
934
                if (!empty($item)) {
935
                    $title_string .= ' - ';
936
                }
937
            }
938
        }
939
940
        $this->assign('title_string', $title_string);
941
942
        //Setting the theme and CSS files
943
        $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...
944
        $this->set_js_files();
945
        $this->setCssCustomFiles($css);
946
        //$this->set_js_files_post();
947
948
        $browser = api_browser_support('check_browser');
949
        if ($browser[0] == 'Internet Explorer' && $browser[1] >= '11') {
950
            $browser_head = '<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9" />';
951
            $this->assign('browser_specific_head', $browser_head);
952
        }
953
954
        // Implementation of prefetch.
955
        // See http://cdn.chamilo.org/main/img/online.png for details
956
        $prefetch = '';
957
        if (!empty($_configuration['cdn_enable'])) {
958
            $prefetch .= '<meta http-equiv="x-dns-prefetch-control" content="on">';
959
            foreach ($_configuration['cdn'] as $host => $exts) {
960
                $prefetch .= '<link rel="dns-prefetch" href="'.$host.'">';
961
            }
962
        }
963
964
        $this->assign('prefetch', $prefetch);
965
        $this->assign('text_direction', api_get_text_direction());
966
        $this->assign('section_name', 'section-'.$this_section);
967
968
        //Defaul root chamilo favicon
969
        $favico = '<link rel="shortcut icon" href="' . api_get_path(WEB_PATH) . 'favicon.ico" type="image/x-icon" />';
970
971
        //Added to verify if in the current Chamilo Theme exist a favicon
972
        $favicoThemeUrl = api_get_path(SYS_CSS_PATH) . 'themes/' . $this->theme . '/images/';
973
974
        //If exist pick the current chamilo theme favicon
975
        if (is_file($favicoThemeUrl . 'favicon.ico')) {
976
            $favico = '<link rel="shortcut icon" href="' . api_get_path(WEB_CSS_PATH). 'themes/' . $this->theme . '/images/favicon.ico" type="image/x-icon" />';
977
        }
978
979
        if (api_is_multiple_url_enabled()) {
980
            $access_url_id = api_get_current_access_url_id();
981
            if ($access_url_id != -1) {
982
                $url_info  = api_get_access_url($access_url_id);
983
                $url       = api_remove_trailing_slash(preg_replace('/https?:\/\//i', '', $url_info['url']));
984
                $clean_url = api_replace_dangerous_char($url);
985
                $clean_url = str_replace('/', '-', $clean_url);
986
                $clean_url .= '/';
987
                $homep           = api_get_path(REL_PATH).'home/'.$clean_url; //homep for Home Path
988
                $icon_real_homep = api_get_path(SYS_APP_PATH).'home/'.$clean_url;
989
990
                //we create the new dir for the new sites
991
                if (is_file($icon_real_homep.'favicon.ico')) {
992
                    $favico = '<link rel="shortcut icon" href="'.$homep.'favicon.ico" type="image/x-icon" />';
993
                }
994
            }
995
        }
996
997
        $this->assign('favico', $favico);
998
        $this->setHelp();
999
1000
        //@todo move this in the template
1001
        $rightFloatMenu = '';
1002
        $iconBug = Display::return_icon('bug.png', get_lang('ReportABug'), null, ICON_SIZE_LARGE);
1003
        if (api_get_setting('show_link_bug_notification') == 'true' && $this->user_is_logged_in) {
1004
            $rightFloatMenu = '<div class="report">
1005
		<a href="https://github.com/chamilo/chamilo-lms/wiki/How-to-report-issues" target="_blank">
1006
                    '. $iconBug . '
1007
                </a>
1008
		</div>';
1009
        }
1010
1011
        if (api_get_setting('show_link_ticket_notification') == 'true' && $this->user_is_logged_in) {
1012
            // by default is project_id = 1
1013
            $iconTicket = Display::return_icon('bug.png', get_lang('Ticket'), null, ICON_SIZE_LARGE);
1014
            $courseInfo = api_get_course_info();
1015
            $courseParams = '';
1016
            if (!empty($courseInfo)) {
1017
                $courseParams = api_get_cidreq();
1018
            }
1019
            $url = api_get_path(WEB_CODE_PATH).'ticket/tickets.php?project_id=1&'.$courseParams;
1020
            $rightFloatMenu .= '<div class="report">
1021
		        <a href="'.$url.'" target="_blank">
1022
                    '. $iconTicket . '
1023
                </a>
1024
		    </div>';
1025
        }
1026
1027
        $this->assign('bug_notification', $rightFloatMenu);
1028
1029
        //$notification = returnNotificationMenu();
1030
        $this->assign('notification_menu', '');
1031
1032
        $resize = '';
1033
        if (api_get_setting('accessibility_font_resize') == 'true') {
1034
            $resize .= '<div class="resize_font">';
1035
            $resize .= '<div class="btn-group">';
1036
            $resize .= '<a title="'.get_lang('DecreaseFontSize').'" href="#" class="decrease_font btn btn-default"><em class="fa fa-font"></em></a>';
1037
            $resize .= '<a title="'.get_lang('ResetFontSize').'" href="#" class="reset_font btn btn-default"><em class="fa fa-font"></em></a>';
1038
            $resize .= '<a title="'.get_lang('IncreaseFontSize').'" href="#" class="increase_font btn btn-default"><em class="fa fa-font"></em></a>';
1039
            $resize .= '</div>';
1040
            $resize .= '</div>';
1041
        }
1042
        $this->assign('accessibility', $resize);
1043
1044
        // Preparing values for the menu
1045
1046
        // Logout link
1047
        $hideLogout = api_get_setting('hide_logout_button');
1048
        if ($hideLogout === 'true') {
1049
            $this->assign('logout_link', null);
1050
        } else {
1051
            $this->assign('logout_link', api_get_path(WEB_PATH).'index.php?logout=logout&uid='.api_get_user_id());
1052
        }
1053
1054
        //Profile link
1055
        if (api_get_setting('allow_social_tool') == 'true') {
1056
            $profile_url  = api_get_path(WEB_CODE_PATH).'social/home.php';
1057
1058
        } else {
1059
            $profile_url  = api_get_path(WEB_CODE_PATH).'auth/profile.php';
1060
1061
        }
1062
1063
        $this->assign('profile_url', $profile_url);
1064
1065
        //Message link
1066
        $message_link = null;
1067
        $message_url  = null;
1068
        if (api_get_setting('allow_message_tool') == 'true') {
1069
            $message_url  = api_get_path(WEB_CODE_PATH).'messages/inbox.php';
1070
            $message_link = '<a href="'.api_get_path(WEB_CODE_PATH).'messages/inbox.php">'.get_lang('Inbox').'</a>';
1071
        }
1072
        $this->assign('message_link', $message_link);
1073
        $this->assign('message_url', $message_url);
1074
1075
        // Certificate Link
1076
1077
        $allow = api_get_configuration_value('hide_my_certificate_link');
1078
        if ($allow === false) {
1079
            $certificateUrl = api_get_path(WEB_CODE_PATH).'gradebook/my_certificates.php';
1080
            $certificateLink = Display::url(
1081
                get_lang('MyCertificates'),
1082
                $certificateUrl
1083
            );
1084
            $this->assign('certificate_link', $certificateLink);
1085
            $this->assign('certificate_url', $certificateUrl);
1086
        }
1087
1088
        $institution = api_get_setting('Institution');
1089
        $portal_name = empty($institution) ? api_get_setting('siteName') : $institution;
1090
1091
        $this->assign('portal_name', $portal_name);
1092
1093
        //Menu
1094
        //$menu = menuArray();
1095
        $this->assign('menu', '');
1096
1097
        // Setting notifications
1098
        $count_unread_message = 0;
1099
        if (api_get_setting('allow_message_tool') == 'true') {
1100
            // get count unread message and total invitations
1101
            $count_unread_message = MessageManager::get_number_of_messages(true);
1102
        }
1103
1104
        $total_invitations = 0;
1105
        if (api_get_setting('allow_social_tool') == 'true') {
1106
            $number_of_new_messages_of_friend = SocialManager::get_message_number_invitation_by_user_id(
1107
                api_get_user_id()
1108
            );
1109
            $usergroup = new UserGroup();
1110
            $group_pending_invitations = $usergroup->get_groups_by_user(
1111
                api_get_user_id(),
1112
                GROUP_USER_PERMISSION_PENDING_INVITATION,
1113
                false
1114
            );
1115
            if (!empty($group_pending_invitations)) {
1116
                $group_pending_invitations = count($group_pending_invitations);
1117
            } else {
1118
                $group_pending_invitations = 0;
1119
            }
1120
            $total_invitations = intval($number_of_new_messages_of_friend) + $group_pending_invitations + intval($count_unread_message);
1121
        }
1122
        $total_invitations = (!empty($total_invitations) ? Display::badge($total_invitations) : null);
1123
1124
        $this->assign('user_notifications', $total_invitations);
1125
1126
1127
        // Block Breadcrumb
1128
        //$breadcrumb = return_breadcrumb($interbreadcrumb, $language_file, $nameTools);
1129
        $breadcrumb  = '';
1130
        $this->assign('breadcrumb', $breadcrumb);
1131
1132
        //Extra content
1133
        $extra_header = null;
1134
        if (!api_is_platform_admin()) {
1135
            $extra_header = trim(api_get_setting('header_extra_content'));
1136
        }
1137
        $this->assign('header_extra_content', $extra_header);
1138
1139
        if ($sendHeaders) {
1140
            header('Content-Type: text/html; charset='.api_get_system_encoding());
1141
            header(
1142
                'X-Powered-By: '.$_configuration['software_name'].' '.substr($_configuration['system_version'], 0, 1)
1143
            );
1144
        }
1145
1146
        $socialMeta = '';
1147
        $metaTitle = api_get_setting('meta_title');
1148
        if (!empty($metaTitle)) {
1149
            $socialMeta .= '<meta name="twitter:card" content="summary" />' . "\n";
1150
            $metaSite = api_get_setting('meta_twitter_site');
1151
            if (!empty($metaSite)) {
1152
                $socialMeta .= '<meta name="twitter:site" content="' . $metaSite . '" />' . "\n";
1153
                $metaCreator = api_get_setting('meta_twitter_creator');
1154
                if (!empty($metaCreator)) {
1155
                    $socialMeta .= '<meta name="twitter:creator" content="' . $metaCreator . '" />' . "\n";
1156
                }
1157
            }
1158
1159
            // The user badge page emits its own meta tags, so if this is
1160
            // enabled, ignore the global ones
1161
            $userId = isset($_GET['user']) ? intval($_GET['user']) : 0;
1162
            $skillId = isset($_GET['skill']) ? intval($_GET['skill']) : 0;
1163
1164
            if (!$userId && !$skillId) {
1165
                // no combination of user and skill ID has been defined,
1166
                // so print the normal OpenGraph meta tags
1167
                $socialMeta .= '<meta property="og:title" content="' . $metaTitle . '" />' . "\n";
1168
                $socialMeta .= '<meta property="og:url" content="' . api_get_path(WEB_PATH) . '" />' . "\n";
1169
1170
                $metaDescription = api_get_setting('meta_description');
1171
                if (!empty($metaDescription)) {
1172
                    $socialMeta .= '<meta property="og:description" content="' . $metaDescription . '" />' . "\n";
1173
                }
1174
1175
                $metaImage = api_get_setting('meta_image_path');
1176
                if (!empty($metaImage)) {
1177
                    if (is_file(api_get_path(SYS_PATH) . $metaImage)) {
1178
                        $path = api_get_path(WEB_PATH) . $metaImage;
1179
                        $socialMeta .= '<meta property="og:image" content="' . $path . '" />' . "\n";
1180
                    }
1181
                }
1182
            }
1183
        }
1184
1185
        $this->assign('social_meta', $socialMeta);
1186
    }
1187
1188
    /**
1189
     * Set footer parameters
1190
     */
1191
    private function set_footer_parameters()
1192
    {
1193
        if (api_get_setting('show_administrator_data') == 'true') {
1194
            // Administrator name
1195
            $administrator_data = get_lang('Manager').' : '.Display::encrypted_mailto_link(
1196
                    api_get_setting('emailAdministrator'),
1197
                    api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname'))
1198
                );
1199
            $this->assign('administrator_name', $administrator_data);
1200
        }
1201
1202
        // Loading footer extra content
1203
        if (!api_is_platform_admin()) {
1204
            $extra_footer = trim(api_get_setting('footer_extra_content'));
1205
            if (!empty($extra_footer)) {
1206
                $this->assign('footer_extra_content', $extra_footer);
1207
            }
1208
        }
1209
1210
        // Tutor name
1211
        if (api_get_setting('show_tutor_data') == 'true') {
1212
            // Course manager
1213
            $courseId  = api_get_course_int_id();
1214
            $id_session = api_get_session_id();
1215
            if (!empty($courseId)) {
1216
                $tutor_data = '';
1217
                if ($id_session != 0) {
1218
                    $coachs_email = CourseManager::get_email_of_tutor_to_session(
1219
                        $id_session,
1220
                        $courseId
1221
                    );
1222
                    $email_link = array();
1223
                    foreach ($coachs_email as $coach) {
1224
                        $email_link[] = Display::encrypted_mailto_link($coach['email'], $coach['complete_name']);
1225
                    }
1226
                    if (count($coachs_email) > 1) {
1227
                        $tutor_data .= get_lang('Coachs').' : ';
1228
                        $tutor_data .= array_to_string($email_link, CourseManager::USER_SEPARATOR);
1229
                    } elseif (count($coachs_email) == 1) {
1230
                        $tutor_data .= get_lang('Coach').' : ';
1231
                        $tutor_data .= array_to_string($email_link, CourseManager::USER_SEPARATOR);
1232
                    } elseif (count($coachs_email) == 0) {
1233
                        $tutor_data .= '';
1234
                    }
1235
                }
1236
                $this->assign('session_teachers', $tutor_data);
1237
            }
1238
        }
1239
1240
        if (api_get_setting('show_teacher_data') == 'true') {
1241
            // course manager
1242
            $courseId = api_get_course_int_id();
1243
            if (!empty($courseId)) {
1244
                $teacher_data = '';
1245
                $mail= CourseManager::get_emails_of_tutors_to_course($courseId);
1246
                if (!empty($mail)) {
1247
                    $teachers_parsed = array();
1248
                    foreach ($mail as $value) {
1249
                        foreach ($value as $email => $name) {
1250
                            $teachers_parsed[] = Display::encrypted_mailto_link($email, $name);
1251
                        }
1252
                    }
1253
                    $label = get_lang('Teacher');
1254
                    if (count($mail) > 1) {
1255
                        $label = get_lang('Teachers');
1256
                    }
1257
                    $teacher_data .= $label.' : '.array_to_string($teachers_parsed, CourseManager::USER_SEPARATOR);
1258
                }
1259
                $this->assign('teachers', $teacher_data);
1260
            }
1261
        }
1262
    }
1263
1264
    /**
1265
     * Show header template.
1266
     */
1267
    public function show_header_template()
1268
    {
1269
        $tpl = $this->get_template('layout/show_header.tpl');
1270
1271
        $this->display($tpl);
1272
    }
1273
1274
    /**
1275
     * Show footer template.
1276
     */
1277
    public function show_footer_template()
1278
    {
1279
        $tpl = $this->get_template('layout/show_footer.tpl');
1280
        $this->display($tpl);
1281
    }
1282
1283
    /**
1284
     * Show footer js template.
1285
     */
1286
    public function show_footer_js_template()
1287
    {
1288
        $tpl = $this->get_template('layout/footer.js.tpl');
1289
        $this->display($tpl);
1290
    }
1291
1292
    /**
1293
     * Sets the plugin content in a template variable
1294
     * @param string $pluginRegion
1295
     * @return null
1296
     */
1297
    public function set_plugin_region($pluginRegion)
1298
    {
1299
        if (!empty($pluginRegion)) {
1300
            $regionContent = $this->plugin->load_region($pluginRegion, $this, $this->force_plugin_load);
1301
1302
            $pluginList = $this->plugin->get_installed_plugins();
1303
            foreach ($pluginList as $plugin_name) {
1304
1305
                // The plugin_info variable is available inside the plugin index
1306
                $pluginInfo = $this->plugin->getPluginInfo($plugin_name);
1307
1308
                if (isset($pluginInfo['is_course_plugin']) && $pluginInfo['is_course_plugin']) {
1309
                    $courseInfo = api_get_course_info();
1310
1311
                    if (!empty($courseInfo)) {
1312
                        if (isset($pluginInfo['obj']) && $pluginInfo['obj'] instanceof Plugin) {
1313
                            /** @var Plugin $plugin */
1314
                            $plugin = $pluginInfo['obj'];
1315
                            $regionContent .= $plugin->renderRegion($pluginRegion);
1316
                        }
1317
                    }
1318
                } else {
1319
                    continue;
1320
                }
1321
            }
1322
1323
            if (!empty($regionContent)) {
1324
                $this->assign('plugin_'.$pluginRegion, $regionContent);
1325
            } else {
1326
                $this->assign('plugin_'.$pluginRegion, null);
1327
            }
1328
        }
1329
        return null;
1330
    }
1331
1332
    /**
1333
     * @param string $template
1334
     * @return string
1335
     */
1336
    public function fetch($template = null)
1337
    {
1338
        /*$template = $this->twig->loadTemplate($template);
1339
        return $template->render($this->params);*/
1340
        //
1341
1342
        $template = \Chamilo\CoreBundle\Framework\Container::getTwig()->loadTemplate('ChamiloCoreBundle::'.$template);
1343
        return $template->render($this->params);
1344
1345
    }
1346
1347
    /**
1348
     * @param string $variable
1349
     * @param mixed $value
1350
     */
1351
    public function assign($variable, $value = '')
1352
    {
1353
        $this->params[$variable] = $value;
1354
    }
1355
1356
    /**
1357
     * Render the template
1358
     * @param string $template The template path
1359
     * @param boolean $clearFlashMessages Clear the $_SESSION variables for flash messages
1360
     */
1361
    public function display($template, $clearFlashMessages = true)
1362
    {
1363
        $this->assign('flash_messages', Display::getFlashToString());
1364
1365
        if ($clearFlashMessages) {
1366
            Display::cleanFlashMessages();
1367
        }
1368
1369
        echo \Chamilo\CoreBundle\Framework\Container::getTwig()->render('ChamiloCoreBundle::'.$template, $this->params);
1370
1371
        //echo $this->twig->render($template, $this->params);
1372
    }
1373
1374
    /**
1375
     * Adds a body class for login pages
1376
     */
1377
    public function setLoginBodyClass()
1378
    {
1379
        $this->assign('login_class', 'section-login');
1380
    }
1381
1382
    /**
1383
     * The theme that will be used if the database is not working.
1384
     * @return string
1385
     */
1386
    public static function getThemeFallback()
1387
    {
1388
        $theme = api_get_configuration_value('theme_fallback');
1389
        if (empty($theme)) {
1390
            $theme = 'chamilo';
1391
        }
1392
        return $theme;
1393
    }
1394
1395
    /**
1396
     * @param bool|true $setLoginForm
1397
     */
1398
    public function setLoginForm($setLoginForm = true)
1399
    {
1400
        global $loginFailed;
1401
        $userId = api_get_user_id();
1402
        if (!($userId) || api_is_anonymous($userId)) {
1403
1404
            // Only display if the user isn't logged in.
1405
            $this->assign(
1406
                'login_language_form',
1407
                api_display_language_form(true)
1408
            );
1409
            if ($setLoginForm) {
1410
                $this->assign('login_form', $this->displayLoginForm());
1411
1412
                if ($loginFailed) {
1413
                    $this->assign('login_failed', $this::handleLoginFailed());
1414
                }
1415
            }
1416
        }
1417
    }
1418
1419
    /**
1420
     * @return string
1421
     */
1422
    public function handleLoginFailed()
1423
    {
1424
        $message = get_lang('InvalidId');
1425
1426
        if (!isset($_GET['error'])) {
1427
            if (api_is_self_registration_allowed()) {
1428
                $message = get_lang('InvalidForSelfRegistration');
1429
            }
1430
        } else {
1431
            switch ($_GET['error']) {
1432
                case '':
1433
                    if (api_is_self_registration_allowed()) {
1434
                        $message = get_lang('InvalidForSelfRegistration');
1435
                    }
1436
                    break;
1437
                case 'account_expired':
1438
                    $message = get_lang('AccountExpired');
1439
                    break;
1440
                case 'account_inactive':
1441
                    $message = get_lang('AccountInactive');
1442
                    break;
1443
                case 'user_password_incorrect':
1444
                    $message = get_lang('InvalidId');
1445
                    break;
1446
                case 'access_url_inactive':
1447
                    $message = get_lang('AccountURLInactive');
1448
                    break;
1449
                case 'wrong_captcha':
1450
                    $message = get_lang('TheTextYouEnteredDoesNotMatchThePicture');
1451
                    break;
1452
                case 'blocked_by_captcha':
1453
                    $message = get_lang('AccountBlockedByCaptcha');
1454
                    break;
1455
                case 'multiple_connection_not_allowed':
1456
                    $message = get_lang('MultipleConnectionsAreNotAllow');
1457
                    break;
1458
                case 'unrecognize_sso_origin':
1459
                    //$message = get_lang('SSOError');
1460
                    break;
1461
            }
1462
        }
1463
        return Display::return_message($message, 'error');
1464
    }
1465
1466
    /**
1467
     * @return string
1468
     */
1469
    public function displayLoginForm()
1470
    {
1471
        $form = new FormValidator(
1472
            'formLogin',
1473
            'POST',
1474
            null,
1475
            null,
1476
            null,
1477
            FormValidator::LAYOUT_BOX_NO_LABEL
1478
        );
1479
1480
        $form->addText(
1481
            'login',
1482
            get_lang('UserName'),
1483
            true,
1484
            array(
1485
                'id' => 'login',
1486
                'autofocus' => 'autofocus',
1487
                'icon' => 'user fa-fw',
1488
                'placeholder' => get_lang('UserName'),
1489
                'autocapitalize' => 'none'
1490
            )
1491
        );
1492
1493
        $form->addElement(
1494
            'password',
1495
            'password',
1496
            get_lang('Pass'),
1497
            array(
1498
                'id' => 'password',
1499
                'icon' => 'lock fa-fw',
1500
                'placeholder' => get_lang('Pass'),
1501
                'autocapitalize' => 'none',
1502
            )
1503
        );
1504
1505
        // Captcha
1506
        $captcha = api_get_setting('allow_captcha');
1507
        $allowCaptcha = $captcha === 'true';
1508
1509
        if ($allowCaptcha) {
1510
            $useCaptcha = isset($_SESSION['loginFailed']) ? $_SESSION['loginFailed'] : null;
1511
            if ($useCaptcha) {
1512
                $ajax = api_get_path(WEB_AJAX_PATH).'form.ajax.php?a=get_captcha';
1513
                $options = array(
1514
                    'width' => 250,
1515
                    'height' => 90,
1516
                    'callback'     => $ajax.'&var='.basename(__FILE__, '.php'),
1517
                    'sessionVar'   => basename(__FILE__, '.php'),
1518
                    'imageOptions' => array(
1519
                        'font_size' => 20,
1520
                        'font_path' => api_get_path(SYS_FONTS_PATH) . 'opensans/',
1521
                        'font_file' => 'OpenSans-Regular.ttf',
1522
                        //'output' => 'gif'
1523
                    )
1524
                );
1525
1526
                // Minimum options using all defaults (including defaults for Image_Text):
1527
                //$options = array('callback' => 'qfcaptcha_image.php');
1528
1529
                $captcha_question = $form->addElement('CAPTCHA_Image', 'captcha_question', '', $options);
1530
                $form->addHtml(get_lang('ClickOnTheImageForANewOne'));
1531
1532
                $form->addElement('text', 'captcha', get_lang('EnterTheLettersYouSee'));
1533
                $form->addRule('captcha', get_lang('EnterTheCharactersYouReadInTheImage'), 'required', null, 'client');
1534
                $form->addRule('captcha', get_lang('TheTextYouEnteredDoesNotMatchThePicture'), 'CAPTCHA', $captcha_question);
1535
            }
1536
        }
1537
1538
        $form->addButton('submitAuth', get_lang('LoginEnter'), null, 'primary', null, 'btn-block');
1539
1540
        $html = $form->returnForm();
1541
        if (api_get_setting('openid_authentication') == 'true') {
1542
            include_once 'main/auth/openid/login.php';
1543
            $html .= '<div>'.openid_form().'</div>';
1544
        }
1545
1546
        return $html;
1547
    }
1548
1549
    /**
1550
     * Set administrator variables
1551
     */
1552
    private function setAdministratorParams()
1553
    {
1554
        $_admin = [
1555
            'email' => api_get_setting('emailAdministrator'),
1556
            'surname' => api_get_setting('administratorSurname'),
1557
            'name' => api_get_setting('administratorName'),
1558
            'telephone' => api_get_setting('administratorTelephone')
1559
        ];
1560
1561
        $this->assign('_admin', $_admin);
1562
    }
1563
}
1564