Completed
Pull Request — development (#2329)
by Joshua
10:12
created

Theme::setupMenuContext()   F

Complexity

Conditions 65
Paths > 20000

Size

Total Lines 386
Code Lines 262

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 0
loc 386
rs 2
c 2
b 0
f 0
cc 65
eloc 262
nc 117969920
nop 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 25 and the first side effect is on line 22.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
namespace Themes\DefaultTheme;
4
5
/**
6
 * The default theme
7
 *
8
 * @name      ElkArte Forum
9
 * @copyright ElkArte Forum contributors
10
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause
11
 *
12
 * This software is a derived product, based on:
13
 *
14
 * Simple Machines Forum (SMF)
15
 * copyright:	2011 Simple Machines (http://www.simplemachines.org)
16
 * license:		BSD, See included LICENSE.TXT for terms and conditions.
17
 *
18
 * @version 1.1 dev
19
 *
20
 */
21
22
if (!defined('ELK'))
23
    die('No access...');
24
25
class Theme extends \Theme
26
{
27
    protected $id = 0;
28
29
30
    /**
31
     * This is the only template included in the sources.
32
     */
33
    function template_rawdata()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
34
    {
35
        global $context;
36
37
        echo $context['raw_data'];
38
    }
39
40
    /**
41
     * The header template
42
     */
43
    function template_header()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Coding Style introduced by
template_header uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
template_header uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
44
    {
45
        global $context, $settings;
46
47
        doSecurityChecks();
48
49
        $this->setupThemeContext();
50
51
        // Print stuff to prevent caching of pages (except on attachment errors, etc.)
52
        if (empty($context['no_last_modified']))
53
        {
54
            header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
55
            header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
56
57
            // Are we debugging the template/html content?
58
            if ((!isset($_REQUEST['xml']) || !isset($_REQUEST['api'])) && isset($_GET['debug']) && !isBrowser('ie'))
59
                header('Content-Type: application/xhtml+xml');
60
            elseif (!isset($_REQUEST['xml']) || !isset($_REQUEST['api']))
61
                header('Content-Type: text/html; charset=UTF-8');
62
        }
63
64
        // Probably temporary ($_REQUEST['xml'] should be replaced by $_REQUEST['api'])
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
65
        if (isset($_REQUEST['api']) && $_REQUEST['api'] == 'json')
66
            header('Content-Type: application/json; charset=UTF-8');
67
        elseif (isset($_REQUEST['xml']) || isset($_REQUEST['api']))
68
            header('Content-Type: text/xml; charset=UTF-8');
69
        else
70
            header('Content-Type: text/html; charset=UTF-8');
71
72
        foreach (\Template_Layers::getInstance()->prepareContext() as $layer)
73
            loadSubTemplate($layer . '_above', 'ignore');
74
75
        if (isset($settings['use_default_images']) && $settings['use_default_images'] == 'defaults' && isset($settings['default_template']))
76
        {
77
            $settings['theme_url'] = $settings['default_theme_url'];
78
            $settings['images_url'] = $settings['default_images_url'];
79
            $settings['theme_dir'] = $settings['default_theme_dir'];
80
        }
81
    }
82
83
    /**
84
     * Show the copyright.
85
     */
86
    function theme_copyright()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
87
    {
88
        global $forum_copyright;
89
90
        // Don't display copyright for things like SSI.
91
        if (!defined('FORUM_VERSION'))
92
            return;
93
94
        // Put in the version...
95
        $forum_copyright = replaceBasicActionUrl(sprintf($forum_copyright, FORUM_VERSION));
96
97
        echo '
98
					', $forum_copyright;
99
    }
100
101
    /**
102
     * The template footer
103
     */
104
    function template_footer()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
105
    {
106
        global $context, $settings, $modSettings, $time_start;
107
108
        $db = database();
109
110
        // Show the load time?  (only makes sense for the footer.)
111
        $context['show_load_time'] = !empty($modSettings['timeLoadPageEnable']);
112
        $context['load_time'] = round(microtime(true) - $time_start, 3);
113
        $context['load_queries'] = $db->num_queries();
114
115
        if (isset($settings['use_default_images']) && $settings['use_default_images'] == 'defaults' && isset($settings['default_template']))
116
        {
117
            $settings['theme_url'] = $settings['actual_theme_url'];
118
            $settings['images_url'] = $settings['actual_images_url'];
119
            $settings['theme_dir'] = $settings['actual_theme_dir'];
120
        }
121
122
        foreach (\Template_Layers::getInstance()->reverseLayers() as $layer)
123
            loadSubTemplate($layer . '_below', 'ignore');
124
125
    }
126
127
    /**
128
     * Output the Javascript files
129
     *
130
     * What it does:
131
     * - tabbing in this function is to make the HTML source look proper
132
     * - outputs jQuery/jQueryUI from the proper source (local/CDN)
133
     * - if defered is set function will output all JS (source & inline) set to load at page end
134
     * - if the admin option to combine files is set, will use Combiner.class
135
     *
136
     * @param bool $do_defered = false
137
     */
138
    function template_javascript($do_defered = false)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
139
    {
140
        global $context, $modSettings, $settings, $boardurl;
141
142
        // First up, load jQuery and jQuery UI
143
        if (isset($modSettings['jquery_source']) && !$do_defered)
144
        {
145
            // Using a specified version of jquery or what was shipped 2.1.4  / 1.11.4
146
            $jquery_version = (!empty($modSettings['jquery_default']) && !empty($modSettings['jquery_version'])) ? $modSettings['jquery_version'] : '2.1.4';
147
            $jqueryui_version = (!empty($modSettings['jqueryui_default']) && !empty($modSettings['jqueryui_version'])) ? $modSettings['jqueryui_version'] : '1.11.4';
148
149
            switch ($modSettings['jquery_source'])
150
            {
151
                // Only getting the files from the CDN?
152
                case 'cdn':
153
                    echo '
154
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/' . $jquery_version . '/jquery.min.js" id="jquery"></script>',
155
                    (!empty($modSettings['jquery_include_ui']) ? '
156
	<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/' . $jqueryui_version . '/jquery-ui.min.js" id="jqueryui"></script>' : '');
157
                    break;
158
                // Just use the local file
159
                case 'local':
160
                    echo '
161
	<script src="', $settings['default_theme_url'], '/scripts/jquery-' . $jquery_version . '.min.js" id="jquery"></script>',
162
                    (!empty($modSettings['jquery_include_ui']) ? '
163
	<script src="' . $settings['default_theme_url'] . '/scripts/jquery-ui-' . $jqueryui_version . '.min.js" id="jqueryui"></script>' : '');
164
                    break;
165
                // CDN with local fallback
166
                case 'auto':
167
                    echo '
168
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/' . $jquery_version . '/jquery.min.js" id="jquery"></script>',
169
                    (!empty($modSettings['jquery_include_ui']) ? '
170
	<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/' . $jqueryui_version . '/jquery-ui.min.js" id="jqueryui"></script>' : '');
171
                    echo '
172
	<script><!-- // --><![CDATA[
173
		window.jQuery || document.write(\'<script src="', $settings['default_theme_url'], '/scripts/jquery-' . $jquery_version . '.min.js"><\/script>\');',
174
                    (!empty($modSettings['jquery_include_ui']) ? '
175
		window.jQuery.ui || document.write(\'<script src="' . $settings['default_theme_url'] . '/scripts/jquery-ui-' . $jqueryui_version . '.min.js"><\/script>\')' : ''), '
176
	// ]]></script>';
177
                    break;
178
            }
179
        }
180
181
        // Use this hook to work with Javascript files and vars pre output
182
        call_integration_hook('pre_javascript_output');
183
184
        // Combine and minify javascript source files to save bandwidth and requests
185
        if (!empty($context['javascript_files']))
186
        {
187
            if (!empty($modSettings['minify_css_js']))
188
            {
189
                $combiner = new \Site_Combiner(CACHEDIR, $boardurl . '/cache');
190
                $combine_name = $combiner->site_js_combine($context['javascript_files'], $do_defered);
191
192
                call_integration_hook('post_javascript_combine', array(&$combine_name, $combiner));
193
194
                if (!empty($combine_name))
195
                    echo '
196
	<script src="', $combine_name, '" id="jscombined', $do_defered ? 'bottom' : 'top', '"></script>';
197
                // While we have Javascript files to place in the template
198
                foreach ($combiner->getSpares() as $id => $js_file)
199
                {
200
                    if ((!$do_defered && empty($js_file['options']['defer'])) || ($do_defered && !empty($js_file['options']['defer'])))
201
                        echo '
202
	<script src="', $js_file['filename'], '" id="', $id, '"', !empty($js_file['options']['async']) ? ' async="async"' : '', '></script>';
203
                }
204
            }
205
            else
206
            {
207
                // While we have Javascript files to place in the template
208
                foreach ($context['javascript_files'] as $id => $js_file)
209
                {
210
                    if ((!$do_defered && empty($js_file['options']['defer'])) || ($do_defered && !empty($js_file['options']['defer'])))
211
                        echo '
212
	<script src="', $js_file['filename'], '" id="', $id, '"', !empty($js_file['options']['async']) ? ' async="async"' : '', '></script>';
213
                }
214
            }
215
        }
216
217
        // Build the declared Javascript variables script
218
        $js_vars = array();
219
        if (!empty($context['javascript_vars']) && !$do_defered)
220
        {
221
            foreach ($context['javascript_vars'] as $var => $value)
222
                $js_vars[] = $var . ' = ' . $value;
223
224
            // nNewlines and tabs are here to make it look nice in the page source view, stripped if minimized though
225
            $context['javascript_inline']['standard'][] = 'var ' . implode(",\n\t\t\t", $js_vars) . ';';
226
        }
227
228
        // Inline JavaScript - Actually useful some times!
229
        if (!empty($context['javascript_inline']))
230
        {
231
            // Defered output waits until we are defering !
232
            if (!empty($context['javascript_inline']['defer']) && $do_defered)
233
            {
234
                // Combine them all in to one output
235
                $context['javascript_inline']['defer'] = array_map('trim', $context['javascript_inline']['defer']);
236
                $inline_defered_code = implode("\n\t\t", $context['javascript_inline']['defer']);
237
238
                // Output the defered script
239
                echo '
240
	<script><!-- // --><![CDATA[
241
		', $inline_defered_code, '
242
	// ]]></script>';
243
            }
244
245
            // Standard output, and our javascript vars, get output when we are not on a defered call
246
            if (!empty($context['javascript_inline']['standard']) && !$do_defered)
247
            {
248
                $context['javascript_inline']['standard'] = array_map('trim', $context['javascript_inline']['standard']);
249
250
                // And output the js vars and standard scripts to the page
251
                echo '
252
	<script><!-- // --><![CDATA[
253
		', implode("\n\t\t", $context['javascript_inline']['standard']), '
254
	// ]]></script>';
255
            }
256
        }
257
    }
258
259
    /**
260
     * Output the CSS files
261
     *
262
     * What it does:
263
     *  - If the admin option to combine files is set, will use Combiner.class
264
     */
265
    function template_css()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
266
    {
267
        global $context, $modSettings, $boardurl;
268
269
        // Use this hook to work with CSS files pre output
270
        call_integration_hook('pre_css_output');
271
272
        // Combine and minify the CSS files to save bandwidth and requests?
273
        if (!empty($context['css_files']))
274
        {
275
            if (!empty($modSettings['minify_css_js']))
276
            {
277
                $combiner = new \Site_Combiner(CACHEDIR, $boardurl . '/cache');
278
                $combine_name = $combiner->site_css_combine($context['css_files']);
279
280
                call_integration_hook('post_css_combine', array(&$combine_name, $combiner));
281
282
                if (!empty($combine_name))
283
                    echo '
284
	<link rel="stylesheet" href="', $combine_name, '" id="csscombined" />';
285
286
                foreach ($combiner->getSpares() as $id => $file)
287
                    echo '
288
	<link rel="stylesheet" href="', $file['filename'], '" id="', $id,'" />';
289
            }
290
            else
291
            {
292
                foreach ($context['css_files'] as $id => $file)
293
                    echo '
294
	<link rel="stylesheet" href="', $file['filename'], '" id="', $id,'" />';
295
            }
296
        }
297
    }
298
299
    /**
300
     * Calls on template_show_error from index.template.php to show warnings
301
     * and security errors for admins
302
     */
303
    function template_admin_warning_above()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
304
    {
305
        global $context, $txt;
306
307
        if (!empty($context['security_controls_files']))
308
        {
309
            $context['security_controls_files']['type'] = 'serious';
310
            template_show_error('security_controls_files');
311
        }
312
313
        if (!empty($context['security_controls_query']))
314
        {
315
            $context['security_controls_query']['type'] = 'serious';
316
            template_show_error('security_controls_query');
317
        }
318
319
        if (!empty($context['security_controls_ban']))
320
        {
321
            $context['security_controls_ban']['type'] = 'serious';
322
            template_show_error('security_controls_ban');
323
        }
324
325
        if (!empty($context['new_version_updates']))
326
        {
327
            template_show_error('new_version_updates');
328
        }
329
330
        // Any special notices to remind the admin about?
331
        if (!empty($context['warning_controls']))
332
        {
333
            $context['warning_controls']['errors'] = $context['warning_controls'];
334
            $context['warning_controls']['title'] = $txt['admin_warning_title'];
335
            $context['warning_controls']['type'] = 'warning';
336
            template_show_error('warning_controls');
337
        }
338
    }
339
340
    function addCodePrettify()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
341
    {
342
        loadCSSFile('prettify.css');
343
        loadJavascriptFile('prettify.min.js', array('defer' => true));
344
345
        addInlineJavascript('
346
		$(document).ready(function(){
347
			prettyPrint();
348
		});', true);
349
    }
350
351
    function autoEmbedVideo()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
352
    {
353
        global $txt;
354
355
        addInlineJavascript('
356
		var oEmbedtext = ({
357
			preview_image : ' . JavaScriptEscape($txt['preview_image']) . ',
358
			ctp_video : ' . JavaScriptEscape($txt['ctp_video']) . ',
359
			hide_video : ' . JavaScriptEscape($txt['hide_video']) . ',
360
			youtube : ' . JavaScriptEscape($txt['youtube']) . ',
361
			vimeo : ' . JavaScriptEscape($txt['vimeo']) . ',
362
			dailymotion : ' . JavaScriptEscape($txt['dailymotion']) . '
363
		});', true);
364
365
        loadJavascriptFile('elk_jquery_embed.js', array('defer' => true));
366
    }
367
368
    function doScheduledSendMail()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
369
    {
370
        global $modSettings;
371
372
        if (isBrowser('possibly_robot'))
373
        {
374
            // @todo Maybe move this somewhere better?!
375
            $controller = new \ScheduledTasks_Controller();
376
377
            // What to do, what to do?!
378
            if (empty($modSettings['next_task_time']) || $modSettings['next_task_time'] < time())
379
                $controller->action_autotask();
380
            else
381
                $controller->action_reducemailqueue();
382
        }
383
        else
384
        {
385
            $type = empty($modSettings['next_task_time']) || $modSettings['next_task_time'] < time() ? 'task' : 'mailq';
386
            $ts = $type == 'mailq' ? $modSettings['mail_next_send'] : $modSettings['next_task_time'];
387
388
            addInlineJavascript('
389
		function elkAutoTask()
390
		{
391
			var tempImage = new Image();
392
			tempImage.src = elk_scripturl + "?scheduled=' . $type . ';ts=' . $ts . '";
393
		}
394
		window.setTimeout("elkAutoTask();", 1);', true);
395
        }
396
    }
397
398
    function relativeTimes()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
399
    {
400
        global $modSettings, $context, $txt;
401
402
        // Relative times?
403
        if (!empty($modSettings['todayMod']) && $modSettings['todayMod'] > 2)
404
        {
405
            addInlineJavascript('
406
		var oRttime = ({
407
			referenceTime : ' . forum_time() * 1000 . ',
408
			now : ' . JavaScriptEscape($txt['rt_now']) . ',
409
			minute : ' . JavaScriptEscape($txt['rt_minute']) . ',
410
			minutes : ' . JavaScriptEscape($txt['rt_minutes']) . ',
411
			hour : ' . JavaScriptEscape($txt['rt_hour']) . ',
412
			hours : ' . JavaScriptEscape($txt['rt_hours']) . ',
413
			day : ' . JavaScriptEscape($txt['rt_day']) . ',
414
			days : ' . JavaScriptEscape($txt['rt_days']) . ',
415
			week : ' . JavaScriptEscape($txt['rt_week']) . ',
416
			weeks : ' . JavaScriptEscape($txt['rt_weeks']) . ',
417
			month : ' . JavaScriptEscape($txt['rt_month']) . ',
418
			months : ' . JavaScriptEscape($txt['rt_months']) . ',
419
			year : ' . JavaScriptEscape($txt['rt_year']) . ',
420
			years : ' . JavaScriptEscape($txt['rt_years']) . ',
421
		});
422
		updateRelativeTime();', true);
423
            $context['using_relative_time'] = true;
424
        }
425
    }
426
427
    /**
428
     * Sets up the basic theme context stuff.
429
     *
430
     * @param bool $forceload = false
431
     */
432
    function setupThemeContext($forceload = false)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Coding Style introduced by
setupThemeContext uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
setupThemeContext uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
setupThemeContext uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
433
    {
434
        global $modSettings, $user_info, $scripturl, $context, $settings, $options, $txt;
435
436
        static $loaded = false;
437
438
        // Under SSI this function can be called more then once.  That can cause some problems.
439
        // So only run the function once unless we are forced to run it again.
440
        if ($loaded && !$forceload)
441
            return;
442
443
        $loaded = true;
444
445
        $context['current_time'] = standardTime(time(), false);
446
        $context['current_action'] = isset($_GET['action']) ? $_GET['action'] : '';
447
        $context['show_quick_login'] = !empty($modSettings['enableVBStyleLogin']) && $user_info['is_guest'];
448
449
        $bbc_parser = \BBC\ParserWrapper::getInstance();
450
451
        // Get some news...
452
        $context['news_lines'] = array_filter(explode("\n", str_replace("\r", '', trim(addslashes($modSettings['news'])))));
453
        for ($i = 0, $n = count($context['news_lines']); $i < $n; $i++)
454
        {
455
            if (trim($context['news_lines'][$i]) == '')
456
                continue;
457
458
            // Clean it up for presentation ;).
459
            $context['news_lines'][$i] = $bbc_parser->parseNews(stripslashes(trim($context['news_lines'][$i])));
460
        }
461
462
        if (!empty($context['news_lines']))
463
        {
464
            $context['random_news_line'] = $context['news_lines'][mt_rand(0, count($context['news_lines']) - 1)];
465
            $context['upper_content_callbacks'][] = 'news_fader';
466
        }
467
468
        if (!$user_info['is_guest'])
469
        {
470
            $context['user']['messages'] = &$user_info['messages'];
471
            $context['user']['unread_messages'] = &$user_info['unread_messages'];
472
            $context['user']['mentions'] = &$user_info['mentions'];
473
474
            // Personal message popup...
475
            if ($user_info['unread_messages'] > (isset($_SESSION['unread_messages']) ? $_SESSION['unread_messages'] : 0))
476
                $context['user']['popup_messages'] = true;
477
            else
478
                $context['user']['popup_messages'] = false;
479
            $_SESSION['unread_messages'] = $user_info['unread_messages'];
480
481
            $context['user']['avatar'] = array(
482
                'href' => !empty($user_info['avatar']['href']) ? $user_info['avatar']['href'] : '',
483
                'image' => !empty($user_info['avatar']['image']) ? $user_info['avatar']['image'] : '',
484
            );
485
486
            // @deprecated since 1.0.2
487
            if (!empty($modSettings['avatar_max_width']))
488
                $context['user']['avatar']['width'] = $modSettings['avatar_max_width'];
489
490
            // @deprecated since 1.0.2
491
            if (!empty($modSettings['avatar_max_height']))
492
                $context['user']['avatar']['height'] = $modSettings['avatar_max_height'];
493
494
            // Figure out how long they've been logged in.
495
            $context['user']['total_time_logged_in'] = array(
496
                'days' => floor($user_info['total_time_logged_in'] / 86400),
497
                'hours' => floor(($user_info['total_time_logged_in'] % 86400) / 3600),
498
                'minutes' => floor(($user_info['total_time_logged_in'] % 3600) / 60)
499
            );
500
        }
501
        else
502
        {
503
            $context['user']['messages'] = 0;
504
            $context['user']['unread_messages'] = 0;
505
            $context['user']['mentions'] = 0;
506
            $context['user']['avatar'] = array();
507
            $context['user']['total_time_logged_in'] = array('days' => 0, 'hours' => 0, 'minutes' => 0);
508
            $context['user']['popup_messages'] = false;
509
510
            if (!empty($modSettings['registration_method']) && $modSettings['registration_method'] == 1)
511
                $txt['welcome_guest'] .= $txt['welcome_guest_activate'];
512
            $txt['welcome_guest'] = replaceBasicActionUrl($txt['welcome_guest']);
513
514
            // If we've upgraded recently, go easy on the passwords.
515
            if (!empty($modSettings['enable_password_conversion']))
516
                $context['disable_login_hashing'] = true;
517
        }
518
519
        // Setup the main menu items.
520
        setupMenuContext();
521
522
        if (empty($settings['theme_version']))
523
            $context['show_vBlogin'] = $context['show_quick_login'];
524
525
        // This is here because old index templates might still use it.
526
        $context['show_news'] = !empty($settings['enable_news']);
527
528
        $context['additional_dropdown_search'] = prepareSearchEngines();
529
530
        // This is done to allow theme authors to customize it as they want.
531
        $context['show_pm_popup'] = $context['user']['popup_messages'] && !empty($options['popup_messages']) && (!isset($_REQUEST['action']) || $_REQUEST['action'] != 'pm');
532
533
        // Add the PM popup here instead. Theme authors can still override it simply by editing/removing the 'fPmPopup' in the array.
534
        if ($context['show_pm_popup'])
535
            addInlineJavascript('
536
		$(document).ready(function(){
537
			new smc_Popup({
538
				heading: ' . JavaScriptEscape($txt['show_personal_messages_heading']) . ',
539
				content: ' . JavaScriptEscape(sprintf($txt['show_personal_messages'], $context['user']['unread_messages'], $scripturl . '?action=pm')) . ',
540
				icon: elk_images_url + \'/im_sm_newmsg.png\'
541
			});
542
		});', true);
543
544
        // This looks weird, but it's because BoardIndex.controller.php references the variable.
545
        $context['common_stats']['latest_member'] = array(
546
            'id' => $modSettings['latestMember'],
547
            'name' => $modSettings['latestRealName'],
548
            'href' => $scripturl . '?action=profile;u=' . $modSettings['latestMember'],
549
            'link' => '<a href="' . $scripturl . '?action=profile;u=' . $modSettings['latestMember'] . '">' . $modSettings['latestRealName'] . '</a>',
550
        );
551
        $context['common_stats'] = array(
552
            'total_posts' => comma_format($modSettings['totalMessages']),
553
            'total_topics' => comma_format($modSettings['totalTopics']),
554
            'total_members' => comma_format($modSettings['totalMembers']),
555
            'latest_member' => $context['common_stats']['latest_member'],
556
        );
557
        $context['common_stats']['boardindex_total_posts'] = sprintf($txt['boardindex_total_posts'], $context['common_stats']['total_posts'], $context['common_stats']['total_topics'], $context['common_stats']['total_members']);
558
559
        if (empty($settings['theme_version']))
560
            addJavascriptVar(array('elk_scripturl' => '\'' . $scripturl . '\''));
561
562
        if (!isset($context['page_title']))
563
            $context['page_title'] = '';
564
565
        // Set some specific vars.
566
        $context['page_title_html_safe'] = \Util::htmlspecialchars(un_htmlspecialchars($context['page_title'])) . (!empty($context['current_page']) ? ' - ' . $txt['page'] . ' ' . ($context['current_page'] + 1) : '');
567
568
        // Load a custom CSS file?
569
        if (file_exists($settings['theme_dir'] . '/css/custom.css'))
570
            loadCSSFile('custom.css');
571
        if (!empty($context['theme_variant']) && file_exists($settings['theme_dir'] . '/css/' . $context['theme_variant'] . '/custom' . $context['theme_variant'] . '.css'))
572
            loadCSSFile($context['theme_variant'] . '/custom' . $context['theme_variant'] . '.css');
573
    }
574
575
    /**
576
     * Sets up all of the top menu buttons
577
     *
578
     * What it does:
579
     * - Defines every master item in the menu, as well as any sub-items
580
     * - Ensures the chosen action is set so the menu is highlighted
581
     * - Saves them in the cache if it is available and on
582
     * - Places the results in $context
583
     */
584
    function setupMenuContext()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Coding Style introduced by
setupMenuContext uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
585
    {
586
        global $context, $modSettings, $user_info, $txt, $scripturl, $settings;
587
588
        // Set up the menu privileges.
589
        $context['allow_search'] = !empty($modSettings['allow_guestAccess']) ? allowedTo('search_posts') : (!$user_info['is_guest'] && allowedTo('search_posts'));
590
        $context['allow_admin'] = allowedTo(array('admin_forum', 'manage_boards', 'manage_permissions', 'moderate_forum', 'manage_membergroups', 'manage_bans', 'send_mail', 'edit_news', 'manage_attachments', 'manage_smileys'));
591
        $context['allow_edit_profile'] = !$user_info['is_guest'] && allowedTo(array('profile_view_own', 'profile_view_any', 'profile_identity_own', 'profile_identity_any', 'profile_extra_own', 'profile_extra_any', 'profile_remove_own', 'profile_remove_any', 'moderate_forum', 'manage_membergroups', 'profile_title_own', 'profile_title_any'));
592
        $context['allow_memberlist'] = allowedTo('view_mlist');
593
        $context['allow_calendar'] = allowedTo('calendar_view') && !empty($modSettings['cal_enabled']);
594
        $context['allow_moderation_center'] = $context['user']['can_mod'];
595
        $context['allow_pm'] = allowedTo('pm_read');
596
597
        if ($context['allow_search'])
598
            $context['theme_header_callbacks'] = elk_array_insert($context['theme_header_callbacks'], 'login_bar', array('search_bar'), 'after');
599
600
        $cacheTime = $modSettings['lastActive'] * 60;
601
602
        // Update the Moderation menu items with action item totals
603
        if ($context['allow_moderation_center'])
604
        {
605
            // Get the numbers for the menu ...
606
            require_once(SUBSDIR . '/Moderation.subs.php');
607
            $menu_count = loadModeratorMenuCounts();
608
        }
609
610
        $menu_count['unread_messages'] = $context['user']['unread_messages'];
0 ignored issues
show
Bug introduced by
The variable $menu_count does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
611
        $menu_count['mentions'] = $context['user']['mentions'];
612
613
        // All the buttons we can possible want and then some, try pulling the final list of buttons from cache first.
614
        if (($menu_buttons = cache_get_data('menu_buttons-' . implode('_', $user_info['groups']) . '-' . $user_info['language'], $cacheTime)) === null || time() - $cacheTime <= $modSettings['settings_updated'])
615
        {
616
            // Start things up: this is what we know by default
617
            require_once(SUBSDIR . '/Menu.subs.php');
618
            $buttons = array(
619
                'home' => array(
620
                    'title' => $txt['community'],
621
                    'href' => $scripturl,
622
                    'data-icon' => '&#xf015;',
623
                    'show' => true,
624
                    'sub_buttons' => array(
625
                        'help' => array(
626
                            'title' => $txt['help'],
627
                            'href' => $scripturl . '?action=help',
628
                            'show' => true,
629
                        ),
630
                        'search' => array(
631
                            'title' => $txt['search'],
632
                            'href' => $scripturl . '?action=search',
633
                            'show' => $context['allow_search'],
634
                        ),
635
                        'calendar' => array(
636
                            'title' => $txt['calendar'],
637
                            'href' => $scripturl . '?action=calendar',
638
                            'show' => $context['allow_calendar'],
639
                        ),
640
                        'memberlist' => array(
641
                            'title' => $txt['members_title'],
642
                            'href' => $scripturl . '?action=memberlist',
643
                            'show' => $context['allow_memberlist'],
644
                        ),
645
                        'recent' => array(
646
                            'title' => $txt['recent_posts'],
647
                            'href' => $scripturl . '?action=recent',
648
                            'show' => true,
649
                        ),
650
                    ),
651
                )
652
            );
653
654
            // Will change title correctly if user is either a mod or an admin.
655
            // Button highlighting works properly too (see current action stuffz).
656
            if ($context['allow_admin'])
657
            {
658
                $buttons['admin'] = array(
659
                    'title' => $context['current_action'] !== 'moderate' ? $txt['admin'] : $txt['moderate'],
660
                    'counter' => 'grand_total',
661
                    'href' => $scripturl . '?action=admin',
662
                    'data-icon' => '&#xf013;',
663
                    'show' => true,
664
                    'sub_buttons' => array(
665
                        'admin_center' => array(
666
                            'title' => $txt['admin_center'],
667
                            'href' => $scripturl . '?action=admin',
668
                            'show' => $context['allow_admin'],
669
                        ),
670
                        'featuresettings' => array(
671
                            'title' => $txt['modSettings_title'],
672
                            'href' => $scripturl . '?action=admin;area=featuresettings',
673
                            'show' => allowedTo('admin_forum'),
674
                        ),
675
                        'packages' => array(
676
                            'title' => $txt['package'],
677
                            'href' => $scripturl . '?action=admin;area=packages',
678
                            'show' => allowedTo('admin_forum'),
679
                        ),
680
                        'permissions' => array(
681
                            'title' => $txt['edit_permissions'],
682
                            'href' => $scripturl . '?action=admin;area=permissions',
683
                            'show' => allowedTo('manage_permissions'),
684
                        ),
685
                        'errorlog' => array(
686
                            'title' => $txt['errlog'],
687
                            'href' => $scripturl . '?action=admin;area=logs;sa=errorlog;desc',
688
                            'show' => allowedTo('admin_forum') && !empty($modSettings['enableErrorLogging']),
689
                        ),
690
                        'moderate_sub' => array(
691
                            'title' => $txt['moderate'],
692
                            'counter' => 'grand_total',
693
                            'href' => $scripturl . '?action=moderate',
694
                            'show' => $context['allow_moderation_center'],
695
                            'sub_buttons' => array(
696
                                'reports' => array(
697
                                    'title' => $txt['mc_reported_posts'],
698
                                    'counter' => 'reports',
699
                                    'href' => $scripturl . '?action=moderate;area=reports',
700
                                    'show' => !empty($user_info['mod_cache']) && $user_info['mod_cache']['bq'] != '0=1',
701
                                ),
702
                                'modlog' => array(
703
                                    'title' => $txt['modlog_view'],
704
                                    'href' => $scripturl . '?action=moderate;area=modlog',
705
                                    'show' => !empty($modSettings['modlog_enabled']) && !empty($user_info['mod_cache']) && $user_info['mod_cache']['bq'] != '0=1',
706
                                ),
707
                                'attachments' => array(
708
                                    'title' => $txt['mc_unapproved_attachments'],
709
                                    'counter' => 'attachments',
710
                                    'href' => $scripturl . '?action=moderate;area=attachmod;sa=attachments',
711
                                    'show' => $modSettings['postmod_active'] && !empty($user_info['mod_cache']['ap']),
712
                                ),
713
                                'poststopics' => array(
714
                                    'title' => $txt['mc_unapproved_poststopics'],
715
                                    'counter' => 'postmod',
716
                                    'href' => $scripturl . '?action=moderate;area=postmod;sa=posts',
717
                                    'show' => $modSettings['postmod_active'] && !empty($user_info['mod_cache']['ap']),
718
                                ),
719
                                'postbyemail' => array(
720
                                    'title' => $txt['mc_emailerror'],
721
                                    'counter' => 'emailmod',
722
                                    'href' => $scripturl . '?action=admin;area=maillist;sa=emaillist',
723
                                    'show' => !empty($modSettings['maillist_enabled']) && allowedTo('approve_emails'),
724
                                ),
725
                            ),
726
                        ),
727
                    ),
728
                );
729
            }
730
            else
731
            {
732
                $buttons['admin'] = array(
733
                    'title' => $txt['moderate'],
734
                    'counter' => 'grand_total',
735
                    'href' => $scripturl . '?action=moderate',
736
                    'data-icon' => '&#xf013;',
737
                    'show' => $context['allow_moderation_center'],
738
                    'sub_buttons' => array(
739
                        'reports' => array(
740
                            'title' => $txt['mc_reported_posts'],
741
                            'counter' => 'reports',
742
                            'href' => $scripturl . '?action=moderate;area=reports',
743
                            'show' => !empty($user_info['mod_cache']) && $user_info['mod_cache']['bq'] != '0=1',
744
                        ),
745
                        'modlog' => array(
746
                            'title' => $txt['modlog_view'],
747
                            'href' => $scripturl . '?action=moderate;area=modlog',
748
                            'show' => !empty($modSettings['modlog_enabled']) && !empty($user_info['mod_cache']) && $user_info['mod_cache']['bq'] != '0=1',
749
                        ),
750
                        'attachments' => array(
751
                            'title' => $txt['mc_unapproved_attachments'],
752
                            'counter' => 'attachments',
753
                            'href' => $scripturl . '?action=moderate;area=attachmod;sa=attachments',
754
                            'show' => $modSettings['postmod_active'] && !empty($user_info['mod_cache']['ap']),
755
                        ),
756
                        'poststopics' => array(
757
                            'title' => $txt['mc_unapproved_poststopics'],
758
                            'counter' => 'postmod',
759
                            'href' => $scripturl . '?action=moderate;area=postmod;sa=posts',
760
                            'show' => $modSettings['postmod_active'] && !empty($user_info['mod_cache']['ap']),
761
                        ),
762
                        'postbyemail' => array(
763
                            'title' => $txt['mc_emailerror'],
764
                            'counter' => 'emailmod',
765
                            'href' => $scripturl . '?action=admin;area=maillist;sa=emaillist',
766
                            'show' => !empty($modSettings['maillist_enabled']) && allowedTo('approve_emails'),
767
                        ),
768
                    ),
769
                );
770
            }
771
772
            $buttons += array(
773
                'profile' => array(
774
                    'title' => (!empty($user_info['avatar']['href']) ? '<img class="avatar" src="' . $user_info['avatar']['href'] . '" alt="" /> ' : '') . (!empty($modSettings['displayMemberNames']) ? $user_info['name'] : $txt['account_short']),
775
                    'href' => $scripturl . '?action=profile',
776
                    'data-icon' => '&#xf007;',
777
                    'show' => $context['allow_edit_profile'],
778
                    'sub_buttons' => array(
779
                        'account' => array(
780
                            'title' => $txt['account'],
781
                            'href' => $scripturl . '?action=profile;area=account',
782
                            'show' => allowedTo(array('profile_identity_any', 'profile_identity_own', 'manage_membergroups')),
783
                        ),
784
                        'forumprofile' => array(
785
                            'title' => $txt['forumprofile'],
786
                            'href' => $scripturl . '?action=profile;area=forumprofile',
787
                            'show' => allowedTo(array('profile_extra_any', 'profile_extra_own')),
788
                        ),
789
                        'theme' => array(
790
                            'title' => $txt['theme'],
791
                            'href' => $scripturl . '?action=profile;area=theme',
792
                            'show' => allowedTo(array('profile_extra_any', 'profile_extra_own', 'profile_extra_any')),
793
                        ),
794
                        'logout' => array(
795
                            'title' => $txt['logout'],
796
                            'href' => $scripturl . '?action=logout',
797
                            'show' => !$user_info['is_guest'],
798
                        ),
799
                    ),
800
                ),
801
                // @todo Look at doing something here, to provide instant access to inbox when using click menus.
802
                // @todo A small pop-up anchor seems like the obvious way to handle it. ;)
803
                'pm' => array(
804
                    'title' => $txt['pm_short'],
805
                    'counter' => 'unread_messages',
806
                    'href' => $scripturl . '?action=pm',
807
                    'data-icon' => '&#xf0e0;',
808
                    'show' => $context['allow_pm'],
809
                    'sub_buttons' => array(
810
                        'pm_read' => array(
811
                            'title' => $txt['pm_menu_read'],
812
                            'href' => $scripturl . '?action=pm',
813
                            'show' => allowedTo('pm_read'),
814
                        ),
815
                        'pm_send' => array(
816
                            'title' => $txt['pm_menu_send'],
817
                            'href' => $scripturl . '?action=pm;sa=send',
818
                            'show' => allowedTo('pm_send'),
819
                        ),
820
                    ),
821
                ),
822
                'mentions' => array(
823
                    'title' => $txt['mention'],
824
                    'counter' => 'mentions',
825
                    'href' => $scripturl . '?action=mentions',
826
                    'data-icon' => '&#xf0f3;',
827
                    'show' => !$user_info['is_guest'] && !empty($modSettings['mentions_enabled']),
828
                ),
829
                // The old language string made no sense, and was too long.
830
                // "New posts" is better, because there are probably a pile
831
                // of old unread posts, and they wont be reached from this button.
832
                'unread' => array(
833
                    'title' => $txt['view_unread_category'],
834
                    'href' => $scripturl . '?action=unread',
835
                    'data-icon' => '&#xf086;',
836
                    'show' => !$user_info['is_guest'],
837
                ),
838
                // The old language string made no sense, and was too long.
839
                // "New replies" is better, because there are "updated topics"
840
                // that the user has never posted in and doesn't care about.
841
                'unreadreplies' => array(
842
                    'title' => $txt['view_replies_category'],
843
                    'href' => $scripturl . '?action=unreadreplies',
844
                    'data-icon' => '&#xf0e6;',
845
                    'show' => !$user_info['is_guest'],
846
                ),
847
                'login' => array(
848
                    'title' => $txt['login'],
849
                    'href' => $scripturl . '?action=login',
850
                    'data-icon' => '&#xf023;',
851
                    'show' => $user_info['is_guest'],
852
                ),
853
854
                'register' => array(
855
                    'title' => $txt['register'],
856
                    'href' => $scripturl . '?action=register',
857
                    'data-icon' => '&#xf090;',
858
                    'show' => $user_info['is_guest'] && $context['can_register'],
859
                ),
860
                'like_stats' => array(
861
                    'title' => $txt['like_post_stats'],
862
                    'href' => $scripturl . '?action=likes;sa=likestats',
863
                    // 'data-icon' => '&#xf090;',
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
864
                    'show' => allowedTo('like_posts_stats'),
865
                ),
866
                'contact' => array(
867
                    'title' => $txt['contact'],
868
                    'href' => $scripturl . '?action=register;sa=contact',
869
                    'data-icon' => '&#xf095;',
870
                    'show' => $user_info['is_guest'] && !empty($modSettings['enable_contactform']) && $modSettings['enable_contactform'] == 'menu',
871
                ),
872
            );
873
874
            // Allow editing menu buttons easily.
875
            call_integration_hook('integrate_menu_buttons', array(&$buttons, &$menu_count));
876
877
            // Now we put the buttons in the context so the theme can use them.
878
            $menu_buttons = array();
879
            foreach ($buttons as $act => $button)
880
            {
881
                if (!empty($button['show']))
882
                {
883
                    $button['active_button'] = false;
884
885
                    // This button needs some action.
886
                    if (isset($button['action_hook']))
887
                        $needs_action_hook = true;
888
889
                    if (isset($button['counter']) && !empty($menu_count[$button['counter']]))
890
                    {
891
                        $button['alttitle'] = $button['title'] . ' [' . $menu_count[$button['counter']] . ']';
892
                        if (!empty($settings['menu_numeric_notice'][0]))
893
                        {
894
                            $button['title'] .= sprintf($settings['menu_numeric_notice'][0], $menu_count[$button['counter']]);
895
                            $button['indicator'] = true;
896
                        }
897
                    }
898
899
                    // Go through the sub buttons if there are any.
900
                    if (isset($button['sub_buttons']))
901
                    {
902
                        foreach ($button['sub_buttons'] as $key => $subbutton)
903
                        {
904
                            if (empty($subbutton['show']))
905
                                unset($button['sub_buttons'][$key]);
906
                            elseif (isset($subbutton['counter']) && !empty($menu_count[$subbutton['counter']]))
907
                            {
908
                                $button['sub_buttons'][$key]['alttitle'] = $subbutton['title'] . ' [' . $menu_count[$subbutton['counter']] . ']';
909
                                if (!empty($settings['menu_numeric_notice'][1]))
910
                                    $button['sub_buttons'][$key]['title'] .= sprintf($settings['menu_numeric_notice'][1], $menu_count[$subbutton['counter']]);
911
912
                                // 2nd level sub buttons next...
913
                                if (isset($subbutton['sub_buttons']))
914
                                {
915
                                    foreach ($subbutton['sub_buttons'] as $key2 => $subbutton2)
916
                                    {
917
                                        $button['sub_buttons'][$key]['sub_buttons'][$key2] = $subbutton2;
918
                                        if (empty($subbutton2['show']))
919
                                            unset($button['sub_buttons'][$key]['sub_buttons'][$key2]);
920
                                        elseif (isset($subbutton2['counter']) && !empty($menu_count[$subbutton2['counter']]))
921
                                        {
922
                                            $button['sub_buttons'][$key]['sub_buttons'][$key2]['alttitle'] = $subbutton2['title'] . ' [' . $menu_count[$subbutton2['counter']] . ']';
923
                                            if (!empty($settings['menu_numeric_notice'][2]))
924
                                                $button['sub_buttons'][$key]['sub_buttons'][$key2]['title'] .= sprintf($settings['menu_numeric_notice'][2], $menu_count[$subbutton2['counter']]);
925
                                            unset($menu_count[$subbutton2['counter']]);
926
                                        }
927
                                    }
928
                                }
929
                            }
930
                        }
931
                    }
932
933
                    $menu_buttons[$act] = $button;
934
                }
935
            }
936
937
            if (!empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= 2)
938
                cache_put_data('menu_buttons-' . implode('_', $user_info['groups']) . '-' . $user_info['language'], $menu_buttons, $cacheTime);
939
        }
940
941
        if (!empty($menu_buttons['profile']['sub_buttons']['logout']))
942
            $menu_buttons['profile']['sub_buttons']['logout']['href'] .= ';' . $context['session_var'] . '=' . $context['session_id'];
943
944
        $context['menu_buttons'] = $menu_buttons;
945
946
        // Figure out which action we are doing so we can set the active tab.
947
        // Default to home.
948
        $current_action = 'home';
949
950
        if (isset($context['menu_buttons'][$context['current_action']]))
951
            $current_action = $context['current_action'];
952
        elseif ($context['current_action'] == 'profile')
953
            $current_action = 'pm';
954
        elseif ($context['current_action'] == 'theme')
955
            $current_action = isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'pick' ? 'profile' : 'admin';
956
        elseif ($context['current_action'] == 'login2' || ($user_info['is_guest'] && $context['current_action'] == 'reminder'))
957
            $current_action = 'login';
958
        elseif ($context['current_action'] == 'groups' && $context['allow_moderation_center'])
959
            $current_action = 'moderate';
960
        elseif ($context['current_action'] == 'moderate' && $context['allow_admin'])
961
            $current_action = 'admin';
962
963
        // Not all actions are simple.
964
        if (!empty($needs_action_hook))
965
            call_integration_hook('integrate_current_action', array(&$current_action));
966
967
        if (isset($context['menu_buttons'][$current_action]))
968
            $context['menu_buttons'][$current_action]['active_button'] = true;
969
    }
970
971
    function loadThemeJavascript()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
972
    {
973
        global $settings, $context, $modSettings, $scripturl, $txt, $options;
974
975
        // Queue our Javascript
976
        loadJavascriptFile(array('elk_jquery_plugins.js', 'script.js', 'script_elk.js', 'theme.js'));
977
978
        // Default JS variables for use in every theme
979
        addJavascriptVar(array(
980
                'elk_theme_url' => JavaScriptEscape($settings['theme_url']),
981
                'elk_default_theme_url' => JavaScriptEscape($settings['default_theme_url']),
982
                'elk_images_url' => JavaScriptEscape($settings['images_url']),
983
                'elk_smiley_url' => JavaScriptEscape($modSettings['smileys_url']),
984
                'elk_scripturl' => '\'' . $scripturl . '\'',
985
                'elk_iso_case_folding' => $context['server']['iso_case_folding'] ? 'true' : 'false',
986
                'elk_charset' => '"UTF-8"',
987
                'elk_session_id' => JavaScriptEscape($context['session_id']),
988
                'elk_session_var' => JavaScriptEscape($context['session_var']),
989
                'elk_member_id' => $context['user']['id'],
990
                'ajax_notification_text' => JavaScriptEscape($txt['ajax_in_progress']),
991
                'ajax_notification_cancel_text' => JavaScriptEscape($txt['modify_cancel']),
992
                'help_popup_heading_text' => JavaScriptEscape($txt['help_popup']),
993
                'use_click_menu' => !empty($options['use_click_menu']) ? 'true' : 'false',
994
                'todayMod' => !empty($modSettings['todayMod']) ? (int) $modSettings['todayMod'] : 0)
995
        );
996
997
        // Auto video embedding enabled, then load the needed JS
998
        if (!empty($modSettings['enableVideoEmbeding']))
999
        {
1000
            theme()->autoEmbedVideo();
1001
        }
1002
1003
        // Prettify code tags? Load the needed JS and CSS.
1004
        if (!empty($modSettings['enableCodePrettify']))
1005
        {
1006
            theme()->addCodePrettify();
1007
        }
1008
1009
        theme()->relativeTimes();
1010
1011
        // If we think we have mail to send, let's offer up some possibilities... robots get pain (Now with scheduled task support!)
1012
        if ((!empty($modSettings['mail_next_send']) && $modSettings['mail_next_send'] < time() && empty($modSettings['mail_queue_use_cron'])) || empty($modSettings['next_task_time']) || $modSettings['next_task_time'] < time())
1013
        {
1014
            theme()->doScheduledSendMail();
1015
        }
1016
    }
1017
1018
    public function loadDefaultLayers()
0 ignored issues
show
Coding Style introduced by
loadDefaultLayers uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
1019
    {
1020
        global $settings;
1021
1022
        $simpleActions = array(
1023
            'quickhelp',
1024
            'printpage',
1025
            'quotefast',
1026
            'spellcheck',
1027
        );
1028
1029
        call_integration_hook('integrate_simple_actions', array(&$simpleActions));
1030
1031
        // Output is fully XML, so no need for the index template.
1032
        if (isset($_REQUEST['xml']))
1033
        {
1034
            loadLanguage('index+Addons');
1035
1036
            // @todo added because some $settings in template_init are necessary even in xml mode. Maybe move template_init to a settings file?
1037
            loadTemplate('index');
1038
            loadTemplate('Xml');
1039
            \Template_Layers::getInstance()->removeAll();
1040
        }
1041
        // These actions don't require the index template at all.
1042
        elseif (!empty($_REQUEST['action']) && in_array($_REQUEST['action'], $simpleActions))
1043
        {
1044
            loadLanguage('index+Addons');
1045
            \Template_Layers::getInstance()->removeAll();
1046
        }
1047
        else
1048
        {
1049
            // Custom templates to load, or just default?
1050
            if (isset($settings['theme_templates']))
1051
                $templates = explode(',', $settings['theme_templates']);
1052
            else
1053
                $templates = array('index');
1054
1055
            // Load each template...
1056
            foreach ($templates as $template)
1057
                loadTemplate($template);
1058
1059
            // ...and attempt to load their associated language files.
1060
            $required_files = implode('+', array_merge($templates, array('Addons')));
1061
            loadLanguage($required_files, '', false);
1062
1063
            // Custom template layers?
1064
            if (isset($settings['theme_layers']))
1065
                $layers = explode(',', $settings['theme_layers']);
1066
            else
1067
                $layers = array('html', 'body');
1068
1069
            $template_layers = \Template_Layers::getInstance(true);
1070
            foreach ($layers as $layer)
1071
                $template_layers->addBegin($layer);
1072
        }
1073
    }
1074
1075
    public function loadThemeVariant()
0 ignored issues
show
Coding Style introduced by
loadThemeVariant uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
loadThemeVariant uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
1076
    {
1077
        global $context, $settings, $options;
1078
1079
        // Overriding - for previews and that ilk.
1080
        if (!empty($_REQUEST['variant']))
1081
            $_SESSION['id_variant'] = $_REQUEST['variant'];
1082
1083
        // User selection?
1084
        if (empty($settings['disable_user_variant']) || allowedTo('admin_forum'))
1085
            $context['theme_variant'] = !empty($_SESSION['id_variant']) ? $_SESSION['id_variant'] : (!empty($options['theme_variant']) ? $options['theme_variant'] : '');
1086
1087
        // If not a user variant, select the default.
1088
        if ($context['theme_variant'] == '' || !in_array($context['theme_variant'], $settings['theme_variants']))
1089
            $context['theme_variant'] = !empty($settings['default_variant']) && in_array($settings['default_variant'], $settings['theme_variants']) ? $settings['default_variant'] : $settings['theme_variants'][0];
1090
1091
        // Do this to keep things easier in the templates.
1092
        $context['theme_variant'] = '_' . $context['theme_variant'];
1093
        $context['theme_variant_url'] = $context['theme_variant'] . '/';
1094
1095
        // The most efficient way of writing multi themes is to use a master index.css plus variant.css files.
1096
        if (!empty($context['theme_variant']))
1097
            loadCSSFile($context['theme_variant'] . '/index' . $context['theme_variant'] . '.css');
1098
    }
1099
}