Passed
Push — release-2.1 ( 0c2197...207d2d )
by Jeremy
05:47
created

Who.php ➔ determineActions()   F

Complexity

Conditions 75
Paths > 20000

Size

Total Lines 276

Duplication

Lines 18
Ratio 6.52 %

Importance

Changes 0
Metric Value
cc 75
nc 273601
nop 2
dl 18
loc 276
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
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 http://www.simplemachines.org
11
 * @copyright 2018 Simple Machines and individual contributors
12
 * @license http://www.simplemachines.org/about/smf/license.php BSD
13
 *
14
 * @version 2.1 Beta 4
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
	// Load the 'Who' template.
42
	loadTemplate('Who');
43
	loadLanguage('Who');
44
45
	// Sort out... the column sorting.
46
	$sort_methods = array(
47
		'user' => 'mem.real_name',
48
		'time' => 'lo.log_time'
49
	);
50
51
	$show_methods = array(
52
		'members' => '(lo.id_member != 0)',
53
		'guests' => '(lo.id_member = 0)',
54
		'all' => '1=1',
55
	);
56
57
	// Store the sort methods and the show types for use in the template.
58
	$context['sort_methods'] = array(
59
		'user' => $txt['who_user'],
60
		'time' => $txt['who_time'],
61
	);
62
	$context['show_methods'] = array(
63
		'all' => $txt['who_show_all'],
64
		'members' => $txt['who_show_members_only'],
65
		'guests' => $txt['who_show_guests_only'],
66
	);
67
68
	// Can they see spiders too?
69
	if (!empty($modSettings['show_spider_online']) && ($modSettings['show_spider_online'] == 2 || allowedTo('admin_forum')) && !empty($modSettings['spider_name_cache']))
70
	{
71
		$show_methods['spiders'] = '(lo.id_member = 0 AND lo.id_spider > 0)';
72
		$show_methods['guests'] = '(lo.id_member = 0 AND lo.id_spider = 0)';
73
		$context['show_methods']['spiders'] = $txt['who_show_spiders_only'];
74
	}
75
	elseif (empty($modSettings['show_spider_online']) && isset($_SESSION['who_online_filter']) && $_SESSION['who_online_filter'] == 'spiders')
76
		unset($_SESSION['who_online_filter']);
77
78
	// Does the user prefer a different sort direction?
79
	if (isset($_REQUEST['sort']) && isset($sort_methods[$_REQUEST['sort']]))
80
	{
81
		$context['sort_by'] = $_SESSION['who_online_sort_by'] = $_REQUEST['sort'];
82
		$sort_method = $sort_methods[$_REQUEST['sort']];
83
	}
84
	// Did we set a preferred sort order earlier in the session?
85
	elseif (isset($_SESSION['who_online_sort_by']))
86
	{
87
		$context['sort_by'] = $_SESSION['who_online_sort_by'];
88
		$sort_method = $sort_methods[$_SESSION['who_online_sort_by']];
89
	}
90
	// Default to last time online.
91
	else
92
	{
93
		$context['sort_by'] = $_SESSION['who_online_sort_by'] = 'time';
94
		$sort_method = 'lo.log_time';
95
	}
96
97
	$context['sort_direction'] = isset($_REQUEST['asc']) || (isset($_REQUEST['sort_dir']) && $_REQUEST['sort_dir'] == 'asc') ? 'up' : 'down';
98
99
	$conditions = array();
100
	if (!allowedTo('moderate_forum'))
101
		$conditions[] = '(COALESCE(mem.show_online, 1) = 1)';
102
103
	// Fallback to top filter?
104
	if (isset($_REQUEST['submit_top']) && isset($_REQUEST['show_top']))
105
		$_REQUEST['show'] = $_REQUEST['show_top'];
106
	// Does the user wish to apply a filter?
107
	if (isset($_REQUEST['show']) && isset($show_methods[$_REQUEST['show']]))
108
		$context['show_by'] = $_SESSION['who_online_filter'] = $_REQUEST['show'];
109
	// Perhaps we saved a filter earlier in the session?
110
	elseif (isset($_SESSION['who_online_filter']))
111
		$context['show_by'] = $_SESSION['who_online_filter'];
112
	else
113
		$context['show_by'] = 'members';
114
115
	$conditions[] = $show_methods[$context['show_by']];
116
117
	// Get the total amount of members online.
118
	$request = $smcFunc['db_query']('', '
119
		SELECT COUNT(*)
120
		FROM {db_prefix}log_online AS lo
121
			LEFT JOIN {db_prefix}members AS mem ON (lo.id_member = mem.id_member)' . (!empty($conditions) ? '
122
		WHERE ' . implode(' AND ', $conditions) : ''),
123
		array(
124
		)
125
	);
126
	list ($totalMembers) = $smcFunc['db_fetch_row']($request);
127
	$smcFunc['db_free_result']($request);
128
129
	// Prepare some page index variables.
130
	$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']);
131
	$context['start'] = $_REQUEST['start'];
132
133
	// Look for people online, provided they don't mind if you see they are.
134
	$request = $smcFunc['db_query']('', '
135
		SELECT
136
			lo.log_time, lo.id_member, lo.url, lo.ip AS ip, mem.real_name,
137
			lo.session, mg.online_color, COALESCE(mem.show_online, 1) AS show_online,
138
			lo.id_spider
139
		FROM {db_prefix}log_online AS lo
140
			LEFT JOIN {db_prefix}members AS mem ON (lo.id_member = mem.id_member)
141
			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) ? '
142
		WHERE ' . implode(' AND ', $conditions) : '') . '
143
		ORDER BY {raw:sort_method} {raw:sort_direction}
144
		LIMIT {int:offset}, {int:limit}',
145
		array(
146
			'regular_member' => 0,
147
			'sort_method' => $sort_method,
148
			'sort_direction' => $context['sort_direction'] == 'up' ? 'ASC' : 'DESC',
149
			'offset' => $context['start'],
150
			'limit' => $modSettings['defaultMaxMembers'],
151
		)
152
	);
153
	$context['members'] = array();
154
	$member_ids = array();
155
	$url_data = array();
156
	while ($row = $smcFunc['db_fetch_assoc']($request))
157
	{
158
		$actions = $smcFunc['json_decode']($row['url'], true);
159
		if ($actions === false)
160
			continue;
161
162
		// Send the information to the template.
163
		$context['members'][$row['session']] = array(
164
			'id' => $row['id_member'],
165
			'ip' => allowedTo('moderate_forum') ? inet_dtop($row['ip']) : '',
166
			// It is *going* to be today or yesterday, so why keep that information in there?
167
			'time' => strtr(timeformat($row['log_time']), array($txt['today'] => '', $txt['yesterday'] => '')),
168
			'timestamp' => forum_time(true, $row['log_time']),
169
			'query' => $actions,
170
			'is_hidden' => $row['show_online'] == 0,
171
			'id_spider' => $row['id_spider'],
172
			'color' => empty($row['online_color']) ? '' : $row['online_color']
173
		);
174
175
		$url_data[$row['session']] = array($row['url'], $row['id_member']);
176
		$member_ids[] = $row['id_member'];
177
	}
178
	$smcFunc['db_free_result']($request);
179
180
	// Load the user data for these members.
181
	loadMemberData($member_ids);
182
183
	// Load up the guest user.
184
	$memberContext[0] = array(
185
		'id' => 0,
186
		'name' => $txt['guest_title'],
187
		'group' => $txt['guest_title'],
188
		'href' => '',
189
		'link' => $txt['guest_title'],
190
		'email' => $txt['guest_title'],
191
		'is_guest' => true
192
	);
193
194
	// Are we showing spiders?
195
	$spiderContext = array();
196
	if (!empty($modSettings['show_spider_online']) && ($modSettings['show_spider_online'] == 2 || allowedTo('admin_forum')) && !empty($modSettings['spider_name_cache']))
197
	{
198
		foreach ($smcFunc['json_decode']($modSettings['spider_name_cache'], true) as $id => $name)
199
			$spiderContext[$id] = array(
200
				'id' => 0,
201
				'name' => $name,
202
				'group' => $txt['spiders'],
203
				'href' => '',
204
				'link' => $name,
205
				'email' => $name,
206
				'is_guest' => true
207
			);
208
	}
209
210
	$url_data = determineActions($url_data);
211
212
	// Setup the linktree and page title (do it down here because the language files are now loaded..)
213
	$context['page_title'] = $txt['who_title'];
214
	$context['linktree'][] = array(
215
		'url' => $scripturl . '?action=who',
216
		'name' => $txt['who_title']
217
	);
218
219
	// Put it in the context variables.
220
	foreach ($context['members'] as $i => $member)
221
	{
222
		if ($member['id'] != 0)
223
			$member['id'] = loadMemberContext($member['id']) ? $member['id'] : 0;
224
225
		// Keep the IP that came from the database.
226
		$memberContext[$member['id']]['ip'] = $member['ip'];
227
		$context['members'][$i]['action'] = isset($url_data[$i]) ? $url_data[$i] : $txt['who_hidden'];
228
		if ($member['id'] == 0 && isset($spiderContext[$member['id_spider']]))
229
			$context['members'][$i] += $spiderContext[$member['id_spider']];
230
		else
231
			$context['members'][$i] += $memberContext[$member['id']];
232
	}
233
234
	// Some people can't send personal messages...
235
	$context['can_send_pm'] = allowedTo('pm_send');
236
	$context['can_send_email'] = allowedTo('send_email_to_members');
237
238
	// any profile fields disabled?
239
	$context['disabled_fields'] = isset($modSettings['disabled_profile_fields']) ? array_flip(explode(',', $modSettings['disabled_profile_fields'])) : array();
240
241
}
242
243
/**
244
 * This function determines the actions of the members passed in urls.
245
 *
246
 * Adding actions to the Who's Online list:
247
 * Adding actions to this list is actually relatively easy...
248
 *  - for actions anyone should be able to see, just add a string named whoall_ACTION.
249
 *    (where ACTION is the action used in index.php.)
250
 *  - for actions that have a subaction which should be represented differently, use whoall_ACTION_SUBACTION.
251
 *  - for actions that include a topic, and should be restricted, use whotopic_ACTION.
252
 *  - for actions that use a message, by msg or quote, use whopost_ACTION.
253
 *  - for administrator-only actions, use whoadmin_ACTION.
254
 *  - for actions that should be viewable only with certain permissions,
255
 *    use whoallow_ACTION and add a list of possible permissions to the
256
 *    $allowedActions array, using ACTION as the key.
257
 *
258
 * @param mixed $urls  a single url (string) or an array of arrays, each inner array being (JSON-encoded request data, id_member)
259
 * @param string|bool $preferred_prefix = false
260
 * @return array, an array of descriptions if you passed an array, otherwise the string describing their current location.
261
 */
262
function determineActions($urls, $preferred_prefix = false)
263
{
264
	global $txt, $user_info, $modSettings, $smcFunc;
265
266
	if (!allowedTo('who_view'))
267
		return array();
268
	loadLanguage('Who');
269
270
	// Actions that require a specific permission level.
271
	$allowedActions = array(
272
		'admin' => array('moderate_forum', 'manage_membergroups', 'manage_bans', 'admin_forum', 'manage_permissions', 'send_mail', 'manage_attachments', 'manage_smileys', 'manage_boards', 'edit_news'),
273
		'ban' => array('manage_bans'),
274
		'boardrecount' => array('admin_forum'),
275
		'calendar' => array('calendar_view'),
276
		'editnews' => array('edit_news'),
277
		'mailing' => array('send_mail'),
278
		'maintain' => array('admin_forum'),
279
		'manageattachments' => array('manage_attachments'),
280
		'manageboards' => array('manage_boards'),
281
		'mlist' => array('view_mlist'),
282
		'moderate' => array('access_mod_center', 'moderate_forum', 'manage_membergroups'),
283
		'optimizetables' => array('admin_forum'),
284
		'repairboards' => array('admin_forum'),
285
		'search' => array('search_posts'),
286
		'search2' => array('search_posts'),
287
		'setcensor' => array('moderate_forum'),
288
		'setreserve' => array('moderate_forum'),
289
		'stats' => array('view_stats'),
290
		'viewErrorLog' => array('admin_forum'),
291
		'viewmembers' => array('moderate_forum'),
292
	);
293
	call_integration_hook('who_allowed', array(&$allowedActions));
294
295
	if (!is_array($urls))
296
		$url_list = array(array($urls, $user_info['id']));
297
	else
298
		$url_list = $urls;
299
300
	// These are done to later query these in large chunks. (instead of one by one.)
301
	$topic_ids = array();
302
	$profile_ids = array();
303
	$board_ids = array();
304
305
	$data = array();
306
	foreach ($url_list as $k => $url)
307
	{
308
		// Get the request parameters..
309
		$actions = $smcFunc['json_decode']($url[0], true);
310
		if ($actions === false)
311
			continue;
312
313
		// If it's the admin or moderation center, and there is an area set, use that instead.
314
		if (isset($actions['action']) && ($actions['action'] == 'admin' || $actions['action'] == 'moderate') && isset($actions['area']))
315
			$actions['action'] = $actions['area'];
316
317
		// Check if there was no action or the action is display.
318
		if (!isset($actions['action']) || $actions['action'] == 'display')
319
		{
320
			// It's a topic!  Must be!
321
			if (isset($actions['topic']))
322
			{
323
				// Assume they can't view it, and queue it up for later.
324
				$data[$k] = $txt['who_hidden'];
325
				$topic_ids[(int) $actions['topic']][$k] = $txt['who_topic'];
326
			}
327
			// It's a board!
328
			elseif (isset($actions['board']))
329
			{
330
				// Hide first, show later.
331
				$data[$k] = $txt['who_hidden'];
332
				$board_ids[$actions['board']][$k] = $txt['who_board'];
333
			}
334
			// It's the board index!!  It must be!
335
			else
336
				$data[$k] = $txt['who_index'];
337
		}
338
		// Probably an error or some goon?
339
		elseif ($actions['action'] == '')
340
			$data[$k] = $txt['who_index'];
341
		// Some other normal action...?
342
		else
343
		{
344
			// Viewing/editing a profile.
345
			if ($actions['action'] == 'profile')
346
			{
347
				// Whose?  Their own?
348
				if (empty($actions['u']))
349
					$actions['u'] = $url[1];
350
351
				$data[$k] = $txt['who_hidden'];
352
				$profile_ids[(int) $actions['u']][$k] = $actions['u'] == $url[1] ? $txt['who_viewownprofile'] : $txt['who_viewprofile'];
353
			}
354
			elseif (($actions['action'] == 'post' || $actions['action'] == 'post2') && empty($actions['topic']) && isset($actions['board']))
355
			{
356
				$data[$k] = $txt['who_hidden'];
357
				$board_ids[(int) $actions['board']][$k] = isset($actions['poll']) ? $txt['who_poll'] : $txt['who_post'];
358
			}
359
			// A subaction anyone can view... if the language string is there, show it.
360
			elseif (isset($actions['sa']) && isset($txt['whoall_' . $actions['action'] . '_' . $actions['sa']]))
361
				$data[$k] = $preferred_prefix && isset($txt[$preferred_prefix . $actions['action'] . '_' . $actions['sa']]) ? $txt[$preferred_prefix . $actions['action'] . '_' . $actions['sa']] : $txt['whoall_' . $actions['action'] . '_' . $actions['sa']];
0 ignored issues
show
Bug introduced by
Are you sure $preferred_prefix of type string|true can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

361
				$data[$k] = $preferred_prefix && isset($txt[/** @scrutinizer ignore-type */ $preferred_prefix . $actions['action'] . '_' . $actions['sa']]) ? $txt[$preferred_prefix . $actions['action'] . '_' . $actions['sa']] : $txt['whoall_' . $actions['action'] . '_' . $actions['sa']];
Loading history...
362
			// An action any old fellow can look at. (if ['whoall_' . $action] exists, we know everyone can see it.)
363
			elseif (isset($txt['whoall_' . $actions['action']]))
364
				$data[$k] = $preferred_prefix && isset($txt[$preferred_prefix . $actions['action']]) ? $txt[$preferred_prefix . $actions['action']] : $txt['whoall_' . $actions['action']];
365
			// Viewable if and only if they can see the board...
366
			elseif (isset($txt['whotopic_' . $actions['action']]))
367
			{
368
				// Find out what topic they are accessing.
369
				$topic = (int) (isset($actions['topic']) ? $actions['topic'] : (isset($actions['from']) ? $actions['from'] : 0));
370
371
				$data[$k] = $txt['who_hidden'];
372
				$topic_ids[$topic][$k] = $txt['whotopic_' . $actions['action']];
373
			}
374
			elseif (isset($txt['whopost_' . $actions['action']]))
375
			{
376
				// Find out what message they are accessing.
377
				$msgid = (int) (isset($actions['msg']) ? $actions['msg'] : (isset($actions['quote']) ? $actions['quote'] : 0));
378
379
				$result = $smcFunc['db_query']('', '
380
					SELECT m.id_topic, m.subject
381
					FROM {db_prefix}messages AS m
382
						INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board)
383
						INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic' . ($modSettings['postmod_active'] ? ' AND t.approved = {int:is_approved}' : '') . ')
384
					WHERE m.id_msg = {int:id_msg}
385
						AND {query_see_board}' . ($modSettings['postmod_active'] ? '
386
						AND m.approved = {int:is_approved}' : '') . '
387
					LIMIT 1',
388
					array(
389
						'is_approved' => 1,
390
						'id_msg' => $msgid,
391
					)
392
				);
393
				list ($id_topic, $subject) = $smcFunc['db_fetch_row']($result);
394
				$data[$k] = sprintf($txt['whopost_' . $actions['action']], $id_topic, $subject);
395
				$smcFunc['db_free_result']($result);
396
397
				if (empty($id_topic))
398
					$data[$k] = $txt['who_hidden'];
399
			}
400
			// Viewable only by administrators.. (if it starts with whoadmin, it's admin only!)
401
			elseif (allowedTo('moderate_forum') && isset($txt['whoadmin_' . $actions['action']]))
402
				$data[$k] = $txt['whoadmin_' . $actions['action']];
403
			// Viewable by permission level.
404
			elseif (isset($allowedActions[$actions['action']]))
405
			{
406
				if (allowedTo($allowedActions[$actions['action']]))
407
					$data[$k] = $txt['whoallow_' . $actions['action']];
408
				elseif (in_array('moderate_forum', $allowedActions[$actions['action']]))
409
					$data[$k] = $txt['who_moderate'];
410
				elseif (in_array('admin_forum', $allowedActions[$actions['action']]))
411
					$data[$k] = $txt['who_admin'];
412
				else
413
					$data[$k] = $txt['who_hidden'];
414
			}
415
			elseif (!empty($actions['action']))
416
				$data[$k] = $txt['who_generic'] . ' ' . $actions['action'];
417
			else
418
				$data[$k] = $txt['who_unknown'];
419
		}
420
421
		if (isset($actions['error']))
422
		{
423
			if (isset($txt[$actions['error']]))
424
				$error_message = str_replace('"', '&quot;', empty($actions['who_error_params']) ? $txt[$actions['error']] : vsprintf($txt[$actions['error']], $actions['who_error_params']));
425
			elseif ($actions['error'] == 'guest_login')
426
				$error_message = str_replace('"', '&quot;', $txt['who_guest_login']);
427
			else
428
				$error_message = str_replace('"', '&quot;', $actions['error']);
429
430
			if (!empty($error_message))
431
				$data[$k] .= ' <span class="generic_icons error" title="' . $error_message . '"></span>';
432
		}
433
434
		// Maybe the action is integrated into another system?
435
		if (count($integrate_actions = call_integration_hook('integrate_whos_online', array($actions))) > 0)
436
		{
437
			foreach ($integrate_actions as $integrate_action)
438
			{
439
				if (!empty($integrate_action))
440
				{
441
					$data[$k] = $integrate_action;
442
					if (isset($actions['topic']) && isset($topic_ids[(int) $actions['topic']][$k]))
443
						$topic_ids[(int) $actions['topic']][$k] = $integrate_action;
444
					if (isset($actions['board']) && isset($board_ids[(int) $actions['board']][$k]))
445
						$board_ids[(int) $actions['board']][$k] = $integrate_action;
446
					if (isset($actions['u']) && isset($profile_ids[(int) $actions['u']][$k]))
447
						$profile_ids[(int) $actions['u']][$k] = $integrate_action;
448
					break;
449
				}
450
			}
451
		}
452
	}
453
454
	// Load topic names.
455
	if (!empty($topic_ids))
456
	{
457
		$result = $smcFunc['db_query']('', '
458
			SELECT t.id_topic, m.subject
459
			FROM {db_prefix}topics AS t
460
				INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
461
				INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
462
			WHERE {query_see_board}
463
				AND t.id_topic IN ({array_int:topic_list})' . ($modSettings['postmod_active'] ? '
464
				AND t.approved = {int:is_approved}' : '') . '
465
			LIMIT {int:limit}',
466
			array(
467
				'topic_list' => array_keys($topic_ids),
468
				'is_approved' => 1,
469
				'limit' => count($topic_ids),
470
			)
471
		);
472
		while ($row = $smcFunc['db_fetch_assoc']($result))
473
		{
474
			// Show the topic's subject for each of the actions.
475
			foreach ($topic_ids[$row['id_topic']] as $k => $session_text)
476
				$data[$k] = sprintf($session_text, $row['id_topic'], censorText($row['subject']));
477
		}
478
		$smcFunc['db_free_result']($result);
479
	}
480
481
	// Load board names.
482
	if (!empty($board_ids))
483
	{
484
		$result = $smcFunc['db_query']('', '
485
			SELECT b.id_board, b.name
486
			FROM {db_prefix}boards AS b
487
			WHERE {query_see_board}
488
				AND b.id_board IN ({array_int:board_list})
489
			LIMIT {int:limit}',
490
			array(
491
				'board_list' => array_keys($board_ids),
492
				'limit' => count($board_ids),
493
			)
494
		);
495
		while ($row = $smcFunc['db_fetch_assoc']($result))
496
		{
497
			// Put the board name into the string for each member...
498
			foreach ($board_ids[$row['id_board']] as $k => $session_text)
499
				$data[$k] = sprintf($session_text, $row['id_board'], $row['name']);
500
		}
501
		$smcFunc['db_free_result']($result);
502
	}
503
504
	// Load member names for the profile. (is_not_guest permission for viewing their own profile)
505
	$allow_view_own = allowedTo('is_not_guest');
506
	$allow_view_any = allowedTo('profile_view');
507
	if (!empty($profile_ids) && ($allow_view_any || $allow_view_own))
508
	{
509
		$result = $smcFunc['db_query']('', '
510
			SELECT id_member, real_name
511
			FROM {db_prefix}members
512
			WHERE id_member IN ({array_int:member_list})
513
			LIMIT ' . count($profile_ids),
514
			array(
515
				'member_list' => array_keys($profile_ids),
516
			)
517
		);
518
		while ($row = $smcFunc['db_fetch_assoc']($result))
519
		{
520
			// If they aren't allowed to view this person's profile, skip it.
521
			if (!$allow_view_any && ($user_info['id'] != $row['id_member']))
522
				continue;
523
524
			// Set their action on each - session/text to sprintf.
525
			foreach ($profile_ids[$row['id_member']] as $k => $session_text)
526
				$data[$k] = sprintf($session_text, $row['id_member'], $row['real_name']);
527
		}
528
		$smcFunc['db_free_result']($result);
529
	}
530
531
	call_integration_hook('whos_online_after', array(&$urls, &$data));
532
533
	if (!is_array($urls))
534
		return isset($data[0]) ? $data[0] : false;
535
	else
536
		return $data;
537
}
538
539
/**
540
 * It prepares credit and copyright information for the credits page or the admin page
541
 *
542
 * @param bool $in_admin = false, if parameter is true the it will not load the sub-template nor the template file
543
 */
544
function Credits($in_admin = false)
545
{
546
	global $context, $smcFunc, $forum_copyright, $forum_version, $software_year, $txt, $user_info;
547
548
	// Don't blink. Don't even blink. Blink and you're dead.
549
	loadLanguage('Who');
550
551
	if ($in_admin)
552
	{
553
		$context[$context['admin_menu_name']]['tab_data'] = array(
554
			'title' => $txt['support_credits_title'],
555
			'help' => '',
556
			'description' => '',
557
		);
558
	}
559
560
	$context['credits'] = array(
561
		array(
562
			'pretext' => $txt['credits_intro'],
563
			'title' => $txt['credits_team'],
564
			'groups' => array(
565
				array(
566
					'title' => $txt['credits_groups_pm'],
567
					'members' => array(
568
						'Michele "Illori" Davis',
569
						// Former Project Managers
570
						'Jessica "Suki" Gonz&aacute;lez',
571
						'Kindred',
572
					),
573
				),
574
				array(
575
					'title' => $txt['credits_groups_dev'],
576
					'members' => array(
577
						// Lead Developer
578
						'Colin Schoen',
579
						// Developers
580
						'Jon "Sesquipedalian" Stovell',
581
						'Michael "Oldiesmann" Eshom',
582
583
						// Former Developers
584
						'Aaron van Geffen',
585
						'Antechinus',
586
						'Bjoern "Bloc" Kristiansen',
587
						'Brad "IchBin&trade;" Grow',
588
						'emanuele',
589
						'Hendrik Jan "Compuart" Visser',
590
						'Juan "JayBachatero" Hernandez',
591
						'John "live627" Rayes',
592
						'Jessica "Suki" Gonz&aacute;lez',
593
						'Karl "RegularExpression" Benson',
594
						'Matthew "Labradoodle-360" Kerle',
595
						$user_info['is_admin'] ? 'Matt "Grudge" Wolf': 'Grudge',
596
						'Michael "Thantos" Miller',
597
						'Norv',
598
						'Peter "Arantor" Spicer',
599
						'Selman "[SiNaN]" Eser',
600
						'Shitiz "Dragooon" Garg',
601
						// 'Spuds', // Doesn't want to be listed here
602
						// 'Steven "Fustrate" Hoffman',
603
						'Theodore "Orstio" Hildebrandt',
604
						'Thorsten "TE" Eurich',
605
						'winrules',
606
					),
607
				),
608
				array(
609
					'title' => $txt['credits_groups_support'],
610
					'members' => array(
611
						// Lead Support Specialist
612
						'br360',
613
						// Support Specialists
614
						'Aleksi "Lex" Kilpinen',
615
						'Kindred',
616
						'Steve',
617
						'shawnb',
618
						'ziycon',
619
						// Former Support Specialists
620
						'Adam Tallon',
621
						'Bigguy',
622
						'Bruno "margarett" Alves',
623
						'CapadY',
624
						'ChalkCat',
625
						'Chas Large',
626
						'Duncan85',
627
						'gbsothere',
628
						'JimM',
629
						'Justyne',
630
						'Kat',
631
						'Kevin "greyknight17" Hou',
632
						'Krash',
633
						'Mashby',
634
						'Michael Colin Blaber',
635
						'Michele "Illori" Davis',
636
						'Old Fossil',
637
						'S-Ace',
638
						'Storman&trade;',
639
						'Wade "s&eta;&sigma;&omega;" Poulsen',
640
						'xenovanis',
641
					),
642
				),
643
				array(
644
					'title' => $txt['credits_groups_customize'],
645
					'members' => array(
646
						// Lead Customizer
647
						'Gary M. Gadsdon',
648
						// Customizers
649
						'Gwenwyfar',
650
						'Jessica "Suki" Gonz&aacute;lez',
651
						'NanoSector',
652
						// Former Customizers
653
						'Brannon "B" Hall',
654
						'Diego Andrés',
655
						'Jack "akabugeyes" Thorsen',
656
						'Jason "JBlaze" Clemons',
657
						'Joey "Tyrsson" Smith',
658
						'Kays',
659
						'Ricky.',
660
						'Russell "NEND" Najar',
661
						'SA&#8482;',
662
					),
663
				),
664
				array(
665
					'title' => $txt['credits_groups_docs'],
666
					'members' => array(
667
						// Doc Coordinator
668
						'Irisado',
669
						// Doc Writers
670
671
						// Former Doc Writers
672
						'AngelinaBelle',
673
						'Chainy',
674
						'Graeme Spence',
675
						'Joshua "groundup" Dickerson',
676
					),
677
				),
678
				array(
679
					'title' => $txt['credits_groups_internationalizers'],
680
					'members' => array(
681
						// Lead Localizer
682
						'Nikola "Dzonny" Novakovi&cacute;',
683
						// Localizers
684
						'd3vcho',
685
						'Robert Monden',
686
						// Former Localizers
687
						'Relyana',
688
					),
689
				),
690
				array(
691
					'title' => $txt['credits_groups_marketing'],
692
					'members' => array(
693
						// Marketing Coordinator
694
695
						// Marketing
696
697
						// Former Marketing
698
						'Adish "(F.L.A.M.E.R)" Patel',
699
						'Bryan "Runic" Deakin',
700
						'Marcus "c&sigma;&sigma;&#1082;&iota;&#1108; &#1084;&sigma;&eta;&#1109;&#1090;&#1108;&#1103;" Forsberg',
701
						'Mert "Antes" Al&#305;nbay ',
702
						'Ralph "[n3rve]" Otowo',
703
					),
704
				),
705
				array(
706
					'title' => $txt['credits_groups_site'],
707
					'members' => array(
708
						'Jeremy "SleePy" Darwood',
709
					),
710
				),
711
				array(
712
					'title' => $txt['credits_groups_servers'],
713
					'members' => array(
714
						'Derek Schwab',
715
						'Michael Johnson',
716
						'Liroy "CoreISP" van Hoewijk',
717
					),
718
				),
719
			),
720
		),
721
	);
722
723
	// Give the translators some credit for their hard work.
724
	if (!empty($txt['translation_credits']))
725
		$context['credits'][] = array(
726
			'title' => $txt['credits_groups_translation'],
727
			'groups' => array(
728
				array(
729
					'title' => $txt['credits_groups_translation'],
730
					'members' => $txt['translation_credits'],
731
				),
732
			),
733
		);
734
735
	$context['credits'][] = array(
736
		'title' => $txt['credits_special'],
737
		'posttext' => $txt['credits_anyone'],
738
		'groups' => array(
739
			array(
740
				'title' => $txt['credits_groups_consultants'],
741
				'members' => array(
742
					'albertlast',
743
					'Brett Flannigan',
744
					'Mark Rose',
745
					'Ren&eacute;-Gilles "Nao &#23578;" Deberdt',
746
					'tinoest',
747
				),
748
			),
749
			array(
750
				'title' => $txt['credits_groups_beta'],
751
				'members' => array(
752
					$txt['credits_beta_message'],
753
				),
754
			),
755
			array(
756
				'title' => $txt['credits_groups_translators'],
757
				'members' => array(
758
					$txt['credits_translators_message'],
759
				),
760
			),
761
			array(
762
				'title' => $txt['credits_groups_founder'],
763
				'members' => array(
764
					'Unknown W. "[Unknown]" Brackets',
765
				),
766
			),
767
			array(
768
				'title' => $txt['credits_groups_orignal_pm'],
769
				'members' => array(
770
					'Jeff Lewis',
771
					'Joseph Fung',
772
					'David Recordon',
773
				),
774
			),
775
		),
776
	);
777
778
	// Give credit to any graphic library's, software library's, plugins etc
779
	$context['credits_software_graphics'] = array(
780
		'graphics' => array(
781
			'<a href="http://p.yusukekamiyamane.com/">Fugue Icons</a> | &copy; 2012 Yusuke Kamiyamane | These icons are licensed under a Creative Commons Attribution 3.0 License',
782
			'<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>',
783
		),
784
		'software' => array(
785
			'<a href="https://jquery.org/">JQuery</a> | &copy; John Resig | Licensed under <a href="https://github.com/jquery/jquery/blob/master/LICENSE.txt">The MIT License (MIT)</a>',
786
			'<a href="https://briancherne.github.io/jquery-hoverIntent/">hoverIntent</a> | &copy; Brian Cherne | Licensed under <a href="https://en.wikipedia.org/wiki/MIT_License">The MIT License (MIT)</a>',
787
			'<a href="https://www.sceditor.com/">SCEditor</a> | &copy; Sam Clarke | Licensed under <a href="https://en.wikipedia.org/wiki/MIT_License">The MIT License (MIT)</a>',
788
			'<a href="http://wayfarerweb.com/jquery/plugins/animadrag/">animaDrag</a> | &copy; Abel Mohler | Licensed under <a href="https://en.wikipedia.org/wiki/MIT_License">The MIT License (MIT)</a>',
789
			'<a href="https://github.com/mzubala/jquery-custom-scrollbar">jQuery Custom Scrollbar</a> | &copy; Maciej Zubala | Licensed under <a href="http://en.wikipedia.org/wiki/MIT_License">The MIT License (MIT)</a>',
790
			'<a href="http://slippry.com/">jQuery Responsive Slider</a> | &copy; booncon ROCKETS | Licensed under <a href="http://en.wikipedia.org/wiki/MIT_License">The MIT License (MIT)</a>',
791
			'<a href="https://github.com/ichord/At.js">At.js</a> | &copy; [email protected] | Licensed under <a href="https://github.com/ichord/At.js/blob/master/LICENSE-MIT">The MIT License (MIT)</a>',
792
			'<a href="https://github.com/ttsvetko/HTML5-Desktop-Notifications">HTML5 Desktop Notifications</a> | &copy; Tsvetan Tsvetkov | Licensed under <a href="https://github.com/ttsvetko/HTML5-Desktop-Notifications/blob/master/License.txt">The Apache License Version 2.0</a>',
793
			'<a href="https://github.com/enygma/gauth">GAuth Code Generator/Validator</a> | &copy; Chris Cornutt | Licensed under <a href="https://github.com/enygma/gauth/blob/master/LICENSE">The MIT License (MIT)</a>',
794
			'<a href="https://github.com/enyo/dropzone">Dropzone.js</a> | &copy; Matias Meno | Licensed under <a href="http://en.wikipedia.org/wiki/MIT_License">The MIT License (MIT)</a>',
795
			'<a href="https://github.com/matthiasmullie/minify">Minify</a> | &copy; Matthias Mullie | Licensed under <a href="http://en.wikipedia.org/wiki/MIT_License">The MIT License (MIT)</a>',
796
			'<a href="https://github.com/true/php-punycode">PHP-Punycode</a> | &copy; True B.V. | Licensed under <a href="http://en.wikipedia.org/wiki/MIT_License">The MIT License (MIT)</a>',
797
		),
798
		'fonts' => array(
799
			'<a href="https://fontlibrary.org/en/font/anonymous-pro"> Anonymous Pro</a> | &copy; 2009 | This font is licensed under the SIL Open Font License, Version 1.1',
800
			'<a href="https://fontlibrary.org/en/font/consolamono"> ConsolaMono</a> | &copy; 2012 | This font is licensed under the SIL Open Font License, Version 1.1',
801
			'<a href="https://fontlibrary.org/en/font/phennig"> Phennig</a> | &copy; 2009-2012 | This font is licensed under the SIL Open Font License, Version 1.1',
802
		),
803
	);
804
805
	// Support for mods that use the <credits> tag via the package manager
806
	$context['credits_modifications'] = array();
807
	if (($mods = cache_get_data('mods_credits', 86400)) === null)
0 ignored issues
show
introduced by
The condition $mods = cache_get_data('...edits', 86400) === null is always false.
Loading history...
808
	{
809
		$mods = array();
810
		$request = $smcFunc['db_query']('substring', '
811
			SELECT version, name, credits
812
			FROM {db_prefix}log_packages
813
			WHERE install_state = {int:installed_mods}
814
				AND credits != {string:empty}
815
				AND SUBSTRING(filename, 1, 9) != {string:patch_name}',
816
			array(
817
				'installed_mods' => 1,
818
				'patch_name' => 'smf_patch',
819
				'empty' => '',
820
			)
821
		);
822
823
		while ($row = $smcFunc['db_fetch_assoc']($request))
824
		{
825
			$credit_info = $smcFunc['json_decode']($row['credits'], true);
826
827
			$copyright = empty($credit_info['copyright']) ? '' : $txt['credits_copyright'] . ' &copy; ' . $smcFunc['htmlspecialchars']($credit_info['copyright']);
828
			$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']));
829
			$version = $txt['credits_version'] . ' ' . $row['version'];
830
			$title = (empty($credit_info['title']) ? $row['name'] : $smcFunc['htmlspecialchars']($credit_info['title'])) . ': ' . $version;
831
832
			// build this one out and stash it away
833
			$mod_name = empty($credit_info['url']) ? $title : '<a href="' . $credit_info['url'] . '">' . $title . '</a>';
834
			$mods[] = $mod_name . (!empty($license) ? ' | ' . $license  : '') . (!empty($copyright) ? ' | ' . $copyright  : '');
835
		}
836
		cache_put_data('mods_credits', $mods, 86400);
837
	}
838
	$context['credits_modifications'] = $mods;
839
840
	$context['copyrights'] = array(
841
		'smf' => sprintf($forum_copyright, $forum_version, $software_year),
842
		/* Modification Authors:  You may add a copyright statement to this array for your mods.
843
			Copyright statements should be in the form of a value only without a array key.  I.E.:
844
				'Some Mod by Thantos &copy; 2010',
845
				$txt['some_mod_copyright'],
846
		*/
847
		'mods' => array(
848
		),
849
	);
850
851
	// Support for those that want to use a hook as well
852
	call_integration_hook('integrate_credits');
853
854
	if (!$in_admin)
855
	{
856
		loadTemplate('Who');
857
		$context['sub_template'] = 'credits';
858
		$context['robot_no_index'] = true;
859
		$context['page_title'] = $txt['credits'];
860
	}
861
}
862
863
?>