1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* This file is mainly concerned with the Who's Online list. |
5
|
|
|
* Although, it also handles credits. :P |
6
|
|
|
* |
7
|
|
|
* Simple Machines Forum (SMF) |
8
|
|
|
* |
9
|
|
|
* @package SMF |
10
|
|
|
* @author Simple Machines https://www.simplemachines.org |
11
|
|
|
* @copyright 2022 Simple Machines and individual contributors |
12
|
|
|
* @license https://www.simplemachines.org/about/smf/license.php BSD |
13
|
|
|
* |
14
|
|
|
* @version 2.1.0 |
15
|
|
|
*/ |
16
|
|
|
|
17
|
|
|
if (!defined('SMF')) |
18
|
|
|
die('No direct access...'); |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* Who's online, and what are they doing? |
22
|
|
|
* This function prepares the who's online data for the Who template. |
23
|
|
|
* It requires the who_view permission. |
24
|
|
|
* It is enabled with the who_enabled setting. |
25
|
|
|
* It is accessed via ?action=who. |
26
|
|
|
* |
27
|
|
|
* Uses Who template, main sub-template |
28
|
|
|
* Uses Who language file. |
29
|
|
|
*/ |
30
|
|
|
function Who() |
31
|
|
|
{ |
32
|
|
|
global $context, $scripturl, $txt, $modSettings, $memberContext, $smcFunc; |
33
|
|
|
|
34
|
|
|
// Permissions, permissions, permissions. |
35
|
|
|
isAllowedTo('who_view'); |
36
|
|
|
|
37
|
|
|
// You can't do anything if this is off. |
38
|
|
|
if (empty($modSettings['who_enabled'])) |
39
|
|
|
fatal_lang_error('who_off', false); |
40
|
|
|
|
41
|
|
|
// Discourage robots from indexing this page. |
42
|
|
|
$context['robot_no_index'] = true; |
43
|
|
|
|
44
|
|
|
// Load the 'Who' template. |
45
|
|
|
loadTemplate('Who'); |
46
|
|
|
loadLanguage('Who'); |
47
|
|
|
|
48
|
|
|
// Sort out... the column sorting. |
49
|
|
|
$sort_methods = array( |
50
|
|
|
'user' => 'mem.real_name', |
51
|
|
|
'time' => 'lo.log_time' |
52
|
|
|
); |
53
|
|
|
|
54
|
|
|
$show_methods = array( |
55
|
|
|
'members' => '(lo.id_member != 0)', |
56
|
|
|
'guests' => '(lo.id_member = 0)', |
57
|
|
|
'all' => '1=1', |
58
|
|
|
); |
59
|
|
|
|
60
|
|
|
// Store the sort methods and the show types for use in the template. |
61
|
|
|
$context['sort_methods'] = array( |
62
|
|
|
'user' => $txt['who_user'], |
63
|
|
|
'time' => $txt['who_time'], |
64
|
|
|
); |
65
|
|
|
$context['show_methods'] = array( |
66
|
|
|
'all' => $txt['who_show_all'], |
67
|
|
|
'members' => $txt['who_show_members_only'], |
68
|
|
|
'guests' => $txt['who_show_guests_only'], |
69
|
|
|
); |
70
|
|
|
|
71
|
|
|
// Can they see spiders too? |
72
|
|
|
if (!empty($modSettings['show_spider_online']) && ($modSettings['show_spider_online'] == 2 || allowedTo('admin_forum')) && !empty($modSettings['spider_name_cache'])) |
73
|
|
|
{ |
74
|
|
|
$show_methods['spiders'] = '(lo.id_member = 0 AND lo.id_spider > 0)'; |
75
|
|
|
$show_methods['guests'] = '(lo.id_member = 0 AND lo.id_spider = 0)'; |
76
|
|
|
$context['show_methods']['spiders'] = $txt['who_show_spiders_only']; |
77
|
|
|
} |
78
|
|
|
elseif (empty($modSettings['show_spider_online']) && isset($_SESSION['who_online_filter']) && $_SESSION['who_online_filter'] == 'spiders') |
79
|
|
|
unset($_SESSION['who_online_filter']); |
80
|
|
|
|
81
|
|
|
// Does the user prefer a different sort direction? |
82
|
|
|
if (isset($_REQUEST['sort']) && isset($sort_methods[$_REQUEST['sort']])) |
83
|
|
|
{ |
84
|
|
|
$context['sort_by'] = $_SESSION['who_online_sort_by'] = $_REQUEST['sort']; |
85
|
|
|
$sort_method = $sort_methods[$_REQUEST['sort']]; |
86
|
|
|
} |
87
|
|
|
// Did we set a preferred sort order earlier in the session? |
88
|
|
|
elseif (isset($_SESSION['who_online_sort_by'])) |
89
|
|
|
{ |
90
|
|
|
$context['sort_by'] = $_SESSION['who_online_sort_by']; |
91
|
|
|
$sort_method = $sort_methods[$_SESSION['who_online_sort_by']]; |
92
|
|
|
} |
93
|
|
|
// Default to last time online. |
94
|
|
|
else |
95
|
|
|
{ |
96
|
|
|
$context['sort_by'] = $_SESSION['who_online_sort_by'] = 'time'; |
97
|
|
|
$sort_method = 'lo.log_time'; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
$context['sort_direction'] = isset($_REQUEST['asc']) || (isset($_REQUEST['sort_dir']) && $_REQUEST['sort_dir'] == 'asc') ? 'up' : 'down'; |
101
|
|
|
|
102
|
|
|
$conditions = array(); |
103
|
|
|
if (!allowedTo('moderate_forum')) |
104
|
|
|
$conditions[] = '(COALESCE(mem.show_online, 1) = 1)'; |
105
|
|
|
|
106
|
|
|
// Fallback to top filter? |
107
|
|
|
if (isset($_REQUEST['submit_top']) && isset($_REQUEST['show_top'])) |
108
|
|
|
$_REQUEST['show'] = $_REQUEST['show_top']; |
109
|
|
|
// Does the user wish to apply a filter? |
110
|
|
|
if (isset($_REQUEST['show']) && isset($show_methods[$_REQUEST['show']])) |
111
|
|
|
$context['show_by'] = $_SESSION['who_online_filter'] = $_REQUEST['show']; |
112
|
|
|
// Perhaps we saved a filter earlier in the session? |
113
|
|
|
elseif (isset($_SESSION['who_online_filter'])) |
114
|
|
|
$context['show_by'] = $_SESSION['who_online_filter']; |
115
|
|
|
else |
116
|
|
|
$context['show_by'] = 'members'; |
117
|
|
|
|
118
|
|
|
$conditions[] = $show_methods[$context['show_by']]; |
119
|
|
|
|
120
|
|
|
// Get the total amount of members online. |
121
|
|
|
$request = $smcFunc['db_query']('', ' |
122
|
|
|
SELECT COUNT(*) |
123
|
|
|
FROM {db_prefix}log_online AS lo |
124
|
|
|
LEFT JOIN {db_prefix}members AS mem ON (lo.id_member = mem.id_member)' . (!empty($conditions) ? ' |
125
|
|
|
WHERE ' . implode(' AND ', $conditions) : ''), |
126
|
|
|
array( |
127
|
|
|
) |
128
|
|
|
); |
129
|
|
|
list ($totalMembers) = $smcFunc['db_fetch_row']($request); |
130
|
|
|
$smcFunc['db_free_result']($request); |
131
|
|
|
|
132
|
|
|
// Prepare some page index variables. |
133
|
|
|
$context['page_index'] = constructPageIndex($scripturl . '?action=who;sort=' . $context['sort_by'] . ($context['sort_direction'] == 'up' ? ';asc' : '') . ';show=' . $context['show_by'], $_REQUEST['start'], $totalMembers, $modSettings['defaultMaxMembers']); |
134
|
|
|
$context['start'] = $_REQUEST['start']; |
135
|
|
|
|
136
|
|
|
// Look for people online, provided they don't mind if you see they are. |
137
|
|
|
$request = $smcFunc['db_query']('', ' |
138
|
|
|
SELECT |
139
|
|
|
lo.log_time, lo.id_member, lo.url, lo.ip AS ip, mem.real_name, |
140
|
|
|
lo.session, mg.online_color, COALESCE(mem.show_online, 1) AS show_online, |
141
|
|
|
lo.id_spider |
142
|
|
|
FROM {db_prefix}log_online AS lo |
143
|
|
|
LEFT JOIN {db_prefix}members AS mem ON (lo.id_member = mem.id_member) |
144
|
|
|
LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:regular_member} THEN mem.id_post_group ELSE mem.id_group END)' . (!empty($conditions) ? ' |
145
|
|
|
WHERE ' . implode(' AND ', $conditions) : '') . ' |
146
|
|
|
ORDER BY {raw:sort_method} {raw:sort_direction} |
147
|
|
|
LIMIT {int:offset}, {int:limit}', |
148
|
|
|
array( |
149
|
|
|
'regular_member' => 0, |
150
|
|
|
'sort_method' => $sort_method, |
151
|
|
|
'sort_direction' => $context['sort_direction'] == 'up' ? 'ASC' : 'DESC', |
152
|
|
|
'offset' => $context['start'], |
153
|
|
|
'limit' => $modSettings['defaultMaxMembers'], |
154
|
|
|
) |
155
|
|
|
); |
156
|
|
|
$context['members'] = array(); |
157
|
|
|
$member_ids = array(); |
158
|
|
|
$url_data = array(); |
159
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
160
|
|
|
{ |
161
|
|
|
$actions = $smcFunc['json_decode']($row['url'], true); |
162
|
|
|
if ($actions === array()) |
163
|
|
|
continue; |
164
|
|
|
|
165
|
|
|
// Send the information to the template. |
166
|
|
|
$context['members'][$row['session']] = array( |
167
|
|
|
'id' => $row['id_member'], |
168
|
|
|
'ip' => allowedTo('moderate_forum') ? inet_dtop($row['ip']) : '', |
169
|
|
|
// It is *going* to be today or yesterday, so why keep that information in there? |
170
|
|
|
'time' => strtr(timeformat($row['log_time']), array($txt['today'] => '', $txt['yesterday'] => '')), |
171
|
|
|
'timestamp' => $row['log_time'], |
172
|
|
|
'query' => $actions, |
173
|
|
|
'is_hidden' => $row['show_online'] == 0, |
174
|
|
|
'id_spider' => $row['id_spider'], |
175
|
|
|
'color' => empty($row['online_color']) ? '' : $row['online_color'] |
176
|
|
|
); |
177
|
|
|
|
178
|
|
|
$url_data[$row['session']] = array($row['url'], $row['id_member']); |
179
|
|
|
$member_ids[] = $row['id_member']; |
180
|
|
|
} |
181
|
|
|
$smcFunc['db_free_result']($request); |
182
|
|
|
|
183
|
|
|
// Load the user data for these members. |
184
|
|
|
loadMemberData($member_ids); |
185
|
|
|
|
186
|
|
|
// Load up the guest user. |
187
|
|
|
$memberContext[0] = array( |
188
|
|
|
'id' => 0, |
189
|
|
|
'name' => $txt['guest_title'], |
190
|
|
|
'group' => $txt['guest_title'], |
191
|
|
|
'href' => '', |
192
|
|
|
'link' => $txt['guest_title'], |
193
|
|
|
'email' => $txt['guest_title'], |
194
|
|
|
'is_guest' => true |
195
|
|
|
); |
196
|
|
|
|
197
|
|
|
// Are we showing spiders? |
198
|
|
|
$spiderContext = array(); |
199
|
|
|
if (!empty($modSettings['show_spider_online']) && ($modSettings['show_spider_online'] == 2 || allowedTo('admin_forum')) && !empty($modSettings['spider_name_cache'])) |
200
|
|
|
{ |
201
|
|
|
foreach ($smcFunc['json_decode']($modSettings['spider_name_cache'], true) as $id => $name) |
202
|
|
|
$spiderContext[$id] = array( |
203
|
|
|
'id' => 0, |
204
|
|
|
'name' => $name, |
205
|
|
|
'group' => $txt['spiders'], |
206
|
|
|
'href' => '', |
207
|
|
|
'link' => $name, |
208
|
|
|
'email' => $name, |
209
|
|
|
'is_guest' => true |
210
|
|
|
); |
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
$url_data = determineActions($url_data); |
214
|
|
|
|
215
|
|
|
// Setup the linktree and page title (do it down here because the language files are now loaded..) |
216
|
|
|
$context['page_title'] = $txt['who_title']; |
217
|
|
|
$context['linktree'][] = array( |
218
|
|
|
'url' => $scripturl . '?action=who', |
219
|
|
|
'name' => $txt['who_title'] |
220
|
|
|
); |
221
|
|
|
|
222
|
|
|
// Put it in the context variables. |
223
|
|
|
foreach ($context['members'] as $i => $member) |
224
|
|
|
{ |
225
|
|
|
if ($member['id'] != 0) |
226
|
|
|
$member['id'] = loadMemberContext($member['id']) ? $member['id'] : 0; |
227
|
|
|
|
228
|
|
|
// Keep the IP that came from the database. |
229
|
|
|
$memberContext[$member['id']]['ip'] = $member['ip']; |
230
|
|
|
$context['members'][$i]['action'] = isset($url_data[$i]) ? $url_data[$i] : array('label' => 'who_hidden', 'class' => 'em'); |
231
|
|
|
if ($member['id'] == 0 && isset($spiderContext[$member['id_spider']])) |
232
|
|
|
$context['members'][$i] += $spiderContext[$member['id_spider']]; |
233
|
|
|
else |
234
|
|
|
$context['members'][$i] += $memberContext[$member['id']]; |
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
// Some people can't send personal messages... |
238
|
|
|
$context['can_send_pm'] = allowedTo('pm_send'); |
239
|
|
|
$context['can_send_email'] = allowedTo('send_email_to_members'); |
240
|
|
|
|
241
|
|
|
// any profile fields disabled? |
242
|
|
|
$context['disabled_fields'] = isset($modSettings['disabled_profile_fields']) ? array_flip(explode(',', $modSettings['disabled_profile_fields'])) : array(); |
243
|
|
|
|
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
/** |
247
|
|
|
* This function determines the actions of the members passed in urls. |
248
|
|
|
* |
249
|
|
|
* Adding actions to the Who's Online list: |
250
|
|
|
* Adding actions to this list is actually relatively easy... |
251
|
|
|
* - for actions anyone should be able to see, just add a string named whoall_ACTION. |
252
|
|
|
* (where ACTION is the action used in index.php.) |
253
|
|
|
* - for actions that have a subaction which should be represented differently, use whoall_ACTION_SUBACTION. |
254
|
|
|
* - for actions that include a topic, and should be restricted, use whotopic_ACTION. |
255
|
|
|
* - for actions that use a message, by msg or quote, use whopost_ACTION. |
256
|
|
|
* - for administrator-only actions, use whoadmin_ACTION. |
257
|
|
|
* - for actions that should be viewable only with certain permissions, |
258
|
|
|
* use whoallow_ACTION and add a list of possible permissions to the |
259
|
|
|
* $allowedActions array, using ACTION as the key. |
260
|
|
|
* |
261
|
|
|
* @param mixed $urls a single url (string) or an array of arrays, each inner array being (JSON-encoded request data, id_member) |
262
|
|
|
* @param string|bool $preferred_prefix = false |
263
|
|
|
* @return array an array of descriptions if you passed an array, otherwise the string describing their current location. |
264
|
|
|
*/ |
265
|
|
|
function determineActions($urls, $preferred_prefix = false) |
266
|
|
|
{ |
267
|
|
|
global $txt, $user_info, $modSettings, $smcFunc, $scripturl, $context; |
268
|
|
|
|
269
|
|
|
if (!allowedTo('who_view')) |
270
|
|
|
return array(); |
271
|
|
|
loadLanguage('Who'); |
272
|
|
|
|
273
|
|
|
// Actions that require a specific permission level. |
274
|
|
|
$allowedActions = array( |
275
|
|
|
'admin' => array('moderate_forum', 'manage_membergroups', 'manage_bans', 'admin_forum', 'manage_permissions', 'send_mail', 'manage_attachments', 'manage_smileys', 'manage_boards', 'edit_news'), |
276
|
|
|
'ban' => array('manage_bans'), |
277
|
|
|
'boardrecount' => array('admin_forum'), |
278
|
|
|
'calendar' => array('calendar_view'), |
279
|
|
|
'corefeatures' => array('admin_forum'), |
280
|
|
|
'editnews' => array('edit_news'), |
281
|
|
|
'featuresettings' => array('admin_forum'), |
282
|
|
|
'languages' => array('admin_forum'), |
283
|
|
|
'logs' => array('admin_forum'), |
284
|
|
|
'mailing' => array('send_mail'), |
285
|
|
|
'mailqueue' => array('admin_forum'), |
286
|
|
|
'maintain' => array('admin_forum'), |
287
|
|
|
'manageattachments' => array('manage_attachments'), |
288
|
|
|
'manageboards' => array('manage_boards'), |
289
|
|
|
'managecalendar' => array('admin_forum'), |
290
|
|
|
'managesearch' => array('admin_forum'), |
291
|
|
|
'managesmileys' => array('manage_smileys'), |
292
|
|
|
'membergroups' => array('manage_membergroups'), |
293
|
|
|
'mlist' => array('view_mlist'), |
294
|
|
|
'moderate' => array('access_mod_center', 'moderate_forum', 'manage_membergroups'), |
295
|
|
|
'modsettings' => array('admin_forum'), |
296
|
|
|
'news' => array('edit_news', 'send_mail', 'admin_forum'), |
297
|
|
|
'optimizetables' => array('admin_forum'), |
298
|
|
|
'packages' => array('admin_forum'), |
299
|
|
|
'paidsubscribe' => array('admin_forum'), |
300
|
|
|
'permissions' => array('manage_permissions'), |
301
|
|
|
'postsettings' => array('admin_forum'), |
302
|
|
|
'regcenter' => array('admin_forum', 'moderate_forum'), |
303
|
|
|
'repairboards' => array('admin_forum'), |
304
|
|
|
'reports' => array('admin_forum'), |
305
|
|
|
'scheduledtasks' => array('admin_forum'), |
306
|
|
|
'search' => array('search_posts'), |
307
|
|
|
'search2' => array('search_posts'), |
308
|
|
|
'securitysettings' => array('admin_forum'), |
309
|
|
|
'sengines' => array('admin_forum'), |
310
|
|
|
'serversettings' => array('admin_forum'), |
311
|
|
|
'setcensor' => array('moderate_forum'), |
312
|
|
|
'setreserve' => array('moderate_forum'), |
313
|
|
|
'stats' => array('view_stats'), |
314
|
|
|
'theme' => array('admin_forum'), |
315
|
|
|
'viewerrorlog' => array('admin_forum'), |
316
|
|
|
'viewmembers' => array('moderate_forum'), |
317
|
|
|
); |
318
|
|
|
call_integration_hook('who_allowed', array(&$allowedActions)); |
319
|
|
|
|
320
|
|
|
if (!is_array($urls)) |
321
|
|
|
$url_list = array(array($urls, $user_info['id'])); |
322
|
|
|
else |
323
|
|
|
$url_list = $urls; |
324
|
|
|
|
325
|
|
|
// These are done to later query these in large chunks. (instead of one by one.) |
326
|
|
|
$topic_ids = array(); |
327
|
|
|
$profile_ids = array(); |
328
|
|
|
$board_ids = array(); |
329
|
|
|
|
330
|
|
|
$data = array(); |
331
|
|
|
foreach ($url_list as $k => $url) |
332
|
|
|
{ |
333
|
|
|
// Get the request parameters.. |
334
|
|
|
$actions = $smcFunc['json_decode']($url[0], true); |
335
|
|
|
if ($actions === array()) |
336
|
|
|
continue; |
337
|
|
|
|
338
|
|
|
// If it's the admin or moderation center, and there is an area set, use that instead. |
339
|
|
|
if (isset($actions['action']) && ($actions['action'] == 'admin' || $actions['action'] == 'moderate') && isset($actions['area'])) |
340
|
|
|
$actions['action'] = $actions['area']; |
341
|
|
|
|
342
|
|
|
// Check if there was no action or the action is display. |
343
|
|
|
if (!isset($actions['action']) || $actions['action'] == 'display') |
344
|
|
|
{ |
345
|
|
|
// It's a topic! Must be! |
346
|
|
|
if (isset($actions['topic'])) |
347
|
|
|
{ |
348
|
|
|
// Assume they can't view it, and queue it up for later. |
349
|
|
|
$data[$k] = array('label' => 'who_hidden', 'class' => 'em'); |
350
|
|
|
$topic_ids[(int) $actions['topic']][$k] = $txt['who_topic']; |
351
|
|
|
} |
352
|
|
|
// It's a board! |
353
|
|
|
elseif (isset($actions['board'])) |
354
|
|
|
{ |
355
|
|
|
// Hide first, show later. |
356
|
|
|
$data[$k] = array('label' => 'who_hidden', 'class' => 'em'); |
357
|
|
|
$board_ids[$actions['board']][$k] = $txt['who_board']; |
358
|
|
|
} |
359
|
|
|
// It's the board index!! It must be! |
360
|
|
|
else |
361
|
|
|
$data[$k] = sprintf($txt['who_index'], $scripturl, $context['forum_name_html_safe']); |
362
|
|
|
} |
363
|
|
|
// Probably an error or some goon? |
364
|
|
|
elseif ($actions['action'] == '') |
365
|
|
|
$data[$k] = sprintf($txt['who_index'], $scripturl, $context['forum_name_html_safe']); |
366
|
|
|
// Some other normal action...? |
367
|
|
|
else |
368
|
|
|
{ |
369
|
|
|
// Viewing/editing a profile. |
370
|
|
|
if ($actions['action'] == 'profile') |
371
|
|
|
{ |
372
|
|
|
// Whose? Their own? |
373
|
|
|
if (empty($actions['u'])) |
374
|
|
|
$actions['u'] = $url[1]; |
375
|
|
|
|
376
|
|
|
$data[$k] = array('label' => 'who_hidden', 'class' => 'em'); |
377
|
|
|
$profile_ids[(int) $actions['u']][$k] = $actions['u'] == $url[1] ? $txt['who_viewownprofile'] : $txt['who_viewprofile']; |
378
|
|
|
} |
379
|
|
|
elseif (($actions['action'] == 'post' || $actions['action'] == 'post2') && empty($actions['topic']) && isset($actions['board'])) |
380
|
|
|
{ |
381
|
|
|
$data[$k] = array('label' => 'who_hidden', 'class' => 'em'); |
382
|
|
|
$board_ids[(int) $actions['board']][$k] = isset($actions['poll']) ? $txt['who_poll'] : $txt['who_post']; |
383
|
|
|
} |
384
|
|
|
// A subaction anyone can view... if the language string is there, show it. |
385
|
|
|
elseif (isset($actions['sa']) && isset($txt['whoall_' . $actions['action'] . '_' . $actions['sa']])) |
386
|
|
|
$data[$k] = $preferred_prefix && isset($txt[$preferred_prefix . $actions['action'] . '_' . $actions['sa']]) ? $txt[$preferred_prefix . $actions['action'] . '_' . $actions['sa']] : sprintf($txt['whoall_' . $actions['action'] . '_' . $actions['sa']], $scripturl); |
|
|
|
|
387
|
|
|
// An action any old fellow can look at. (if ['whoall_' . $action] exists, we know everyone can see it.) |
388
|
|
|
elseif (isset($txt['whoall_' . $actions['action']])) |
389
|
|
|
$data[$k] = $preferred_prefix && isset($txt[$preferred_prefix . $actions['action']]) ? $txt[$preferred_prefix . $actions['action']] : sprintf($txt['whoall_' . $actions['action']], $scripturl); |
390
|
|
|
// Viewable if and only if they can see the board... |
391
|
|
|
elseif (isset($txt['whotopic_' . $actions['action']])) |
392
|
|
|
{ |
393
|
|
|
// Find out what topic they are accessing. |
394
|
|
|
$topic = (int) (isset($actions['topic']) ? $actions['topic'] : (isset($actions['from']) ? $actions['from'] : 0)); |
395
|
|
|
|
396
|
|
|
$data[$k] = array('label' => 'who_hidden', 'class' => 'em'); |
397
|
|
|
$topic_ids[$topic][$k] = $txt['whotopic_' . $actions['action']]; |
398
|
|
|
} |
399
|
|
|
elseif (isset($txt['whopost_' . $actions['action']])) |
400
|
|
|
{ |
401
|
|
|
// Find out what message they are accessing. |
402
|
|
|
$msgid = (int) (isset($actions['msg']) ? $actions['msg'] : (isset($actions['quote']) ? $actions['quote'] : 0)); |
403
|
|
|
|
404
|
|
|
$result = $smcFunc['db_query']('', ' |
405
|
|
|
SELECT m.id_topic, m.subject |
406
|
|
|
FROM {db_prefix}messages AS m |
407
|
|
|
' . ($modSettings['postmod_active'] ? 'INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic AND t.approved = {int:is_approved})' : '') . ' |
408
|
|
|
WHERE m.id_msg = {int:id_msg} |
409
|
|
|
AND {query_see_message_board}' . ($modSettings['postmod_active'] ? ' |
410
|
|
|
AND m.approved = {int:is_approved}' : '') . ' |
411
|
|
|
LIMIT 1', |
412
|
|
|
array( |
413
|
|
|
'is_approved' => 1, |
414
|
|
|
'id_msg' => $msgid, |
415
|
|
|
) |
416
|
|
|
); |
417
|
|
|
list ($id_topic, $subject) = $smcFunc['db_fetch_row']($result); |
418
|
|
|
$data[$k] = sprintf($txt['whopost_' . $actions['action']], $id_topic, $subject, $scripturl); |
419
|
|
|
$smcFunc['db_free_result']($result); |
420
|
|
|
|
421
|
|
|
if (empty($id_topic)) |
422
|
|
|
$data[$k] = array('label' => 'who_hidden', 'class' => 'em'); |
423
|
|
|
} |
424
|
|
|
// Viewable only by administrators.. (if it starts with whoadmin, it's admin only!) |
425
|
|
|
elseif (allowedTo('moderate_forum') && isset($txt['whoadmin_' . $actions['action']])) |
426
|
|
|
$data[$k] = sprintf($txt['whoadmin_' . $actions['action']], $scripturl); |
427
|
|
|
// Viewable by permission level. |
428
|
|
|
elseif (isset($allowedActions[$actions['action']])) |
429
|
|
|
{ |
430
|
|
|
if (allowedTo($allowedActions[$actions['action']]) && !empty($txt['whoallow_' . $actions['action']])) |
431
|
|
|
$data[$k] = sprintf($txt['whoallow_' . $actions['action']], $scripturl); |
432
|
|
|
elseif (in_array('moderate_forum', $allowedActions[$actions['action']])) |
433
|
|
|
$data[$k] = $txt['who_moderate']; |
434
|
|
|
elseif (in_array('admin_forum', $allowedActions[$actions['action']])) |
435
|
|
|
$data[$k] = $txt['who_admin']; |
436
|
|
|
else |
437
|
|
|
$data[$k] = array('label' => 'who_hidden', 'class' => 'em'); |
438
|
|
|
} |
439
|
|
|
elseif (!empty($actions['action'])) |
440
|
|
|
$data[$k] = $txt['who_generic'] . ' ' . $actions['action']; |
441
|
|
|
else |
442
|
|
|
$data[$k] = array('label' => 'who_unknown', 'class' => 'em'); |
443
|
|
|
} |
444
|
|
|
|
445
|
|
|
if (isset($actions['error'])) |
446
|
|
|
{ |
447
|
|
|
loadLanguage('Errors'); |
448
|
|
|
|
449
|
|
|
if (isset($txt[$actions['error']])) |
450
|
|
|
$error_message = str_replace('"', '"', empty($actions['error_params']) ? $txt[$actions['error']] : vsprintf($txt[$actions['error']], $actions['error_params'])); |
451
|
|
|
elseif ($actions['error'] == 'guest_login') |
452
|
|
|
$error_message = str_replace('"', '"', $txt['who_guest_login']); |
453
|
|
|
else |
454
|
|
|
$error_message = str_replace('"', '"', $actions['error']); |
455
|
|
|
|
456
|
|
|
if (!empty($error_message)) |
457
|
|
|
{ |
458
|
|
|
$error_message = ' <span class="main_icons error" title="' . $error_message . '"></span>'; |
459
|
|
|
|
460
|
|
|
if (is_array($data[$k])) |
461
|
|
|
$data[$k]['error_message'] = $error_message; |
462
|
|
|
else |
463
|
|
|
$data[$k] .= $error_message; |
464
|
|
|
} |
465
|
|
|
} |
466
|
|
|
|
467
|
|
|
// Maybe the action is integrated into another system? |
468
|
|
|
if (count($integrate_actions = call_integration_hook('integrate_whos_online', array($actions))) > 0) |
469
|
|
|
{ |
470
|
|
|
foreach ($integrate_actions as $integrate_action) |
471
|
|
|
{ |
472
|
|
|
if (!empty($integrate_action)) |
473
|
|
|
{ |
474
|
|
|
$data[$k] = $integrate_action; |
475
|
|
|
if (isset($actions['topic']) && isset($topic_ids[(int) $actions['topic']][$k])) |
476
|
|
|
$topic_ids[(int) $actions['topic']][$k] = $integrate_action; |
477
|
|
|
if (isset($actions['board']) && isset($board_ids[(int) $actions['board']][$k])) |
478
|
|
|
$board_ids[(int) $actions['board']][$k] = $integrate_action; |
479
|
|
|
if (isset($actions['u']) && isset($profile_ids[(int) $actions['u']][$k])) |
480
|
|
|
$profile_ids[(int) $actions['u']][$k] = $integrate_action; |
481
|
|
|
break; |
482
|
|
|
} |
483
|
|
|
} |
484
|
|
|
} |
485
|
|
|
} |
486
|
|
|
|
487
|
|
|
// Load topic names. |
488
|
|
|
if (!empty($topic_ids)) |
489
|
|
|
{ |
490
|
|
|
$result = $smcFunc['db_query']('', ' |
491
|
|
|
SELECT t.id_topic, m.subject |
492
|
|
|
FROM {db_prefix}topics AS t |
493
|
|
|
INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg) |
494
|
|
|
WHERE {query_see_topic_board} |
495
|
|
|
AND t.id_topic IN ({array_int:topic_list})' . ($modSettings['postmod_active'] ? ' |
496
|
|
|
AND t.approved = {int:is_approved}' : '') . ' |
497
|
|
|
LIMIT {int:limit}', |
498
|
|
|
array( |
499
|
|
|
'topic_list' => array_keys($topic_ids), |
500
|
|
|
'is_approved' => 1, |
501
|
|
|
'limit' => count($topic_ids), |
502
|
|
|
) |
503
|
|
|
); |
504
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($result)) |
505
|
|
|
{ |
506
|
|
|
// Show the topic's subject for each of the actions. |
507
|
|
|
foreach ($topic_ids[$row['id_topic']] as $k => $session_text) |
508
|
|
|
$data[$k] = sprintf($session_text, $row['id_topic'], censorText($row['subject']), $scripturl); |
509
|
|
|
} |
510
|
|
|
$smcFunc['db_free_result']($result); |
511
|
|
|
} |
512
|
|
|
|
513
|
|
|
// Load board names. |
514
|
|
|
if (!empty($board_ids)) |
515
|
|
|
{ |
516
|
|
|
$result = $smcFunc['db_query']('', ' |
517
|
|
|
SELECT b.id_board, b.name |
518
|
|
|
FROM {db_prefix}boards AS b |
519
|
|
|
WHERE {query_see_board} |
520
|
|
|
AND b.id_board IN ({array_int:board_list}) |
521
|
|
|
LIMIT {int:limit}', |
522
|
|
|
array( |
523
|
|
|
'board_list' => array_keys($board_ids), |
524
|
|
|
'limit' => count($board_ids), |
525
|
|
|
) |
526
|
|
|
); |
527
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($result)) |
528
|
|
|
{ |
529
|
|
|
// Put the board name into the string for each member... |
530
|
|
|
foreach ($board_ids[$row['id_board']] as $k => $session_text) |
531
|
|
|
$data[$k] = sprintf($session_text, $row['id_board'], $row['name'], $scripturl); |
532
|
|
|
} |
533
|
|
|
$smcFunc['db_free_result']($result); |
534
|
|
|
} |
535
|
|
|
|
536
|
|
|
// Load member names for the profile. (is_not_guest permission for viewing their own profile) |
537
|
|
|
$allow_view_own = allowedTo('is_not_guest'); |
538
|
|
|
$allow_view_any = allowedTo('profile_view'); |
539
|
|
|
if (!empty($profile_ids) && ($allow_view_any || $allow_view_own)) |
540
|
|
|
{ |
541
|
|
|
$result = $smcFunc['db_query']('', ' |
542
|
|
|
SELECT id_member, real_name |
543
|
|
|
FROM {db_prefix}members |
544
|
|
|
WHERE id_member IN ({array_int:member_list}) |
545
|
|
|
LIMIT ' . count($profile_ids), |
546
|
|
|
array( |
547
|
|
|
'member_list' => array_keys($profile_ids), |
548
|
|
|
) |
549
|
|
|
); |
550
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($result)) |
551
|
|
|
{ |
552
|
|
|
// If they aren't allowed to view this person's profile, skip it. |
553
|
|
|
if (!$allow_view_any && ($user_info['id'] != $row['id_member'])) |
554
|
|
|
continue; |
555
|
|
|
|
556
|
|
|
// Set their action on each - session/text to sprintf. |
557
|
|
|
foreach ($profile_ids[$row['id_member']] as $k => $session_text) |
558
|
|
|
$data[$k] = sprintf($session_text, $row['id_member'], $row['real_name'], $scripturl); |
559
|
|
|
} |
560
|
|
|
$smcFunc['db_free_result']($result); |
561
|
|
|
} |
562
|
|
|
|
563
|
|
|
call_integration_hook('whos_online_after', array(&$urls, &$data)); |
564
|
|
|
|
565
|
|
|
if (!is_array($urls)) |
566
|
|
|
return isset($data[0]) ? $data[0] : false; |
567
|
|
|
else |
568
|
|
|
return $data; |
569
|
|
|
} |
570
|
|
|
|
571
|
|
|
/** |
572
|
|
|
* It prepares credit and copyright information for the credits page or the admin page |
573
|
|
|
* |
574
|
|
|
* @param bool $in_admin = false, if parameter is true the it will not load the sub-template nor the template file |
575
|
|
|
*/ |
576
|
|
|
function Credits($in_admin = false) |
577
|
|
|
{ |
578
|
|
|
global $context, $smcFunc, $forum_copyright, $txt, $user_info, $scripturl; |
579
|
|
|
|
580
|
|
|
// Don't blink. Don't even blink. Blink and you're dead. |
581
|
|
|
loadLanguage('Who'); |
582
|
|
|
|
583
|
|
|
// Discourage robots from indexing this page. |
584
|
|
|
$context['robot_no_index'] = true; |
585
|
|
|
|
586
|
|
|
if ($in_admin) |
587
|
|
|
{ |
588
|
|
|
$context[$context['admin_menu_name']]['tab_data'] = array( |
589
|
|
|
'title' => $txt['support_credits_title'], |
590
|
|
|
'help' => '', |
591
|
|
|
'description' => '', |
592
|
|
|
); |
593
|
|
|
} |
594
|
|
|
|
595
|
|
|
$context['credits'] = array( |
596
|
|
|
array( |
597
|
|
|
'pretext' => $txt['credits_intro'], |
598
|
|
|
'title' => $txt['credits_team'], |
599
|
|
|
'groups' => array( |
600
|
|
|
array( |
601
|
|
|
'title' => $txt['credits_groups_pm'], |
602
|
|
|
'members' => array( |
603
|
|
|
'Aleksi "Lex" Kilpinen', |
604
|
|
|
// Former Project Managers |
605
|
|
|
'Michele "Illori" Davis', |
606
|
|
|
'Jessica "Suki" González', |
607
|
|
|
'Will "Kindred" Wagner', |
608
|
|
|
), |
609
|
|
|
), |
610
|
|
|
array( |
611
|
|
|
'title' => $txt['credits_groups_dev'], |
612
|
|
|
'members' => array( |
613
|
|
|
// Lead Developer |
614
|
|
|
'Jon "Sesquipedalian" Stovell', |
615
|
|
|
// Developers |
616
|
|
|
'Jessica "Suki" González', |
617
|
|
|
'John "live627" Rayes', |
618
|
|
|
'Oscar "Ozp" Rydhé', |
619
|
|
|
'Shawn Bulen', |
620
|
|
|
|
621
|
|
|
// Former Developers |
622
|
|
|
'Aaron van Geffen', |
623
|
|
|
'Antechinus', |
624
|
|
|
'Bjoern "Bloc" Kristiansen', |
625
|
|
|
'Brad "IchBin™" Grow', |
626
|
|
|
'Colin Schoen', |
627
|
|
|
'emanuele', |
628
|
|
|
'Hendrik Jan "Compuart" Visser', |
629
|
|
|
'Juan "JayBachatero" Hernandez', |
630
|
|
|
'Karl "RegularExpression" Benson', |
631
|
|
|
'Matthew "Labradoodle-360" Kerle', |
632
|
|
|
$user_info['is_admin'] ? 'Matt "Grudge" Wolf' : 'Grudge', |
633
|
|
|
'Michael "Oldiesmann" Eshom', |
634
|
|
|
'Michael "Thantos" Miller', |
635
|
|
|
'Norv', |
636
|
|
|
'Peter "Arantor" Spicer', |
637
|
|
|
'Selman "[SiNaN]" Eser', |
638
|
|
|
'Shitiz "Dragooon" Garg', |
639
|
|
|
// 'Spuds', // Doesn't want to be listed here |
640
|
|
|
// 'Steven "Fustrate" Hoffman', |
641
|
|
|
'Theodore "Orstio" Hildebrandt', |
642
|
|
|
'Thorsten "TE" Eurich', |
643
|
|
|
'winrules', |
644
|
|
|
), |
645
|
|
|
), |
646
|
|
|
array( |
647
|
|
|
'title' => $txt['credits_groups_support'], |
648
|
|
|
'members' => array( |
649
|
|
|
// Lead Support Specialist |
650
|
|
|
'Will "Kindred" Wagner', |
651
|
|
|
// Support Specialists |
652
|
|
|
'lurkalot', |
653
|
|
|
'shadav', |
654
|
|
|
'Steve', |
655
|
|
|
|
656
|
|
|
// Former Support Specialists |
657
|
|
|
'Aleksi "Lex" Kilpinen', |
658
|
|
|
'br360', |
659
|
|
|
'GigaWatt', |
660
|
|
|
'ziycon', |
661
|
|
|
'Adam Tallon', |
662
|
|
|
'Bigguy', |
663
|
|
|
'Bruno "margarett" Alves', |
664
|
|
|
'CapadY', |
665
|
|
|
'ChalkCat', |
666
|
|
|
'Chas Large', |
667
|
|
|
'Duncan85', |
668
|
|
|
'gbsothere', |
669
|
|
|
'JimM', |
670
|
|
|
'Justyne', |
671
|
|
|
'Kat', |
672
|
|
|
'Kevin "greyknight17" Hou', |
673
|
|
|
'Krash', |
674
|
|
|
'Mashby', |
675
|
|
|
'Michael Colin Blaber', |
676
|
|
|
'Old Fossil', |
677
|
|
|
'S-Ace', |
678
|
|
|
'Storman™', |
679
|
|
|
'Wade "sησω" Poulsen', |
680
|
|
|
'xenovanis', |
681
|
|
|
), |
682
|
|
|
), |
683
|
|
|
array( |
684
|
|
|
'title' => $txt['credits_groups_customize'], |
685
|
|
|
'members' => array( |
686
|
|
|
// Lead Customizer |
687
|
|
|
'Gary M. Gadsdon', |
688
|
|
|
// Customizers |
689
|
|
|
'Diego Andrés', |
690
|
|
|
'Jonathan "vbgamer45" Valentin', |
691
|
|
|
'Michael "Mick." Gomez', |
692
|
|
|
|
693
|
|
|
// Former Customizers |
694
|
|
|
'Sami "SychO" Mazouz', |
695
|
|
|
'Brannon "B" Hall', |
696
|
|
|
'Jack "akabugeyes" Thorsen', |
697
|
|
|
'Jason "JBlaze" Clemons', |
698
|
|
|
'Joey "Tyrsson" Smith', |
699
|
|
|
'Kays', |
700
|
|
|
'NanoSector', |
701
|
|
|
'Ricky.', |
702
|
|
|
'Russell "NEND" Najar', |
703
|
|
|
'SA™', |
704
|
|
|
), |
705
|
|
|
), |
706
|
|
|
array( |
707
|
|
|
'title' => $txt['credits_groups_docs'], |
708
|
|
|
'members' => array( |
709
|
|
|
// Doc Coordinator |
710
|
|
|
'Michele "Illori" Davis', |
711
|
|
|
// Doc Writers |
712
|
|
|
'Irisado', |
713
|
|
|
|
714
|
|
|
// Former Doc Writers |
715
|
|
|
'AngelinaBelle', |
716
|
|
|
'Chainy', |
717
|
|
|
'Graeme Spence', |
718
|
|
|
'Joshua "groundup" Dickerson', |
719
|
|
|
), |
720
|
|
|
), |
721
|
|
|
array( |
722
|
|
|
'title' => $txt['credits_groups_internationalizers'], |
723
|
|
|
'members' => array( |
724
|
|
|
// Lead Localizer |
725
|
|
|
'Nikola "Dzonny" Novaković', |
726
|
|
|
// Localizers |
727
|
|
|
'm4z', |
728
|
|
|
// Former Localizers |
729
|
|
|
'Francisco "d3vcho" Domínguez', |
730
|
|
|
'Robert Monden', |
731
|
|
|
'Relyana', |
732
|
|
|
), |
733
|
|
|
), |
734
|
|
|
array( |
735
|
|
|
'title' => $txt['credits_groups_marketing'], |
736
|
|
|
'members' => array( |
737
|
|
|
// Marketing Coordinator |
738
|
|
|
|
739
|
|
|
// Marketing |
740
|
|
|
|
741
|
|
|
// Former Marketing |
742
|
|
|
'Adish "(F.L.A.M.E.R)" Patel', |
743
|
|
|
'Bryan "Runic" Deakin', |
744
|
|
|
'Marcus "cσσкιє мσηѕтєя" Forsberg', |
745
|
|
|
'Ralph "[n3rve]" Otowo', |
746
|
|
|
), |
747
|
|
|
), |
748
|
|
|
array( |
749
|
|
|
'title' => $txt['credits_groups_site'], |
750
|
|
|
'members' => array( |
751
|
|
|
'Jeremy "SleePy" Darwood', |
752
|
|
|
), |
753
|
|
|
), |
754
|
|
|
array( |
755
|
|
|
'title' => $txt['credits_groups_servers'], |
756
|
|
|
'members' => array( |
757
|
|
|
'Derek Schwab', |
758
|
|
|
'Michael Johnson', |
759
|
|
|
'Liroy van Hoewijk', |
760
|
|
|
), |
761
|
|
|
), |
762
|
|
|
), |
763
|
|
|
), |
764
|
|
|
); |
765
|
|
|
|
766
|
|
|
// Give the translators some credit for their hard work. |
767
|
|
|
if (!is_array($txt['translation_credits'])) |
768
|
|
|
$txt['translation_credits'] = array_filter(array_map('trim', explode(',', $txt['translation_credits']))); |
769
|
|
|
|
770
|
|
|
if (!empty($txt['translation_credits'])) |
771
|
|
|
$context['credits'][] = array( |
772
|
|
|
'title' => $txt['credits_groups_translation'], |
773
|
|
|
'groups' => array( |
774
|
|
|
array( |
775
|
|
|
'title' => $txt['credits_groups_translation'], |
776
|
|
|
'members' => $txt['translation_credits'], |
777
|
|
|
), |
778
|
|
|
), |
779
|
|
|
); |
780
|
|
|
|
781
|
|
|
$context['credits'][] = array( |
782
|
|
|
'title' => $txt['credits_special'], |
783
|
|
|
'posttext' => $txt['credits_anyone'], |
784
|
|
|
'groups' => array( |
785
|
|
|
array( |
786
|
|
|
'title' => $txt['credits_groups_consultants'], |
787
|
|
|
'members' => array( |
788
|
|
|
'albertlast', |
789
|
|
|
'Brett Flannigan', |
790
|
|
|
'Mark Rose', |
791
|
|
|
'René-Gilles "Nao 尚" Deberdt', |
792
|
|
|
'tinoest', |
793
|
|
|
$txt['credits_code_contributors'], |
794
|
|
|
), |
795
|
|
|
), |
796
|
|
|
array( |
797
|
|
|
'title' => $txt['credits_groups_beta'], |
798
|
|
|
'members' => array( |
799
|
|
|
$txt['credits_beta_message'], |
800
|
|
|
), |
801
|
|
|
), |
802
|
|
|
array( |
803
|
|
|
'title' => $txt['credits_groups_translators'], |
804
|
|
|
'members' => array( |
805
|
|
|
$txt['credits_translators_message'], |
806
|
|
|
), |
807
|
|
|
), |
808
|
|
|
array( |
809
|
|
|
'title' => $txt['credits_groups_founder'], |
810
|
|
|
'members' => array( |
811
|
|
|
'Unknown W. "[Unknown]" Brackets', |
812
|
|
|
), |
813
|
|
|
), |
814
|
|
|
array( |
815
|
|
|
'title' => $txt['credits_groups_orignal_pm'], |
816
|
|
|
'members' => array( |
817
|
|
|
'Jeff Lewis', |
818
|
|
|
'Joseph Fung', |
819
|
|
|
'David Recordon', |
820
|
|
|
), |
821
|
|
|
), |
822
|
|
|
array( |
823
|
|
|
'title' => $txt['credits_in_memoriam'], |
824
|
|
|
'members' => array( |
825
|
|
|
'Crip', |
826
|
|
|
'K@', |
827
|
|
|
'metallica48423', |
828
|
|
|
'Paul_Pauline', |
829
|
|
|
), |
830
|
|
|
), |
831
|
|
|
), |
832
|
|
|
); |
833
|
|
|
|
834
|
|
|
// Give credit to any graphic library's, software library's, plugins etc |
835
|
|
|
$context['credits_software_graphics'] = array( |
836
|
|
|
'graphics' => array( |
837
|
|
|
'<a href="http://p.yusukekamiyamane.com/">Fugue Icons</a> | © 2012 Yusuke Kamiyamane | These icons are licensed under a Creative Commons Attribution 3.0 License', |
838
|
|
|
'<a href="https://techbase.kde.org/Projects/Oxygen/Licensing#Use_on_Websites">Oxygen Icons</a> | These icons are licensed under <a href="http://www.gnu.org/copyleft/lesser.html">GNU LGPLv3</a>', |
839
|
|
|
), |
840
|
|
|
'software' => array( |
841
|
|
|
'<a href="https://jquery.org/">JQuery</a> | © John Resig | Licensed under <a href="https://github.com/jquery/jquery/blob/master/LICENSE.txt">The MIT License (MIT)</a>', |
842
|
|
|
'<a href="https://briancherne.github.io/jquery-hoverIntent/">hoverIntent</a> | © Brian Cherne | Licensed under <a href="https://en.wikipedia.org/wiki/MIT_License">The MIT License (MIT)</a>', |
843
|
|
|
'<a href="https://www.sceditor.com/">SCEditor</a> | © Sam Clarke | Licensed under <a href="https://en.wikipedia.org/wiki/MIT_License">The MIT License (MIT)</a>', |
844
|
|
|
'<a href="http://wayfarerweb.com/jquery/plugins/animadrag/">animaDrag</a> | © Abel Mohler | Licensed under <a href="https://en.wikipedia.org/wiki/MIT_License">The MIT License (MIT)</a>', |
845
|
|
|
'<a href="https://github.com/mzubala/jquery-custom-scrollbar">jQuery Custom Scrollbar</a> | © Maciej Zubala | Licensed under <a href="http://en.wikipedia.org/wiki/MIT_License">The MIT License (MIT)</a>', |
846
|
|
|
'<a href="http://slippry.com/">jQuery Responsive Slider</a> | © booncon ROCKETS | Licensed under <a href="http://en.wikipedia.org/wiki/MIT_License">The MIT License (MIT)</a>', |
847
|
|
|
'<a href="https://github.com/ichord/At.js">At.js</a> | © [email protected] | Licensed under <a href="https://github.com/ichord/At.js/blob/master/LICENSE-MIT">The MIT License (MIT)</a>', |
848
|
|
|
'<a href="https://github.com/ttsvetko/HTML5-Desktop-Notifications">HTML5 Desktop Notifications</a> | © Tsvetan Tsvetkov | Licensed under <a href="https://github.com/ttsvetko/HTML5-Desktop-Notifications/blob/master/License.txt">The Apache License Version 2.0</a>', |
849
|
|
|
'<a href="https://github.com/enygma/gauth">GAuth Code Generator/Validator</a> | © Chris Cornutt | Licensed under <a href="https://github.com/enygma/gauth/blob/master/LICENSE">The MIT License (MIT)</a>', |
850
|
|
|
'<a href="https://github.com/enyo/dropzone">Dropzone.js</a> | © Matias Meno | Licensed under <a href="http://en.wikipedia.org/wiki/MIT_License">The MIT License (MIT)</a>', |
851
|
|
|
'<a href="https://github.com/matthiasmullie/minify">Minify</a> | © Matthias Mullie | Licensed under <a href="http://en.wikipedia.org/wiki/MIT_License">The MIT License (MIT)</a>', |
852
|
|
|
'<a href="https://github.com/true/php-punycode">PHP-Punycode</a> | © True B.V. | Licensed under <a href="http://en.wikipedia.org/wiki/MIT_License">The MIT License (MIT)</a>', |
853
|
|
|
), |
854
|
|
|
'fonts' => array( |
855
|
|
|
'<a href="https://fontlibrary.org/en/font/anonymous-pro"> Anonymous Pro</a> | © 2009 | This font is licensed under the SIL Open Font License, Version 1.1', |
856
|
|
|
'<a href="https://fontlibrary.org/en/font/consolamono"> ConsolaMono</a> | © 2012 | This font is licensed under the SIL Open Font License, Version 1.1', |
857
|
|
|
'<a href="https://fontlibrary.org/en/font/phennig"> Phennig</a> | © 2009-2012 | This font is licensed under the SIL Open Font License, Version 1.1', |
858
|
|
|
), |
859
|
|
|
); |
860
|
|
|
|
861
|
|
|
// Support for mods that use the <credits> tag via the package manager |
862
|
|
|
$context['credits_modifications'] = array(); |
863
|
|
|
if (($mods = cache_get_data('mods_credits', 86400)) === null) |
864
|
|
|
{ |
865
|
|
|
$mods = array(); |
866
|
|
|
$request = $smcFunc['db_query']('substring', ' |
867
|
|
|
SELECT version, name, credits |
868
|
|
|
FROM {db_prefix}log_packages |
869
|
|
|
WHERE install_state = {int:installed_mods} |
870
|
|
|
AND credits != {string:empty} |
871
|
|
|
AND SUBSTRING(filename, 1, 9) != {string:patch_name}', |
872
|
|
|
array( |
873
|
|
|
'installed_mods' => 1, |
874
|
|
|
'patch_name' => 'smf_patch', |
875
|
|
|
'empty' => '', |
876
|
|
|
) |
877
|
|
|
); |
878
|
|
|
|
879
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
880
|
|
|
{ |
881
|
|
|
$credit_info = $smcFunc['json_decode']($row['credits'], true); |
882
|
|
|
|
883
|
|
|
$copyright = empty($credit_info['copyright']) ? '' : $txt['credits_copyright'] . ' © ' . $smcFunc['htmlspecialchars']($credit_info['copyright']); |
884
|
|
|
$license = empty($credit_info['license']) ? '' : $txt['credits_license'] . ': ' . (!empty($credit_info['licenseurl']) ? '<a href="' . $smcFunc['htmlspecialchars']($credit_info['licenseurl']) . '">' . $smcFunc['htmlspecialchars']($credit_info['license']) . '</a>' : $smcFunc['htmlspecialchars']($credit_info['license'])); |
885
|
|
|
$version = $txt['credits_version'] . ' ' . $row['version']; |
886
|
|
|
$title = (empty($credit_info['title']) ? $row['name'] : $smcFunc['htmlspecialchars']($credit_info['title'])) . ': ' . $version; |
887
|
|
|
|
888
|
|
|
// build this one out and stash it away |
889
|
|
|
$mod_name = empty($credit_info['url']) ? $title : '<a href="' . $credit_info['url'] . '">' . $title . '</a>'; |
890
|
|
|
$mods[] = $mod_name . (!empty($license) ? ' | ' . $license : '') . (!empty($copyright) ? ' | ' . $copyright : ''); |
891
|
|
|
} |
892
|
|
|
cache_put_data('mods_credits', $mods, 86400); |
893
|
|
|
} |
894
|
|
|
$context['credits_modifications'] = $mods; |
895
|
|
|
|
896
|
|
|
$context['copyrights'] = array( |
897
|
|
|
'smf' => sprintf($forum_copyright, SMF_FULL_VERSION, SMF_SOFTWARE_YEAR, $scripturl), |
898
|
|
|
/* Modification Authors: You may add a copyright statement to this array for your mods. |
899
|
|
|
Copyright statements should be in the form of a value only without a array key. I.E.: |
900
|
|
|
'Some Mod by Thantos © 2010', |
901
|
|
|
$txt['some_mod_copyright'], |
902
|
|
|
*/ |
903
|
|
|
'mods' => array( |
904
|
|
|
), |
905
|
|
|
); |
906
|
|
|
|
907
|
|
|
// Support for those that want to use a hook as well |
908
|
|
|
call_integration_hook('integrate_credits'); |
909
|
|
|
|
910
|
|
|
if (!$in_admin) |
911
|
|
|
{ |
912
|
|
|
loadTemplate('Who'); |
913
|
|
|
$context['sub_template'] = 'credits'; |
914
|
|
|
$context['robot_no_index'] = true; |
915
|
|
|
$context['page_title'] = $txt['credits']; |
916
|
|
|
} |
917
|
|
|
} |
918
|
|
|
|
919
|
|
|
?> |