Completed
Push — master ( 815120...7a7e0c )
by Julito
46:08
created

Template   F

Complexity

Total Complexity 206

Size/Duplication

Total Lines 1493
Duplicated Lines 3.01 %

Coupling/Cohesion

Components 2
Dependencies 15

Importance

Changes 0
Metric Value
dl 45
loc 1493
rs 0.6314
c 0
b 0
f 0
wmc 206
lcom 2
cbo 15

38 Methods

Rating   Name   Duplication   Size   Complexity  
B setCssFiles() 0 47 6
A setCSSEditor() 0 10 2
C setCssCustomFiles() 11 64 10
F set_js_files() 9 94 19
B set_js_files_post() 6 19 7
F set_header_parameters() 0 297 45
D set_footer_parameters() 0 72 17
D __construct() 0 157 13
A get_icon_path() 0 4 1
A get_image() 0 4 1
A format_date() 0 4 1
B key() 0 17 6
B setHelp() 0 26 4
A set_actions() 0 10 3
A display() 0 5 1
A display_one_col_template() 0 4 1
A display_two_col_template() 0 4 1
A display_blank_template() 0 4 1
A display_no_layout_template() 0 4 1
A set_footer() 0 5 1
C isToolBarDisplayedForUser() 0 25 8
B set_header() 0 30 6
A get_template() 0 21 3
B set_course_parameters() 0 24 3
A set_user_parameters() 0 20 3
B set_system_parameters() 0 36 1
B getGlobals() 0 39 1
A show_footer_js_template() 0 5 1
D set_plugin_region() 19 34 9
A fetch() 0 6 1
A assign() 0 4 1
A setLoginBodyClass() 0 4 1
A getThemeFallback() 0 8 2
B setLoginForm() 0 20 5
C handleLoginFailed() 0 43 13
B displayLoginForm() 0 79 5
A setAdministratorParams() 0 11 1
A getParams() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Template often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Template, and based on these observations, apply Extract Interface, too.

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 = api_get_user_info();
614
615
        return [
616
            '_p' => $_p,
617
            '_s' => $_s,
618
     //       '_u' => $user_info,
619
            'template' => 'default' // @todo setup template folder in config.yml;
620
        ];
621
    }
622
623
    /**
624
     * Set theme, include mainstream CSS files
625
     * @return void
626
     * @see setCssCustomFiles() for additional CSS sheets
627
     */
628
    public function setCssFiles()
629
    {
630
        return;
631
        global $disable_js_and_css_files;
0 ignored issues
show
Unused Code introduced by
global $disable_js_and_css_files; does not seem to be reachable.

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

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

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

    return false;
}

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

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

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

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

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

    return false;
}

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

Loading history...
683
        if (is_file(api_get_path(SYS_CSS_PATH).'themes/'.$this->theme.'/editor.css')) {
684
            $cssEditor = api_get_path(WEB_CSS_PATH).'themes/'.$this->theme.'/editor.css';
685
        }
686
687
        $this->assign('cssEditor', $cssEditor);
688
    }
689
690
    /**
691
     * Prepare custom CSS to be added at the very end of the <head> section
692
     * @return void
693
     * @see setCssFiles() for the mainstream CSS files
694
     */
695
    public function setCssCustomFiles()
696
    {
697
        return;
698
        global $disable_js_and_css_files;
0 ignored issues
show
Unused Code introduced by
global $disable_js_and_css_files; does not seem to be reachable.

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

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

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

    return false;
}

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

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

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

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

}

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

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

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

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