Completed
Push — master ( 911a15...50617c )
by Julito
30:21
created

Template::show_header_template()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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