Completed
Push — master ( 81699d...a5d7cd )
by Julito
31:09
created

Template::set_system_parameters()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

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

    return false;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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