online::main()   F
last analyzed

Complexity

Conditions 53
Paths > 20000

Duplication

Lines 0
Ratio 0 %

Size

Total Lines 232
Code Lines 126

Importance

Changes 0
Metric Value
dl 0
loc 232
rs 2
c 0
b 0
f 0
cc 53
eloc 126
nc 80096
nop 1

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
* This file is part of the VinaBB.vn package.
4
*
5
* @copyright (c) VinaBB <vinabb.vn>
6
* @license GNU General Public License, version 2 (GPL-2.0)
7
*/
8
9
namespace vinabb\web\controllers\user;
10
11
use vinabb\web\includes\constants;
12
13
/**
14
* 'Who is online' page
15
*/
16
class online implements online_interface
17
{
18
	/** @var \phpbb\auth\auth */
19
	protected $auth;
20
21
	/** @var \phpbb\cache\service */
22
	protected $cache;
23
24
	/** @var \phpbb\config\config */
25
	protected $config;
26
27
	/** @var \phpbb\db\driver\driver_interface */
28
	protected $db;
29
30
	/** @var \phpbb\language\language */
31
	protected $language;
32
33
	/** @var \phpbb\pagination */
34
	protected $pagination;
35
36
	/** @var \phpbb\request\request */
37
	protected $request;
38
39
	/** @var \phpbb\template\template */
40
	protected $template;
41
42
	/** @var \phpbb\user */
43
	protected $user;
44
45
	/** @var \phpbb\controller\helper */
46
	protected $helper;
47
48
	/** @var \vinabb\web\controllers\helper\helper_interface */
49
	protected $ext_helper;
50
51
	/** @var string */
52
	protected $root_path;
53
54
	/** @var string */
55
	protected $admin_path;
56
57
	/** @var string */
58
	protected $php_ext;
59
60
	/** @var array $forum_data */
61
	protected $forum_data;
62
63
	/**
64
	* Constructor
65
	*
66
	* @param \phpbb\auth\auth $auth
67
	* @param \phpbb\cache\service $cache
68
	* @param \phpbb\config\config $config
69
	* @param \phpbb\db\driver\driver_interface $db
70
	* @param \phpbb\language\language $language
71
	* @param \phpbb\pagination $pagination
72
	* @param \phpbb\request\request $request
73
	* @param \phpbb\template\template $template
74
	* @param \phpbb\user $user
75
	* @param \phpbb\controller\helper $helper
76
	* @param \vinabb\web\controllers\helper\helper_interface $ext_helper
77
	* @param string $root_path
78
	* @param string $admin_path
79
	* @param string $php_ext
80
	*/
81
	public function __construct(
82
		\phpbb\auth\auth $auth,
83
		\phpbb\cache\service $cache,
84
		\phpbb\config\config $config,
85
		\phpbb\db\driver\driver_interface $db,
86
		\phpbb\language\language $language,
87
		\phpbb\pagination $pagination,
88
		\phpbb\request\request $request,
89
		\phpbb\template\template $template,
90
		\phpbb\user $user,
91
		\phpbb\controller\helper $helper,
92
		\vinabb\web\controllers\helper\helper_interface $ext_helper,
93
		$root_path,
94
		$admin_path,
95
		$php_ext
96
	)
97
	{
98
		$this->auth = $auth;
99
		$this->cache = $cache;
100
		$this->config = $config;
101
		$this->db = $db;
102
		$this->language = $language;
103
		$this->pagination = $pagination;
104
		$this->request = $request;
105
		$this->template = $template;
106
		$this->user = $user;
107
		$this->helper = $helper;
108
		$this->ext_helper = $ext_helper;
109
		$this->root_path = $root_path;
110
		$this->admin_path = $admin_path;
111
		$this->php_ext = $php_ext;
112
113
		$this->forum_data = $this->cache->get_forum_data();
114
	}
115
116
	/**
117
	* Main method
118
	*
119
	* @param $mode View mode
120
	* @return \Symfony\Component\HttpFoundation\Response
121
	*/
122
	public function main($mode)
123
	{
124
		// Language
125
		$this->language->add_lang('memberlist');
126
127
		// Get and set some variables
128
		$session_id = $this->request->variable('s', '');
129
		$start = $this->request->variable('start', 0);
130
		$sort_key = $this->request->variable('sk', 'b');
131
		$sort_dir = $this->request->variable('sd', 'd');
132
		$show_guests = ($this->config['load_online_guests']) ? $this->request->variable('sg', 0) : 0;
133
134
		// Can this user view profiles/memberlist?
135
		$this->require_login();
136
137
		$sort_key_text = [
138
			'a' => $this->language->lang('SORT_USERNAME'),
139
			'b' => $this->language->lang('SORT_JOINED'),
140
			'c' => $this->language->lang('SORT_LOCATION')
141
		];
142
143
		$sort_key_sql = [
144
			'a' => 'u.username_clean',
145
			'b' => 's.session_time',
146
			'c' => 's.session_page'
147
		];
148
149
		// Sorting and order
150
		if (!isset($sort_key_text[$sort_key]))
151
		{
152
			$sort_key = 'b';
153
		}
154
155
		$order_by = $sort_key_sql[$sort_key] . ' ' . (($sort_dir == 'a') ? 'ASC' : 'DESC');
156
157
		$this->user->update_session_infos();
158
159
		// Get number of online guests (if we do not display them)
160
		$guest_counter = 0;
161
162
		if (!$show_guests)
163
		{
164
			$guest_counter = $this->get_guest_counter();
165
		}
166
167
		// Get user list
168
		$sql_ary = [
169
			'SELECT'	=> 'u.user_id, u.username, u.username_clean, u.user_type, u.user_colour, s.session_id, s.session_time, s.session_page, s.session_ip, s.session_browser, s.session_viewonline, s.session_forum_id',
170
			'FROM'		=> [
171
				USERS_TABLE		=> 'u',
172
				SESSIONS_TABLE	=> 's'
173
			],
174
			'WHERE'		=> 'u.user_id = s.session_user_id
175
				AND s.session_time >= ' . (time() - ($this->config['load_online_time'] * 60)) .
176
				((!$show_guests) ? ' AND s.session_user_id <> ' . ANONYMOUS : ''),
177
			'ORDER_BY'	=> $order_by
178
		];
179
		$result = $this->db->sql_query($this->db->sql_build_query('SELECT', $sql_ary));
180
181
		$prev_id = $prev_ip = [];
182
		$logged_visible_online = $logged_hidden_online = $counter = 0;
183
184
		while ($row = $this->db->sql_fetchrow($result))
185
		{
186
			if ($row['user_id'] != ANONYMOUS && !isset($prev_id[$row['user_id']]))
187
			{
188
				$s_user_hidden = false;
189
				$user_colour = ($row['user_colour']) ? ' style="color: #' . $row['user_colour'] . '" class="username-coloured"' : '';
190
191
				$username_full = ($row['user_type'] != USER_IGNORE) ? get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']) : '<span' . $user_colour . '>' . $row['username'] . '</span>';
192
193
				if (!$row['session_viewonline'])
194
				{
195
					$view_online = ($this->auth->acl_get('u_viewonline') || $row['user_id'] === $this->user->data['user_id']) ? true : false;
196
					$logged_hidden_online++;
197
198
					$username_full = '<em>' . $username_full . '</em>';
199
					$s_user_hidden = true;
200
				}
201
				else
202
				{
203
					$view_online = true;
204
					$logged_visible_online++;
205
				}
206
207
				$prev_id[$row['user_id']] = 1;
208
209
				if ($view_online)
210
				{
211
					$counter++;
212
				}
213
214
				if (!$view_online || $counter > $start + $this->config['topics_per_page'] || $counter <= $start)
215
				{
216
					continue;
217
				}
218
			}
219
			else if ($show_guests && $row['user_id'] == ANONYMOUS && !isset($prev_ip[$row['session_ip']]))
220
			{
221
				$prev_ip[$row['session_ip']] = 1;
222
				$guest_counter++;
223
				$counter++;
224
225
				if ($counter > $start + $this->config['topics_per_page'] || $counter <= $start)
226
				{
227
					continue;
228
				}
229
230
				$s_user_hidden = false;
231
				$username_full = get_username_string('full', $row['user_id'], $this->user->lang['GUEST']);
232
			}
233
			else
234
			{
235
				continue;
236
			}
237
238
			// What are they viewing?
239
			$location = $location_url = '';
240
241
			// First, try to detect from the basic list
242
			foreach ($this->get_on_page_data() as $page_str => $page_data)
243
			{
244
				if (strpos($row['session_page'], $page_str) !== false)
245
				{
246
					$location = $page_data['lang'];
247
					$location_url = isset($page_data['url']) ? $page_data['url'] : append_sid("{$this->root_path}index.{$this->php_ext}");
248
				}
249
			}
250
251
			// Then, with more URL parameters than...
252
			if (empty($location_url))
253
			{
254
				if (strpos($row['session_page'], "app.{$this->php_ext}/board/forum") !== false || strpos($row['session_page'], "app.{$this->php_ext}/board/topic") !== false || strpos($row['session_page'], "app.{$this->php_ext}/posting") !== false)
255
				{
256
					$forum_id = $row['session_forum_id'];
257
258
					if ($forum_id && $this->auth->acl_get('f_list', $forum_id))
259
					{
260
						$location_url = $this->helper->route('vinabb_web_board_forum_route', ['forum_id' => $forum_id, 'seo' => $this->forum_data[$forum_id]['forum_name_seo'] . constants::REWRITE_URL_SEO]);
261
262
						if ($this->forum_data[$forum_id]['forum_type'] == FORUM_LINK)
263
						{
264
							$location = $this->language->lang('READING_LINK', $this->forum_data[$forum_id]['forum_name']);
265
						}
266
						else if (strpos($row['session_page'], "app.{$this->php_ext}/board/forum") !== false)
267
						{
268
							$location = $this->language->lang('READING_FORUM', $this->forum_data[$forum_id]['forum_name']);
269
						}
270
						else if (strpos($row['session_page'], "app.{$this->php_ext}/board/topic") !== false)
271
						{
272
							$location = $this->language->lang('READING_TOPIC', $this->forum_data[$forum_id]['forum_name']);
273
						}
274
						else if (strpos($row['session_page'], "app.{$this->php_ext}/posting") !== false)
275
						{
276
							if (strpos($row['session_page'], "app.{$this->php_ext}/posting/reply") !== false || strpos($row['session_page'], "app.{$this->php_ext}/posting/quote") !== false)
277
							{
278
								$location = $this->language->lang('REPLYING_MESSAGE', $this->forum_data[$forum_id]['forum_name']);
279
							}
280
							else
281
							{
282
								$location = $this->language->lang('POSTING_MESSAGE', $this->forum_data[$forum_id]['forum_name']);
283
							}
284
						}
285
286
						if (empty($location))
287
						{
288
							$location = $this->language->lang('BOARD');
289
						}
290
					}
291
					else
292
					{
293
						$location = $this->language->lang('INDEX');
294
						$location_url = append_sid("{$this->root_path}index.{$this->php_ext}");
295
					}
296
				}
297
				else
298
				{
299
					$location = $this->language->lang('INDEX');
300
					$location_url = append_sid("{$this->root_path}index.{$this->php_ext}");
301
				}
302
			}
303
304
			$this->template->assign_block_vars('user_row', [
305
				'USERNAME' 			=> $row['username'],
306
				'USERNAME_COLOUR'	=> $row['user_colour'],
307
				'USERNAME_FULL'		=> $username_full,
308
				'LASTUPDATE'		=> $this->user->format_date($row['session_time']),
309
				'FORUM_LOCATION'	=> $location,
310
				'USER_IP'			=> ($this->auth->acl_get('a_')) ? (($mode == 'lookup' && $session_id == $row['session_id']) ? gethostbyaddr($row['session_ip']) : $row['session_ip']) : '',
311
				'USER_BROWSER'		=> ($this->auth->acl_get('a_user')) ? $row['session_browser'] : '',
312
313
				'U_USER_PROFILE'	=> ($row['user_type'] != USER_IGNORE) ? get_username_string('profile', $row['user_id'], '') : '',
314
				'U_USER_IP'			=> ($mode != 'lookup' || $row['session_id'] != $session_id) ? $this->helper->route('vinabb_web_user_online_route', ['mode' => 'lookup', 's' => $row['session_id'], 'sg' => $show_guests, 'start' => $start, 'sk' => $sort_key, 'sd' => $sort_dir]) : $this->helper->route('vinabb_web_user_online_route', ['mode' => 'lookup', 'sg' => $show_guests, 'start' => $start, 'sk' => $sort_key, 'sd' => $sort_dir]),
315
				'U_WHOIS'			=> $this->helper->route('vinabb_web_user_whois_route', ['session_id' => $row['session_id']]),
316
				'U_FORUM_LOCATION'	=> $location_url,
317
318
				'S_USER_HIDDEN'		=> $s_user_hidden,
319
				'S_GUEST'			=> $row['user_id'] == ANONYMOUS,
320
				'S_USER_TYPE'		=> $row['user_type']
321
			]);
322
		}
323
		$this->db->sql_freeresult($result);
324
		unset($prev_id, $prev_ip);
325
326
		// Refreshing the page every 60 seconds...
327
		meta_refresh(60, $this->helper->route('vinabb_web_user_online_route', ['sg' => $show_guests, 'sk' => $sort_key, 'sd' => $sort_dir, 'start' => $start]));
328
329
		$start = $this->pagination->validate_start($start, $this->config['topics_per_page'], $counter);
330
		$base_url = $this->helper->route('vinabb_web_user_online_route', ['sg' => $show_guests, 'sk' => $sort_key, 'sd' => $sort_dir]);
331
		$this->pagination->generate_template_pagination($base_url, 'pagination', 'start', $counter, $this->config['topics_per_page'], $start);
332
333
		// Send data to template
334
		$this->template->assign_vars([
335
			'TOTAL_REGISTERED_USERS_ONLINE'	=> $this->language->lang('REG_USERS_ONLINE', (int) $logged_visible_online, $this->language->lang('HIDDEN_USERS_ONLINE', (int) $logged_hidden_online)),
336
			'TOTAL_GUEST_USERS_ONLINE'		=> $this->language->lang('GUEST_USERS_ONLINE', (int) $guest_counter),
337
			'LEGEND'						=> $this->ext_helper->get_group_legend(),
338
339
			'U_SORT_USERNAME'	=> $this->helper->route('vinabb_web_user_online_route', ['sk' => 'a', 'sd' => (($sort_key == 'a' && $sort_dir == 'a') ? 'd' : 'a'), 'sg' => ((int) $show_guests)]),
340
			'U_SORT_UPDATED'	=> $this->helper->route('vinabb_web_user_online_route', ['sk' => 'b', 'sd' => (($sort_key == 'b' && $sort_dir == 'a') ? 'd' : 'a'), 'sg' => ((int) $show_guests)]),
341
			'U_SORT_LOCATION'	=> $this->helper->route('vinabb_web_user_online_route', ['sk' => 'c', 'sd' => (($sort_key == 'c' && $sort_dir == 'a') ? 'd' : 'a'), 'sg' => ((int) $show_guests)]),
342
343
			'U_SWITCH_GUEST_DISPLAY'	=> $this->helper->route('vinabb_web_user_online_route', ['sg' => ((int) !$show_guests)]),
344
			'L_SWITCH_GUEST_DISPLAY'	=> $this->language->lang(($show_guests) ? 'HIDE_GUESTS' : 'DISPLAY_GUESTS'),
345
			'S_SWITCH_GUEST_DISPLAY'	=> $this->config['load_online_guests'],
346
			'S_VIEWONLINE'				=> true
347
		]);
348
349
		// We do not need to load the who is online box here. ;)
350
		$this->config['load_online'] = false;
351
352
		return $this->helper->render('viewonline_body.html', $this->language->lang('WHO_IS_ONLINE'));
353
	}
354
355
	/**
356
	* Requires guests to login to view the online list
357
	*/
358
	protected function require_login()
359
	{
360
		if (!$this->auth->acl_gets('u_viewprofile', 'a_user', 'a_useradd', 'a_userdel'))
361
		{
362
			if ($this->user->data['user_id'] != ANONYMOUS)
363
			{
364
				send_status_line(403, 'Forbidden');
365
				trigger_error('NO_VIEW_USERS');
366
			}
367
368
			login_box('', $this->language->lang('LOGIN_EXPLAIN_VIEWONLINE'));
369
		}
370
	}
371
372
	/**
373
	* List of our pages and their URLs
374
	*
375
	* @return array
376
	*/
377
	protected function get_on_page_data()
378
	{
379
		return [
380
			"index.{$this->php_ext}"					=> ['lang' => $this->language->lang('INDEX'), 'url' => append_sid("{$this->root_path}index.{$this->php_ext}")],
381
			"{$this->admin_path}index.{$this->php_ext}"	=> ['lang' => $this->language->lang('ACP')],
382
			"search.{$this->php_ext}"					=> ['lang' => $this->language->lang('SEARCHING_FORUMS'), 'url' => append_sid("{$this->root_path}search.{$this->php_ext}")],
383
			"app.{$this->php_ext}/user/online"			=> ['lang' => $this->language->lang('VIEWING_ONLINE'), 'url' => $this->helper->route('vinabb_web_user_online_route')],
384
			"app.{$this->php_ext}/user/list"			=> ['lang' => $this->language->lang('VIEWING_MEMBERS'), 'url' => $this->helper->route('vinabb_web_user_list_route')],
385
			"app.{$this->php_ext}/user/profile"			=> ['lang' => $this->language->lang('VIEWING_MEMBER_PROFILE'), 'url' => $this->helper->route('vinabb_web_user_list_route')],
386
			"app.{$this->php_ext}/user/contact"			=> ['lang' => $this->language->lang('VIEWING_CONTACT_ADMIN'), 'url' => $this->helper->route('vinabb_web_user_contact_route')],
387
			"app.{$this->php_ext}/mcp"					=> ['lang' => $this->language->lang('VIEWING_MCP')],
388
			"app.{$this->php_ext}/ucp/front/register"	=> ['lang' => $this->language->lang('VIEWING_REGISTER')],
389
			"app.{$this->php_ext}/ucp/pm/compose"		=> ['lang' => $this->language->lang('POSTING_PRIVATE_MESSAGE')],
390
			"app.{$this->php_ext}/ucp/pm"				=> ['lang' => $this->language->lang('VIEWING_PRIVATE_MESSAGES')],
391
			"app.{$this->php_ext}/ucp/profile"			=> ['lang' => $this->language->lang('CHANGING_PROFILE')],
392
			"app.{$this->php_ext}/ucp/prefs"			=> ['lang' => $this->language->lang('CHANGING_PREFERENCES')],
393
			"app.{$this->php_ext}/ucp"					=> ['lang' => $this->language->lang('VIEWING_UCP')],
394
			"app.{$this->php_ext}/attachment"			=> ['lang' => $this->language->lang('DOWNLOADING_FILE')],
395
			"app.{$this->php_ext}/post/"				=> ['lang' => $this->language->lang('REPORTING_POST')],
396
			"app.{$this->php_ext}/help/"				=> ['lang' => $this->language->lang('VIEWING_FAQ'), 'url' => $this->helper->route('phpbb_help_faq_controller')]
397
		];
398
	}
399
400
	/**
401
	* Get number of online guests
402
	*
403
	* @return int
404
	*/
405
	public function get_guest_counter()
406
	{
407
		switch ($this->db->get_sql_layer())
408
		{
409
			case 'sqlite3':
410
				$sql = 'SELECT COUNT(session_ip) AS num_guests
411
					FROM (
412
						SELECT DISTINCT session_ip
413
							FROM ' . SESSIONS_TABLE . '
414
							WHERE session_user_id = ' . ANONYMOUS . '
415
								AND session_time >= ' . (time() - ($this->config['load_online_time'] * 60)) .
416
					')';
417
			break;
418
419
			default:
420
				$sql = 'SELECT COUNT(DISTINCT session_ip) AS num_guests
421
					FROM ' . SESSIONS_TABLE . '
422
					WHERE session_user_id = ' . ANONYMOUS . '
423
						AND session_time >= ' . (time() - ($this->config['load_online_time'] * 60));
424
			break;
425
		}
426
427
		$result = $this->db->sql_query($sql);
428
		$guest_counter = (int) $this->db->sql_fetchfield('num_guests');
429
		$this->db->sql_freeresult($result);
430
431
		return $guest_counter;
432
	}
433
}
434