Completed
Push — master ( e29d63...8b3aec )
by Julito
101:03 queued 68:16
created

Template::__construct()   D

Complexity

Conditions 13
Paths 2

Size

Total Lines 157
Code Lines 87

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 87
nc 2
nop 7
dl 0
loc 157
rs 4.9922
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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