1
|
|
|
<?php |
|
|
|
|
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() |
|
|
|
|
34
|
|
|
{ |
35
|
|
|
global $context; |
36
|
|
|
|
37
|
|
|
echo $context['raw_data']; |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* The header template |
42
|
|
|
*/ |
43
|
|
|
function template_header() |
|
|
|
|
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']) |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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) |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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() |
|
|
|
|
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) |
|
|
|
|
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() |
|
|
|
|
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']; |
|
|
|
|
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' => '', |
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' => '', |
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' => '', |
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' => '', |
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' => '', |
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' => '', |
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' => '', |
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' => '', |
857
|
|
|
'show' => !$user_info['is_guest'], |
858
|
|
|
), |
859
|
|
|
'login' => array( |
860
|
|
|
'title' => $txt['login'], |
861
|
|
|
'href' => $scripturl . '?action=login', |
862
|
|
|
'data-icon' => '', |
863
|
|
|
'show' => $user_info['is_guest'], |
864
|
|
|
), |
865
|
|
|
|
866
|
|
|
'register' => array( |
867
|
|
|
'title' => $txt['register'], |
868
|
|
|
'href' => $scripturl . '?action=register', |
869
|
|
|
'data-icon' => '', |
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' => '', |
|
|
|
|
876
|
|
|
'show' => allowedTo('like_posts_stats'), |
877
|
|
|
), |
878
|
|
|
'contact' => array( |
879
|
|
|
'title' => $txt['contact'], |
880
|
|
|
'href' => $scripturl . '?action=register;sa=contact', |
881
|
|
|
'data-icon' => '', |
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() |
|
|
|
|
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() |
|
|
|
|
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
|
|
|
} |
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.