Completed
Pull Request — development (#2329)
by Joshua
09:15
created

Theme::loadThemeVariant()   C

Complexity

Conditions 11
Paths 100

Size

Total Lines 24
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 0
loc 24
rs 5.3307
c 2
b 0
f 0
cc 11
eloc 12
nc 100
nop 0

How to fix   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
    public function templateJquery()
128
    {
129
        global $modSettings, $settings;
130
131
        // Using a specified version of jquery or what was shipped 2.1.4  / 1.11.4
132
        $jquery_version = (!empty($modSettings['jquery_default']) && !empty($modSettings['jquery_version'])) ? $modSettings['jquery_version'] : '2.1.4';
133
        $jqueryui_version = (!empty($modSettings['jqueryui_default']) && !empty($modSettings['jqueryui_version'])) ? $modSettings['jqueryui_version'] : '1.11.4';
134
135
        switch ($modSettings['jquery_source'])
136
        {
137
            // Only getting the files from the CDN?
138
            case 'cdn':
139
                echo '
140
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/' . $jquery_version . '/jquery.min.js" id="jquery"></script>',
141
                (!empty($modSettings['jquery_include_ui']) ? '
142
	<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/' . $jqueryui_version . '/jquery-ui.min.js" id="jqueryui"></script>' : '');
143
                break;
144
            // Just use the local file
145
            case 'local':
146
                echo '
147
	<script src="', $settings['default_theme_url'], '/scripts/jquery-' . $jquery_version . '.min.js" id="jquery"></script>',
148
                (!empty($modSettings['jquery_include_ui']) ? '
149
	<script src="' . $settings['default_theme_url'] . '/scripts/jquery-ui-' . $jqueryui_version . '.min.js" id="jqueryui"></script>' : '');
150
                break;
151
            // CDN with local fallback
152
            case 'auto':
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
                echo '
158
	<script><!-- // --><![CDATA[
159
		window.jQuery || document.write(\'<script src="', $settings['default_theme_url'], '/scripts/jquery-' . $jquery_version . '.min.js"><\/script>\');',
160
                (!empty($modSettings['jquery_include_ui']) ? '
161
		window.jQuery.ui || document.write(\'<script src="' . $settings['default_theme_url'] . '/scripts/jquery-ui-' . $jqueryui_version . '.min.js"><\/script>\')' : ''), '
162
	// ]]></script>';
163
                break;
164
        }
165
    }
166
167
    protected function templateJavascriptFiles($do_defered)
168
    {
169
        global $boardurl, $modSettings;
170
        if (!empty($modSettings['minify_css_js']))
171
        {
172
            $combiner = new \Site_Combiner(CACHEDIR, $boardurl . '/cache');
173
            $combine_name = $combiner->site_js_combine($this->js_files, $do_defered);
174
175
            call_integration_hook('post_javascript_combine', array(&$combine_name, $combiner));
176
177
            if (!empty($combine_name))
178
                echo '
179
	<script src="', $combine_name, '" id="jscombined', $do_defered ? 'bottom' : 'top', '"></script>';
180
            // While we have Javascript files to place in the template
181
            foreach ($combiner->getSpares() as $id => $js_file)
182
            {
183
                if ((!$do_defered && empty($js_file['options']['defer'])) || ($do_defered && !empty($js_file['options']['defer'])))
184
                    echo '
185
	<script src="', $js_file['filename'], '" id="', $id, '"', !empty($js_file['options']['async']) ? ' async="async"' : '', '></script>';
186
            }
187
        }
188
        else
189
        {
190
            // While we have Javascript files to place in the template
191
            foreach ($this->js_files as $id => $js_file)
192
            {
193
                if ((!$do_defered && empty($js_file['options']['defer'])) || ($do_defered && !empty($js_file['options']['defer'])))
194
                    echo '
195
	<script src="', $js_file['filename'], '" id="', $id, '"', !empty($js_file['options']['async']) ? ' async="async"' : '', '></script>';
196
            }
197
        }
198
    }
199
    /**
200
     * Output the Javascript files
201
     *
202
     * What it does:
203
     * - tabbing in this function is to make the HTML source look proper
204
     * - outputs jQuery/jQueryUI from the proper source (local/CDN)
205
     * - if defered is set function will output all JS (source & inline) set to load at page end
206
     * - if the admin option to combine files is set, will use Combiner.class
207
     *
208
     * @param bool $do_defered = false
209
     */
210
    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...
211
    {
212
        global $modSettings;
213
214
        // First up, load jQuery and jQuery UI
215
        if (isset($modSettings['jquery_source']) && !$do_defered)
216
        {
217
            $this->templateJquery();
218
        }
219
220
        // Use this hook to work with Javascript files and vars pre output
221
        call_integration_hook('pre_javascript_output');
222
223
        // Combine and minify javascript source files to save bandwidth and requests
224
        if (!empty($this->js_files))
225
        {
226
            $this->templateJavascriptFiles($do_defered);
227
        }
228
229
        // Build the declared Javascript variables script
230
        $js_vars = array();
231
        if (!empty($this->js_vars) && !$do_defered)
232
        {
233
            foreach ($this->js_vars as $var => $value)
234
                $js_vars[] = $var . ' = ' . $value;
235
236
            // Newlines and tabs are here to make it look nice in the page source view, stripped if minimized though
237
            $this->js_inline['standard'][] = 'var ' . implode(",\n\t\t\t", $js_vars) . ';';
238
        }
239
240
        // Inline JavaScript - Actually useful some times!
241
        if (!empty($this->js_inline))
242
        {
243
            // Defered output waits until we are defering !
244
            if (!empty($this->js_inline['defer']) && $do_defered)
245
            {
246
                // Combine them all in to one output
247
                $this->js_inline['defer'] = array_map('trim', $this->js_inline['defer']);
248
                $inline_defered_code = implode("\n\t\t", $this->js_inline['defer']);
249
250
                // Output the defered script
251
                echo '
252
	<script><!-- // --><![CDATA[
253
		', $inline_defered_code, '
254
	// ]]></script>';
255
            }
256
257
            // Standard output, and our javascript vars, get output when we are not on a defered call
258
            if (!empty($this->js_inline['standard']) && !$do_defered)
259
            {
260
                $this->js_inline['standard'] = array_map('trim', $this->js_inline['standard']);
261
262
                // And output the js vars and standard scripts to the page
263
                echo '
264
	<script><!-- // --><![CDATA[
265
		', implode("\n\t\t", $this->js_inline['standard']), '
266
	// ]]></script>';
267
            }
268
        }
269
    }
270
271
    /**
272
     * Output the CSS files
273
     *
274
     * What it does:
275
     *  - If the admin option to combine files is set, will use Combiner.class
276
     */
277
    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...
278
    {
279
        global $modSettings, $boardurl;
280
281
        // Use this hook to work with CSS files pre output
282
        call_integration_hook('pre_css_output');
283
284
        // Combine and minify the CSS files to save bandwidth and requests?
285
        if (!empty($this->css_files))
286
        {
287
            if (!empty($modSettings['minify_css_js']))
288
            {
289
                $combiner = new \Site_Combiner(CACHEDIR, $boardurl . '/cache');
290
                $combine_name = $combiner->site_css_combine($this->css_files);
291
292
                call_integration_hook('post_css_combine', array(&$combine_name, $combiner));
293
294
                if (!empty($combine_name))
295
                    echo '
296
	<link rel="stylesheet" href="', $combine_name, '" id="csscombined" />';
297
298
                foreach ($combiner->getSpares() as $id => $file)
299
                    echo '
300
	<link rel="stylesheet" href="', $file['filename'], '" id="', $id,'" />';
301
            }
302
            else
303
            {
304
                foreach ($this->css_files as $id => $file)
305
                    echo '
306
	<link rel="stylesheet" href="', $file['filename'], '" id="', $id,'" />';
307
            }
308
        }
309
    }
310
311
    /**
312
     * Calls on template_show_error from index.template.php to show warnings
313
     * and security errors for admins
314
     */
315
    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...
316
    {
317
        global $context, $txt;
318
319
        if (!empty($context['security_controls_files']))
320
        {
321
            $context['security_controls_files']['type'] = 'serious';
322
            template_show_error('security_controls_files');
323
        }
324
325
        if (!empty($context['security_controls_query']))
326
        {
327
            $context['security_controls_query']['type'] = 'serious';
328
            template_show_error('security_controls_query');
329
        }
330
331
        if (!empty($context['security_controls_ban']))
332
        {
333
            $context['security_controls_ban']['type'] = 'serious';
334
            template_show_error('security_controls_ban');
335
        }
336
337
        if (!empty($context['new_version_updates']))
338
        {
339
            template_show_error('new_version_updates');
340
        }
341
342
        // Any special notices to remind the admin about?
343
        if (!empty($context['warning_controls']))
344
        {
345
            $context['warning_controls']['errors'] = $context['warning_controls'];
346
            $context['warning_controls']['title'] = $txt['admin_warning_title'];
347
            $context['warning_controls']['type'] = 'warning';
348
            template_show_error('warning_controls');
349
        }
350
    }
351
352
    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...
353
    {
354
        loadCSSFile('prettify.css');
355
        loadJavascriptFile('prettify.min.js', array('defer' => true));
356
357
        addInlineJavascript('
358
		$(document).ready(function(){
359
			prettyPrint();
360
		});', true);
361
    }
362
363
    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...
364
    {
365
        global $txt;
366
367
        addInlineJavascript('
368
		var oEmbedtext = ({
369
			preview_image : ' . JavaScriptEscape($txt['preview_image']) . ',
370
			ctp_video : ' . JavaScriptEscape($txt['ctp_video']) . ',
371
			hide_video : ' . JavaScriptEscape($txt['hide_video']) . ',
372
			youtube : ' . JavaScriptEscape($txt['youtube']) . ',
373
			vimeo : ' . JavaScriptEscape($txt['vimeo']) . ',
374
			dailymotion : ' . JavaScriptEscape($txt['dailymotion']) . '
375
		});', true);
376
377
        loadJavascriptFile('elk_jquery_embed.js', array('defer' => true));
378
    }
379
380
    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...
381
    {
382
        global $modSettings;
383
384
        if (isBrowser('possibly_robot'))
385
        {
386
            // @todo Maybe move this somewhere better?!
387
            $controller = new \ScheduledTasks_Controller();
388
389
            // What to do, what to do?!
390
            if (empty($modSettings['next_task_time']) || $modSettings['next_task_time'] < time())
391
                $controller->action_autotask();
392
            else
393
                $controller->action_reducemailqueue();
394
        }
395
        else
396
        {
397
            $type = empty($modSettings['next_task_time']) || $modSettings['next_task_time'] < time() ? 'task' : 'mailq';
398
            $ts = $type == 'mailq' ? $modSettings['mail_next_send'] : $modSettings['next_task_time'];
399
400
            addInlineJavascript('
401
		function elkAutoTask()
402
		{
403
			var tempImage = new Image();
404
			tempImage.src = elk_scripturl + "?scheduled=' . $type . ';ts=' . $ts . '";
405
		}
406
		window.setTimeout("elkAutoTask();", 1);', true);
407
        }
408
    }
409
410
    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...
411
    {
412
        global $modSettings, $context, $txt;
413
414
        // Relative times?
415
        if (!empty($modSettings['todayMod']) && $modSettings['todayMod'] > 2)
416
        {
417
            addInlineJavascript('
418
		var oRttime = ({
419
			referenceTime : ' . forum_time() * 1000 . ',
420
			now : ' . JavaScriptEscape($txt['rt_now']) . ',
421
			minute : ' . JavaScriptEscape($txt['rt_minute']) . ',
422
			minutes : ' . JavaScriptEscape($txt['rt_minutes']) . ',
423
			hour : ' . JavaScriptEscape($txt['rt_hour']) . ',
424
			hours : ' . JavaScriptEscape($txt['rt_hours']) . ',
425
			day : ' . JavaScriptEscape($txt['rt_day']) . ',
426
			days : ' . JavaScriptEscape($txt['rt_days']) . ',
427
			week : ' . JavaScriptEscape($txt['rt_week']) . ',
428
			weeks : ' . JavaScriptEscape($txt['rt_weeks']) . ',
429
			month : ' . JavaScriptEscape($txt['rt_month']) . ',
430
			months : ' . JavaScriptEscape($txt['rt_months']) . ',
431
			year : ' . JavaScriptEscape($txt['rt_year']) . ',
432
			years : ' . JavaScriptEscape($txt['rt_years']) . ',
433
		});
434
		updateRelativeTime();', true);
435
            $context['using_relative_time'] = true;
436
        }
437
    }
438
439
    /**
440
     * Sets up the basic theme context stuff.
441
     *
442
     * @param bool $forceload = false
443
     */
444
    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...
445
    {
446
        global $modSettings, $user_info, $scripturl, $context, $settings, $options, $txt;
447
448
        static $loaded = false;
449
450
        // Under SSI this function can be called more then once.  That can cause some problems.
451
        // So only run the function once unless we are forced to run it again.
452
        if ($loaded && !$forceload)
453
            return;
454
455
        $loaded = true;
456
457
        $context['current_time'] = standardTime(time(), false);
458
        $context['current_action'] = isset($_GET['action']) ? $_GET['action'] : '';
459
        $context['show_quick_login'] = !empty($modSettings['enableVBStyleLogin']) && $user_info['is_guest'];
460
461
        $bbc_parser = \BBC\ParserWrapper::getInstance();
462
463
        // Get some news...
464
        $context['news_lines'] = array_filter(explode("\n", str_replace("\r", '', trim(addslashes($modSettings['news'])))));
465
        for ($i = 0, $n = count($context['news_lines']); $i < $n; $i++)
466
        {
467
            if (trim($context['news_lines'][$i]) == '')
468
                continue;
469
470
            // Clean it up for presentation ;).
471
            $context['news_lines'][$i] = $bbc_parser->parseNews(stripslashes(trim($context['news_lines'][$i])));
472
        }
473
474
        if (!empty($context['news_lines']))
475
        {
476
            $context['random_news_line'] = $context['news_lines'][mt_rand(0, count($context['news_lines']) - 1)];
477
            $context['upper_content_callbacks'][] = 'news_fader';
478
        }
479
480
        if (!$user_info['is_guest'])
481
        {
482
            $context['user']['messages'] = &$user_info['messages'];
483
            $context['user']['unread_messages'] = &$user_info['unread_messages'];
484
            $context['user']['mentions'] = &$user_info['mentions'];
485
486
            // Personal message popup...
487
            if ($user_info['unread_messages'] > (isset($_SESSION['unread_messages']) ? $_SESSION['unread_messages'] : 0))
488
                $context['user']['popup_messages'] = true;
489
            else
490
                $context['user']['popup_messages'] = false;
491
            $_SESSION['unread_messages'] = $user_info['unread_messages'];
492
493
            $context['user']['avatar'] = array(
494
                'href' => !empty($user_info['avatar']['href']) ? $user_info['avatar']['href'] : '',
495
                'image' => !empty($user_info['avatar']['image']) ? $user_info['avatar']['image'] : '',
496
            );
497
498
            // @deprecated since 1.0.2
499
            if (!empty($modSettings['avatar_max_width']))
500
                $context['user']['avatar']['width'] = $modSettings['avatar_max_width'];
501
502
            // @deprecated since 1.0.2
503
            if (!empty($modSettings['avatar_max_height']))
504
                $context['user']['avatar']['height'] = $modSettings['avatar_max_height'];
505
506
            // Figure out how long they've been logged in.
507
            $context['user']['total_time_logged_in'] = array(
508
                'days' => floor($user_info['total_time_logged_in'] / 86400),
509
                'hours' => floor(($user_info['total_time_logged_in'] % 86400) / 3600),
510
                'minutes' => floor(($user_info['total_time_logged_in'] % 3600) / 60)
511
            );
512
        }
513
        else
514
        {
515
            $context['user']['messages'] = 0;
516
            $context['user']['unread_messages'] = 0;
517
            $context['user']['mentions'] = 0;
518
            $context['user']['avatar'] = array();
519
            $context['user']['total_time_logged_in'] = array('days' => 0, 'hours' => 0, 'minutes' => 0);
520
            $context['user']['popup_messages'] = false;
521
522
            if (!empty($modSettings['registration_method']) && $modSettings['registration_method'] == 1)
523
                $txt['welcome_guest'] .= $txt['welcome_guest_activate'];
524
            $txt['welcome_guest'] = replaceBasicActionUrl($txt['welcome_guest']);
525
526
            // If we've upgraded recently, go easy on the passwords.
527
            if (!empty($modSettings['enable_password_conversion']))
528
                $context['disable_login_hashing'] = true;
529
        }
530
531
        // Setup the main menu items.
532
        $this->setupMenuContext();
533
534
        if (empty($settings['theme_version']))
535
            $context['show_vBlogin'] = $context['show_quick_login'];
536
537
        // This is here because old index templates might still use it.
538
        $context['show_news'] = !empty($settings['enable_news']);
539
540
        $context['additional_dropdown_search'] = prepareSearchEngines();
541
542
        // This is done to allow theme authors to customize it as they want.
543
        $context['show_pm_popup'] = $context['user']['popup_messages'] && !empty($options['popup_messages']) && (!isset($_REQUEST['action']) || $_REQUEST['action'] != 'pm');
544
545
        // Add the PM popup here instead. Theme authors can still override it simply by editing/removing the 'fPmPopup' in the array.
546
        if ($context['show_pm_popup'])
547
            addInlineJavascript('
548
		$(document).ready(function(){
549
			new smc_Popup({
550
				heading: ' . JavaScriptEscape($txt['show_personal_messages_heading']) . ',
551
				content: ' . JavaScriptEscape(sprintf($txt['show_personal_messages'], $context['user']['unread_messages'], $scripturl . '?action=pm')) . ',
552
				icon: elk_images_url + \'/im_sm_newmsg.png\'
553
			});
554
		});', true);
555
556
        // This looks weird, but it's because BoardIndex.controller.php references the variable.
557
        $context['common_stats']['latest_member'] = array(
558
            'id' => $modSettings['latestMember'],
559
            'name' => $modSettings['latestRealName'],
560
            'href' => $scripturl . '?action=profile;u=' . $modSettings['latestMember'],
561
            'link' => '<a href="' . $scripturl . '?action=profile;u=' . $modSettings['latestMember'] . '">' . $modSettings['latestRealName'] . '</a>',
562
        );
563
        $context['common_stats'] = array(
564
            'total_posts' => comma_format($modSettings['totalMessages']),
565
            'total_topics' => comma_format($modSettings['totalTopics']),
566
            'total_members' => comma_format($modSettings['totalMembers']),
567
            'latest_member' => $context['common_stats']['latest_member'],
568
        );
569
        $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']);
570
571
        if (empty($settings['theme_version']))
572
            addJavascriptVar(array('elk_scripturl' => '\'' . $scripturl . '\''));
573
574
        if (!isset($context['page_title']))
575
            $context['page_title'] = '';
576
577
        // Set some specific vars.
578
        $context['page_title_html_safe'] = \Util::htmlspecialchars(un_htmlspecialchars($context['page_title'])) . (!empty($context['current_page']) ? ' - ' . $txt['page'] . ' ' . ($context['current_page'] + 1) : '');
579
580
        // Load a custom CSS file?
581
        if (file_exists($settings['theme_dir'] . '/css/custom.css'))
582
            loadCSSFile('custom.css');
583
        if (!empty($context['theme_variant']) && file_exists($settings['theme_dir'] . '/css/' . $context['theme_variant'] . '/custom' . $context['theme_variant'] . '.css'))
584
            loadCSSFile($context['theme_variant'] . '/custom' . $context['theme_variant'] . '.css');
585
    }
586
587
    /**
588
     * Sets up all of the top menu buttons
589
     *
590
     * What it does:
591
     * - Defines every master item in the menu, as well as any sub-items
592
     * - Ensures the chosen action is set so the menu is highlighted
593
     * - Saves them in the cache if it is available and on
594
     * - Places the results in $context
595
     */
596
    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...
597
    {
598
        global $context, $modSettings, $user_info, $txt, $scripturl, $settings;
599
600
        // Set up the menu privileges.
601
        $context['allow_search'] = !empty($modSettings['allow_guestAccess']) ? allowedTo('search_posts') : (!$user_info['is_guest'] && allowedTo('search_posts'));
602
        $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'));
603
        $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'));
604
        $context['allow_memberlist'] = allowedTo('view_mlist');
605
        $context['allow_calendar'] = allowedTo('calendar_view') && !empty($modSettings['cal_enabled']);
606
        $context['allow_moderation_center'] = $context['user']['can_mod'];
607
        $context['allow_pm'] = allowedTo('pm_read');
608
609
        if ($context['allow_search'])
610
            $context['theme_header_callbacks'] = elk_array_insert($context['theme_header_callbacks'], 'login_bar', array('search_bar'), 'after');
611
612
        $cacheTime = $modSettings['lastActive'] * 60;
613
614
        // Update the Moderation menu items with action item totals
615
        if ($context['allow_moderation_center'])
616
        {
617
            // Get the numbers for the menu ...
618
            require_once(SUBSDIR . '/Moderation.subs.php');
619
            $menu_count = loadModeratorMenuCounts();
620
        }
621
622
        $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...
623
        $menu_count['mentions'] = $context['user']['mentions'];
624
625
        // All the buttons we can possible want and then some, try pulling the final list of buttons from cache first.
626
        if (($menu_buttons = cache_get_data('menu_buttons-' . implode('_', $user_info['groups']) . '-' . $user_info['language'], $cacheTime)) === null || time() - $cacheTime <= $modSettings['settings_updated'])
627
        {
628
            // Start things up: this is what we know by default
629
            require_once(SUBSDIR . '/Menu.subs.php');
630
            $buttons = array(
631
                'home' => array(
632
                    'title' => $txt['community'],
633
                    'href' => $scripturl,
634
                    'data-icon' => '&#xf015;',
635
                    'show' => true,
636
                    'sub_buttons' => array(
637
                        'help' => array(
638
                            'title' => $txt['help'],
639
                            'href' => $scripturl . '?action=help',
640
                            'show' => true,
641
                        ),
642
                        'search' => array(
643
                            'title' => $txt['search'],
644
                            'href' => $scripturl . '?action=search',
645
                            'show' => $context['allow_search'],
646
                        ),
647
                        'calendar' => array(
648
                            'title' => $txt['calendar'],
649
                            'href' => $scripturl . '?action=calendar',
650
                            'show' => $context['allow_calendar'],
651
                        ),
652
                        'memberlist' => array(
653
                            'title' => $txt['members_title'],
654
                            'href' => $scripturl . '?action=memberlist',
655
                            'show' => $context['allow_memberlist'],
656
                        ),
657
                        'recent' => array(
658
                            'title' => $txt['recent_posts'],
659
                            'href' => $scripturl . '?action=recent',
660
                            'show' => true,
661
                        ),
662
                    ),
663
                )
664
            );
665
666
            // Will change title correctly if user is either a mod or an admin.
667
            // Button highlighting works properly too (see current action stuffz).
668
            if ($context['allow_admin'])
669
            {
670
                $buttons['admin'] = array(
671
                    'title' => $context['current_action'] !== 'moderate' ? $txt['admin'] : $txt['moderate'],
672
                    'counter' => 'grand_total',
673
                    'href' => $scripturl . '?action=admin',
674
                    'data-icon' => '&#xf013;',
675
                    'show' => true,
676
                    'sub_buttons' => array(
677
                        'admin_center' => array(
678
                            'title' => $txt['admin_center'],
679
                            'href' => $scripturl . '?action=admin',
680
                            'show' => $context['allow_admin'],
681
                        ),
682
                        'featuresettings' => array(
683
                            'title' => $txt['modSettings_title'],
684
                            'href' => $scripturl . '?action=admin;area=featuresettings',
685
                            'show' => allowedTo('admin_forum'),
686
                        ),
687
                        'packages' => array(
688
                            'title' => $txt['package'],
689
                            'href' => $scripturl . '?action=admin;area=packages',
690
                            'show' => allowedTo('admin_forum'),
691
                        ),
692
                        'permissions' => array(
693
                            'title' => $txt['edit_permissions'],
694
                            'href' => $scripturl . '?action=admin;area=permissions',
695
                            'show' => allowedTo('manage_permissions'),
696
                        ),
697
                        'errorlog' => array(
698
                            'title' => $txt['errlog'],
699
                            'href' => $scripturl . '?action=admin;area=logs;sa=errorlog;desc',
700
                            'show' => allowedTo('admin_forum') && !empty($modSettings['enableErrorLogging']),
701
                        ),
702
                        'moderate_sub' => array(
703
                            'title' => $txt['moderate'],
704
                            'counter' => 'grand_total',
705
                            'href' => $scripturl . '?action=moderate',
706
                            'show' => $context['allow_moderation_center'],
707
                            'sub_buttons' => array(
708
                                'reports' => array(
709
                                    'title' => $txt['mc_reported_posts'],
710
                                    'counter' => 'reports',
711
                                    'href' => $scripturl . '?action=moderate;area=reports',
712
                                    'show' => !empty($user_info['mod_cache']) && $user_info['mod_cache']['bq'] != '0=1',
713
                                ),
714
                                'modlog' => array(
715
                                    'title' => $txt['modlog_view'],
716
                                    'href' => $scripturl . '?action=moderate;area=modlog',
717
                                    'show' => !empty($modSettings['modlog_enabled']) && !empty($user_info['mod_cache']) && $user_info['mod_cache']['bq'] != '0=1',
718
                                ),
719
                                'attachments' => array(
720
                                    'title' => $txt['mc_unapproved_attachments'],
721
                                    'counter' => 'attachments',
722
                                    'href' => $scripturl . '?action=moderate;area=attachmod;sa=attachments',
723
                                    'show' => $modSettings['postmod_active'] && !empty($user_info['mod_cache']['ap']),
724
                                ),
725
                                'poststopics' => array(
726
                                    'title' => $txt['mc_unapproved_poststopics'],
727
                                    'counter' => 'postmod',
728
                                    'href' => $scripturl . '?action=moderate;area=postmod;sa=posts',
729
                                    'show' => $modSettings['postmod_active'] && !empty($user_info['mod_cache']['ap']),
730
                                ),
731
                                'postbyemail' => array(
732
                                    'title' => $txt['mc_emailerror'],
733
                                    'counter' => 'emailmod',
734
                                    'href' => $scripturl . '?action=admin;area=maillist;sa=emaillist',
735
                                    'show' => !empty($modSettings['maillist_enabled']) && allowedTo('approve_emails'),
736
                                ),
737
                            ),
738
                        ),
739
                    ),
740
                );
741
            }
742
            else
743
            {
744
                $buttons['admin'] = array(
745
                    'title' => $txt['moderate'],
746
                    'counter' => 'grand_total',
747
                    'href' => $scripturl . '?action=moderate',
748
                    'data-icon' => '&#xf013;',
749
                    'show' => $context['allow_moderation_center'],
750
                    'sub_buttons' => array(
751
                        'reports' => array(
752
                            'title' => $txt['mc_reported_posts'],
753
                            'counter' => 'reports',
754
                            'href' => $scripturl . '?action=moderate;area=reports',
755
                            'show' => !empty($user_info['mod_cache']) && $user_info['mod_cache']['bq'] != '0=1',
756
                        ),
757
                        'modlog' => array(
758
                            'title' => $txt['modlog_view'],
759
                            'href' => $scripturl . '?action=moderate;area=modlog',
760
                            'show' => !empty($modSettings['modlog_enabled']) && !empty($user_info['mod_cache']) && $user_info['mod_cache']['bq'] != '0=1',
761
                        ),
762
                        'attachments' => array(
763
                            'title' => $txt['mc_unapproved_attachments'],
764
                            'counter' => 'attachments',
765
                            'href' => $scripturl . '?action=moderate;area=attachmod;sa=attachments',
766
                            'show' => $modSettings['postmod_active'] && !empty($user_info['mod_cache']['ap']),
767
                        ),
768
                        'poststopics' => array(
769
                            'title' => $txt['mc_unapproved_poststopics'],
770
                            'counter' => 'postmod',
771
                            'href' => $scripturl . '?action=moderate;area=postmod;sa=posts',
772
                            'show' => $modSettings['postmod_active'] && !empty($user_info['mod_cache']['ap']),
773
                        ),
774
                        'postbyemail' => array(
775
                            'title' => $txt['mc_emailerror'],
776
                            'counter' => 'emailmod',
777
                            'href' => $scripturl . '?action=admin;area=maillist;sa=emaillist',
778
                            'show' => !empty($modSettings['maillist_enabled']) && allowedTo('approve_emails'),
779
                        ),
780
                    ),
781
                );
782
            }
783
784
            $buttons += array(
785
                'profile' => array(
786
                    'title' => (!empty($user_info['avatar']['href']) ? '<img class="avatar" src="' . $user_info['avatar']['href'] . '" alt="" /> ' : '') . (!empty($modSettings['displayMemberNames']) ? $user_info['name'] : $txt['account_short']),
787
                    'href' => $scripturl . '?action=profile',
788
                    'data-icon' => '&#xf007;',
789
                    'show' => $context['allow_edit_profile'],
790
                    'sub_buttons' => array(
791
                        'account' => array(
792
                            'title' => $txt['account'],
793
                            'href' => $scripturl . '?action=profile;area=account',
794
                            'show' => allowedTo(array('profile_identity_any', 'profile_identity_own', 'manage_membergroups')),
795
                        ),
796
                        'forumprofile' => array(
797
                            'title' => $txt['forumprofile'],
798
                            'href' => $scripturl . '?action=profile;area=forumprofile',
799
                            'show' => allowedTo(array('profile_extra_any', 'profile_extra_own')),
800
                        ),
801
                        'theme' => array(
802
                            'title' => $txt['theme'],
803
                            'href' => $scripturl . '?action=profile;area=theme',
804
                            'show' => allowedTo(array('profile_extra_any', 'profile_extra_own', 'profile_extra_any')),
805
                        ),
806
                        'logout' => array(
807
                            'title' => $txt['logout'],
808
                            'href' => $scripturl . '?action=logout',
809
                            'show' => !$user_info['is_guest'],
810
                        ),
811
                    ),
812
                ),
813
                // @todo Look at doing something here, to provide instant access to inbox when using click menus.
814
                // @todo A small pop-up anchor seems like the obvious way to handle it. ;)
815
                'pm' => array(
816
                    'title' => $txt['pm_short'],
817
                    'counter' => 'unread_messages',
818
                    'href' => $scripturl . '?action=pm',
819
                    'data-icon' => '&#xf0e0;',
820
                    'show' => $context['allow_pm'],
821
                    'sub_buttons' => array(
822
                        'pm_read' => array(
823
                            'title' => $txt['pm_menu_read'],
824
                            'href' => $scripturl . '?action=pm',
825
                            'show' => allowedTo('pm_read'),
826
                        ),
827
                        'pm_send' => array(
828
                            'title' => $txt['pm_menu_send'],
829
                            'href' => $scripturl . '?action=pm;sa=send',
830
                            'show' => allowedTo('pm_send'),
831
                        ),
832
                    ),
833
                ),
834
                'mentions' => array(
835
                    'title' => $txt['mention'],
836
                    'counter' => 'mentions',
837
                    'href' => $scripturl . '?action=mentions',
838
                    'data-icon' => '&#xf0f3;',
839
                    'show' => !$user_info['is_guest'] && !empty($modSettings['mentions_enabled']),
840
                ),
841
                // The old language string made no sense, and was too long.
842
                // "New posts" is better, because there are probably a pile
843
                // of old unread posts, and they wont be reached from this button.
844
                'unread' => array(
845
                    'title' => $txt['view_unread_category'],
846
                    'href' => $scripturl . '?action=unread',
847
                    'data-icon' => '&#xf086;',
848
                    'show' => !$user_info['is_guest'],
849
                ),
850
                // The old language string made no sense, and was too long.
851
                // "New replies" is better, because there are "updated topics"
852
                // that the user has never posted in and doesn't care about.
853
                'unreadreplies' => array(
854
                    'title' => $txt['view_replies_category'],
855
                    'href' => $scripturl . '?action=unreadreplies',
856
                    'data-icon' => '&#xf0e6;',
857
                    'show' => !$user_info['is_guest'],
858
                ),
859
                'login' => array(
860
                    'title' => $txt['login'],
861
                    'href' => $scripturl . '?action=login',
862
                    'data-icon' => '&#xf023;',
863
                    'show' => $user_info['is_guest'],
864
                ),
865
866
                'register' => array(
867
                    'title' => $txt['register'],
868
                    'href' => $scripturl . '?action=register',
869
                    'data-icon' => '&#xf090;',
870
                    'show' => $user_info['is_guest'] && $context['can_register'],
871
                ),
872
                'like_stats' => array(
873
                    'title' => $txt['like_post_stats'],
874
                    'href' => $scripturl . '?action=likes;sa=likestats',
875
                    // '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...
876
                    'show' => allowedTo('like_posts_stats'),
877
                ),
878
                'contact' => array(
879
                    'title' => $txt['contact'],
880
                    'href' => $scripturl . '?action=register;sa=contact',
881
                    'data-icon' => '&#xf095;',
882
                    'show' => $user_info['is_guest'] && !empty($modSettings['enable_contactform']) && $modSettings['enable_contactform'] == 'menu',
883
                ),
884
            );
885
886
            // Allow editing menu buttons easily.
887
            call_integration_hook('integrate_menu_buttons', array(&$buttons, &$menu_count));
888
889
            // Now we put the buttons in the context so the theme can use them.
890
            $menu_buttons = array();
891
            foreach ($buttons as $act => $button)
892
            {
893
                if (!empty($button['show']))
894
                {
895
                    $button['active_button'] = false;
896
897
                    // This button needs some action.
898
                    if (isset($button['action_hook']))
899
                        $needs_action_hook = true;
900
901
                    if (isset($button['counter']) && !empty($menu_count[$button['counter']]))
902
                    {
903
                        $button['alttitle'] = $button['title'] . ' [' . $menu_count[$button['counter']] . ']';
904
                        if (!empty($settings['menu_numeric_notice'][0]))
905
                        {
906
                            $button['title'] .= sprintf($settings['menu_numeric_notice'][0], $menu_count[$button['counter']]);
907
                            $button['indicator'] = true;
908
                        }
909
                    }
910
911
                    // Go through the sub buttons if there are any.
912
                    if (isset($button['sub_buttons']))
913
                    {
914
                        foreach ($button['sub_buttons'] as $key => $subbutton)
915
                        {
916
                            if (empty($subbutton['show']))
917
                                unset($button['sub_buttons'][$key]);
918
                            elseif (isset($subbutton['counter']) && !empty($menu_count[$subbutton['counter']]))
919
                            {
920
                                $button['sub_buttons'][$key]['alttitle'] = $subbutton['title'] . ' [' . $menu_count[$subbutton['counter']] . ']';
921
                                if (!empty($settings['menu_numeric_notice'][1]))
922
                                    $button['sub_buttons'][$key]['title'] .= sprintf($settings['menu_numeric_notice'][1], $menu_count[$subbutton['counter']]);
923
924
                                // 2nd level sub buttons next...
925
                                if (isset($subbutton['sub_buttons']))
926
                                {
927
                                    foreach ($subbutton['sub_buttons'] as $key2 => $subbutton2)
928
                                    {
929
                                        $button['sub_buttons'][$key]['sub_buttons'][$key2] = $subbutton2;
930
                                        if (empty($subbutton2['show']))
931
                                            unset($button['sub_buttons'][$key]['sub_buttons'][$key2]);
932
                                        elseif (isset($subbutton2['counter']) && !empty($menu_count[$subbutton2['counter']]))
933
                                        {
934
                                            $button['sub_buttons'][$key]['sub_buttons'][$key2]['alttitle'] = $subbutton2['title'] . ' [' . $menu_count[$subbutton2['counter']] . ']';
935
                                            if (!empty($settings['menu_numeric_notice'][2]))
936
                                                $button['sub_buttons'][$key]['sub_buttons'][$key2]['title'] .= sprintf($settings['menu_numeric_notice'][2], $menu_count[$subbutton2['counter']]);
937
                                            unset($menu_count[$subbutton2['counter']]);
938
                                        }
939
                                    }
940
                                }
941
                            }
942
                        }
943
                    }
944
945
                    $menu_buttons[$act] = $button;
946
                }
947
            }
948
949
            if (!empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= 2)
950
                cache_put_data('menu_buttons-' . implode('_', $user_info['groups']) . '-' . $user_info['language'], $menu_buttons, $cacheTime);
951
        }
952
953
        if (!empty($menu_buttons['profile']['sub_buttons']['logout']))
954
            $menu_buttons['profile']['sub_buttons']['logout']['href'] .= ';' . $context['session_var'] . '=' . $context['session_id'];
955
956
        $context['menu_buttons'] = $menu_buttons;
957
958
        // Figure out which action we are doing so we can set the active tab.
959
        // Default to home.
960
        $current_action = 'home';
961
962
        if (isset($context['menu_buttons'][$context['current_action']]))
963
            $current_action = $context['current_action'];
964
        elseif ($context['current_action'] == 'profile')
965
            $current_action = 'pm';
966
        elseif ($context['current_action'] == 'theme')
967
            $current_action = isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'pick' ? 'profile' : 'admin';
968
        elseif ($context['current_action'] == 'login2' || ($user_info['is_guest'] && $context['current_action'] == 'reminder'))
969
            $current_action = 'login';
970
        elseif ($context['current_action'] == 'groups' && $context['allow_moderation_center'])
971
            $current_action = 'moderate';
972
        elseif ($context['current_action'] == 'moderate' && $context['allow_admin'])
973
            $current_action = 'admin';
974
975
        // Not all actions are simple.
976
        if (!empty($needs_action_hook))
977
            call_integration_hook('integrate_current_action', array(&$current_action));
978
979
        if (isset($context['menu_buttons'][$current_action]))
980
            $context['menu_buttons'][$current_action]['active_button'] = true;
981
    }
982
983
    public function loadThemeJavascript()
984
    {
985
        global $settings, $context, $modSettings, $scripturl, $txt, $options;
986
987
        // Queue our Javascript
988
        loadJavascriptFile(array('elk_jquery_plugins.js', 'script.js', 'script_elk.js', 'theme.js'));
989
990
        // Default JS variables for use in every theme
991
        $this->addJavascriptVar(array(
992
            'elk_theme_url' => JavaScriptEscape($settings['theme_url']),
993
            'elk_default_theme_url' => JavaScriptEscape($settings['default_theme_url']),
994
            'elk_images_url' => JavaScriptEscape($settings['images_url']),
995
            'elk_smiley_url' => JavaScriptEscape($modSettings['smileys_url']),
996
            'elk_scripturl' => '\'' . $scripturl . '\'',
997
            'elk_iso_case_folding' => $context['server']['iso_case_folding'] ? 'true' : 'false',
998
            'elk_charset' => '"UTF-8"',
999
            'elk_session_id' => JavaScriptEscape($context['session_id']),
1000
            'elk_session_var' => JavaScriptEscape($context['session_var']),
1001
            'elk_member_id' => $context['user']['id'],
1002
            'ajax_notification_text' => JavaScriptEscape($txt['ajax_in_progress']),
1003
            'ajax_notification_cancel_text' => JavaScriptEscape($txt['modify_cancel']),
1004
            'help_popup_heading_text' => JavaScriptEscape($txt['help_popup']),
1005
            'use_click_menu' => !empty($options['use_click_menu']) ? 'true' : 'false',
1006
            'todayMod' => !empty($modSettings['todayMod']) ? (int) $modSettings['todayMod'] : 0)
1007
        );
1008
1009
        // Auto video embedding enabled, then load the needed JS
1010
        if (!empty($modSettings['enableVideoEmbeding']))
1011
        {
1012
            theme()->autoEmbedVideo();
1013
        }
1014
1015
        // Prettify code tags? Load the needed JS and CSS.
1016
        if (!empty($modSettings['enableCodePrettify']))
1017
        {
1018
            theme()->addCodePrettify();
1019
        }
1020
1021
        theme()->relativeTimes();
1022
1023
        // If we think we have mail to send, let's offer up some possibilities... robots get pain (Now with scheduled task support!)
1024
        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())
1025
        {
1026
            theme()->doScheduledSendMail();
1027
        }
1028
    }
1029
1030
    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...
1031
    {
1032
        global $settings;
1033
1034
        $simpleActions = array(
1035
            'quickhelp',
1036
            'printpage',
1037
            'quotefast',
1038
            'spellcheck',
1039
        );
1040
1041
        call_integration_hook('integrate_simple_actions', array(&$simpleActions));
1042
1043
        // Output is fully XML, so no need for the index template.
1044
        if (isset($_REQUEST['xml']))
1045
        {
1046
            loadLanguage('index+Addons');
1047
1048
            // @todo added because some $settings in template_init are necessary even in xml mode. Maybe move template_init to a settings file?
1049
            loadTemplate('index');
1050
            loadTemplate('Xml');
1051
            \Template_Layers::getInstance()->removeAll();
1052
        }
1053
        // These actions don't require the index template at all.
1054
        elseif (!empty($_REQUEST['action']) && in_array($_REQUEST['action'], $simpleActions))
1055
        {
1056
            loadLanguage('index+Addons');
1057
            \Template_Layers::getInstance()->removeAll();
1058
        }
1059
        else
1060
        {
1061
            // Custom templates to load, or just default?
1062
            if (isset($settings['theme_templates']))
1063
                $templates = explode(',', $settings['theme_templates']);
1064
            else
1065
                $templates = array('index');
1066
1067
            // Load each template...
1068
            foreach ($templates as $template)
1069
                loadTemplate($template);
1070
1071
            // ...and attempt to load their associated language files.
1072
            $required_files = implode('+', array_merge($templates, array('Addons')));
1073
            loadLanguage($required_files, '', false);
1074
1075
            // Custom template layers?
1076
            if (isset($settings['theme_layers']))
1077
                $layers = explode(',', $settings['theme_layers']);
1078
            else
1079
                $layers = array('html', 'body');
1080
1081
            $template_layers = \Template_Layers::getInstance(true);
1082
            foreach ($layers as $layer)
1083
                $template_layers->addBegin($layer);
1084
        }
1085
    }
1086
1087
    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...
1088
    {
1089
        global $context, $settings, $options;
1090
1091
        // Overriding - for previews and that ilk.
1092
        if (!empty($_REQUEST['variant']))
1093
            $_SESSION['id_variant'] = $_REQUEST['variant'];
1094
1095
        // User selection?
1096
        if (empty($settings['disable_user_variant']) || allowedTo('admin_forum'))
1097
            $context['theme_variant'] = !empty($_SESSION['id_variant']) ? $_SESSION['id_variant'] : (!empty($options['theme_variant']) ? $options['theme_variant'] : '');
1098
1099
        // If not a user variant, select the default.
1100
        if ($context['theme_variant'] == '' || !in_array($context['theme_variant'], $settings['theme_variants']))
1101
            $context['theme_variant'] = !empty($settings['default_variant']) && in_array($settings['default_variant'], $settings['theme_variants']) ? $settings['default_variant'] : $settings['theme_variants'][0];
1102
1103
        // Do this to keep things easier in the templates.
1104
        $context['theme_variant'] = '_' . $context['theme_variant'];
1105
        $context['theme_variant_url'] = $context['theme_variant'] . '/';
1106
1107
        // The most efficient way of writing multi themes is to use a master index.css plus variant.css files.
1108
        if (!empty($context['theme_variant']))
1109
            loadCSSFile($context['theme_variant'] . '/index' . $context['theme_variant'] . '.css');
1110
    }
1111
}