Completed
Push — master ( a93112...75382e )
by Daniel
16:13
created

featured_member::_display_user()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 27
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 27
ccs 0
cts 16
cp 0
rs 8.8571
cc 2
eloc 19
nc 2
nop 1
crap 6
1
<?php
2
/**
3
 *
4
 * @package sitemaker
5
 * @copyright (c) 2013 Daniel A. (blitze)
6
 * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
7
 *
8
 */
9
10
namespace blitze\sitemaker\blocks;
11
12
use blitze\sitemaker\services\blocks\driver\block;
13
use phpbb\cache\driver\driver_interface as cache;
14
use phpbb\config\config;
15
use phpbb\db\driver\driver_interface as database;
16
use phpbb\profilefields\manager as profile_fields;
17
use phpbb\user;
18
19
/**
20
 * Featured Member Block
21
 */
22
class featured_member extends block
23
{
24
	/** @var cache */
25
	protected $cache;
26
27
	/** @var config */
28
	protected $config;
29
30
	/** @var database */
31
	protected $db;
32
33
	/** @var profile_fields */
34
	protected $profile_fields;
35
36
	/** @var user */
37
	protected $user;
38
39
	/** @var string */
40
	protected $phpbb_root_path;
41
42
	/** @var string */
43
	protected $php_ext;
44
45
	/** @var string */
46
	protected $blocks_table;
47
48
	/** @var int */
49
	protected $cache_time;
50
51
	/** @var array */
52
	private $settings;
53
54
	/** @var array */
55
	private static $rotations = array(
56
		'hourly'	=> 'hour',
57
		'daily'		=> 'day',
58
		'weekly'	=> 'week',
59
		'monthly'	=> 'month'
60
	);
61
62
	/**
63
	 * Constructor
64
	 *
65
	 * @param cache				$cache					Cache driver interface
66
	 * @param config			$config					Config object
67
	 * @param database			$db	 					Database connection
68
	 * @param profile_fields	$profile_fields			Profile fields manager object
69
	 * @param user				$user					User object
70
	 * @param string			$phpbb_root_path		Path to the phpbb includes directory.
71
	 * @param string			$php_ext				php file extension
72
	 * @param string			$blocks_table			Name of blocks database table
73
	 * @param int				$cache_time
74
	 */
75
	public function __construct(cache $cache, config $config, database $db, profile_fields $profile_fields, user $user, $phpbb_root_path, $php_ext, $blocks_table, $cache_time = 3600)
76
	{
77
		$this->cache = $cache;
78
		$this->config = $config;
79
		$this->db = $db;
80
		$this->profile_fields = $profile_fields;
81
		$this->user = $user;
82
		$this->phpbb_root_path = $phpbb_root_path;
83
		$this->php_ext = $php_ext;
84
		$this->blocks_table = $blocks_table;
85
		$this->cache_time = $cache_time;
86
87
		if (!function_exists('phpbb_show_profile'))
88
		{
89
			include($this->phpbb_root_path . 'includes/functions_display.' . $this->php_ext);
90
		}
91
	}
92
93
	/**
94
	 * {@inheritdoc}
95
	 */
96
	public function get_config(array $settings)
97
	{
98
		$rotation_options = $this->_get_rotation_frequencies();
99
		$qtype_options = $this->_get_query_types();
100
		$cpf_options = $this->_get_cpf_fields();
101
102
		return array(
103
			'legend1'		=> 'SETTINGS',
104
			'qtype'			=> array('lang' => 'QUERY_TYPE', 'validate' => 'string', 'type' => 'select', 'options' => $qtype_options, 'default' => 'recent', 'explain' => false),
105
			'rotation'		=> array('lang' => 'FREQUENCY', 'validate' => 'string', 'type' => 'select', 'options' => $rotation_options, 'default' => 'daily', 'explain' => false),
106
			'userlist'		=> array('lang' => 'FEATURED_MEMBER_IDS', 'validate' => 'string', 'type' => 'textarea:3:40', 'default' => '', 'explain' => true),
107
108
			'legend2'		=> 'CUSTOM_PROFILE_FIELDS',
109
			'show_cpf'		=> array('lang' => 'SELECT_PROFILE_FIELDS', 'validate' => 'string', 'type' => 'checkbox', 'options' => $cpf_options, 'default' => array(), 'explain' => true),
110
			'last_changed'	=> array('type' => 'hidden', 'default' => 0),
111
			'current_user'	=> array('type' => 'hidden', 'default' => 0),
112
		);
113
	}
114
115
	/**
116
	 * {@inheritdoc}
117
	 */
118
	public function display(array $bdata, $edit_mode = false)
119
	{
120
		$this->settings = $this->_get_settings($bdata);
121
122
		$change_user = $this->_change_user();
123
		$block_title = $this->user->lang(strtoupper($this->settings['qtype']) . '_MEMBER');
124
125
		if (($row = $this->_get_user_data($change_user)) === false)
126
		{
127
			return $this->_update_userlist($block_title, $bdata, $edit_mode);
128
		}
129
130
		$this->_save_settings($bdata['bid'], $change_user);
131
		$this->_explain_view();
132
		$this->ptemplate->assign_vars($this->_display_user($row));
133
134
		return array(
135
			'title'		=> $block_title,
136
			'content'	=> $this->ptemplate->render_view('blitze/sitemaker', 'blocks/featured_member.html', 'featured_member_block'),
137
		);
138
	}
139
140
	/**
141
	 * @param bool $change_user
142
	 * @return array|false
143
	 */
144
	private function _get_user_data($change_user)
145
	{
146
		$sql = 'SELECT user_id, username, user_colour, user_avatar, user_avatar_type, user_avatar_height, user_avatar_width, user_regdate, user_lastvisit, user_birthday, user_posts, user_rank
147
			FROM ' . USERS_TABLE . '
148
			WHERE ' . $this->db->sql_in_set('user_type', array(USER_NORMAL, USER_FOUNDER));
149
150
		$method = '_query_user_by_' . $this->settings['qtype'];
151
152
		if (is_callable(array($this, $method)))
153
		{
154
			call_user_func_array(array($this, $method), array(&$sql, $change_user));
155
		}
156
		else
157
		{
158
			$sql .= 'ORDER BY RAND()';
159
		}
160
161
		$result = $this->db->sql_query_limit($sql, 1, 0, $this->_get_cache_time($this->settings['qtype'], $this->settings['rotation']));
162
		$row = $this->db->sql_fetchrow($result);
163
		$this->db->sql_freeresult($result);
164
165
		return $row;
166
	}
167
168
	/**
169
	 * @param string $sql
170
	 * @param bool $change_user
171
	 */
172
	private function _query_user_by_featured(&$sql, $change_user)
173
	{
174
		$userlist = $this->_get_userlist($this->settings['userlist']);
175
		$current_user = (sizeof($userlist)) ? $this->_get_featured_user($userlist, $change_user) : 0;
176
177
		$sql .= ' AND user_id = ' . (int) $current_user;
178
	}
179
180
	/**
181
	 * @param string $sql
182
	 */
183
	private function _query_user_by_recent(&$sql)
184
	{
185
		$sql .= ' AND user_posts > 0 ORDER BY user_regdate DESC';
186
	}
187
188
	/**
189
	 * @param string $sql
190
	 */
191
	private function _query_user_by_posts(&$sql)
192
	{
193
		$sql .= ' AND user_posts > 0 ORDER BY user_posts DESC';
194
	}
195
196
	/**
197
	 * @param string $query_type
198
	 * @param string $rotation
199
	 * @return int
200
	 */
201
	private function _get_cache_time($query_type, $rotation)
202
	{
203
		return ($rotation !== 'pageload' || in_array($query_type, array('posts', 'recent'))) ? $this->cache_time : 0;
204
	}
205
206
	/**
207
	 * @return bool
208
	 */
209
	private function _change_user()
210
	{
211
		if ($this->settings['rotation'] == 'pageload' || $this->settings['last_changed'] < strtotime('-1 ' . self::$rotations[$this->settings['rotation']]))
212
		{
213
			$this->settings['last_changed'] = time();
214
			return true;
215
		}
216
		else
217
		{
218
			return false;
219
		}
220
	}
221
222
	/**
223
	 * @param array $userlist
224
	 * @param $change_user
225
	 * @return int
226
	 */
227
	private function _get_featured_user(array $userlist, $change_user)
228
	{
229
		$current_user = $this->settings['current_user'];
230
231
		if ($change_user && sizeof($userlist))
232
		{
233
			$current_user = $this->_get_next_user($current_user, $userlist);
234
235
			$this->settings['current_user'] = $current_user;
236
		}
237
238
		return $current_user;
239
	}
240
241
	/**
242
	 * @param $current_user
243
	 * @param $userlist
244
	 * @return int
245
	 */
246
	private function _get_next_user($current_user, array $userlist)
247
	{
248
		$key = 0;
249
		if ($current_user)
250
		{
251
			$key = $this->_get_next_key($current_user, $userlist);
252
		}
253
254
		return $userlist[$key];
255
	}
256
257
	/**
258
	 * @param $current_user
259
	 * @param $userlist
260
	 * @return int
261
	 */
262
	private function _get_next_key($current_user, array $userlist)
263
	{
264
		$end_key = sizeof($userlist) - 1;
265
		$curr_key = (int) array_search($current_user, $userlist);
266
267
		return ($curr_key >= 0 && $curr_key < $end_key) ? ($curr_key + 1) : 0;
268
	}
269
270
	/**
271
	 */
272
	private function _explain_view()
273
	{
274
		$query_type = $this->settings['qtype'];
275
		$rotation = $this->settings['rotation'];
276
277
		$this->ptemplate->assign_vars(array(
278
			'QTYPE_EXPLAIN'		=> ($query_type == 'posts' || $query_type == 'recent') ? $this->user->lang('QTYPE_' . strtoupper($query_type)) : '',
279
			'TITLE_EXPLAIN'		=> ($rotation != 'pageload') ? $this->user->lang(strtoupper($rotation) . '_MEMBER') : '',
280
		));
281
	}
282
283
	/**
284
	 * @param array $bdata
285
	 * @return array
286
	 */
287
	private function _get_settings(array $bdata)
288
	{
289
		$cached_settings = $this->cache->get('pt_block_data_' . $bdata['bid']);
290
		$settings = ($cached_settings && $cached_settings['hash'] === $bdata['hash']) ? $cached_settings : $bdata['settings'];
291
		$settings['hash'] = $bdata['hash'];
292
293
		return $settings;
294
	}
295
296
	/**
297
	 * @param $bid
298
	 * @param bool $change_user
299
	 */
300
	private function _save_settings($bid, $change_user)
301
	{
302
		if ($change_user && ($this->settings['rotation'] !== 'pageload' || $this->settings['qtype'] === 'featured'))
303
		{
304
			$settings = $this->settings;
305
			unset($settings['hash']);
306
			$sql_data = array(
307
				'settings'	=> serialize($settings)
308
			);
309
			$this->db->sql_query('UPDATE ' . $this->blocks_table . ' SET ' . $this->db->sql_build_array('UPDATE', $sql_data) . ' WHERE bid = ' . (int) $bid);
310
			$this->cache->put('pt_block_data_' . $bid, $this->settings);
311
		}
312
	}
313
314
	/**
315
	 * @param string $list
316
	 * @return array
317
	 */
318
	private function _get_userlist($list)
319
	{
320
		$userlist = preg_replace("/\s*,?\s*(\r\n|\n\r|\n|\r)+\s*/", "\n", trim($list));
321
		return array_map('intval', array_filter(explode(',', $userlist)));
322
	}
323
324
	/**
325
	 * if we're selecting from a list and there is no result, we remove the culprit and update the list
326
	 *
327
	 * @param string $title
328
	 * @param array $bdata
329
	 * @param bool $edit_mode
330
	 * @return array
331
	 */
332
	private function _update_userlist($title, array $bdata, $edit_mode)
333
	{
334
		$userlist = $this->_get_userlist($bdata['settings']['userlist']);
335
336
		if ($this->settings['qtype'] === 'featured' && sizeof($userlist))
337
		{
338
			$curr_key = (int) array_search($this->settings['current_user'], $userlist);
339
340
			// Remove the invalid user from the list
341
			$new_list = str_replace($this->settings['current_user'] . ',', '', $this->settings['userlist'] . ',');
342
			$new_list = trim($new_list, ',');
343
344
			$new_userlist = $this->_get_userlist($new_list);
345
			$current_user =& $new_userlist[$curr_key - 1];
346
347
			$this->settings['current_user'] = (int) $current_user;
348
			$this->settings['userlist'] = $new_list;
349
			$this->settings['last_changed'] = 0;
350
351
			$bdata['settings'] = $this->settings;
352
			$bdata['hash'] = 0;
353
354
			return $this->display($bdata, $edit_mode);
355
		}
356
357
		return array(
358
			'title' => $title,
359
		);
360
	}
361
362
	/**
363
	 * @param $user_id
364
	 * @return array|string
365
	 */
366
	private function _get_profile_fields($user_id)
367
	{
368
		$fields = '';
369
		if (sizeof($this->settings['show_cpf']))
370
		{
371
			$fields = $this->profile_fields->grab_profile_fields_data($user_id);
372
373
			if (sizeof($fields))
374
			{
375
				$fields = array_intersect_key(array_shift($fields), array_flip($this->settings['show_cpf']));
376
			}
377
		}
378
379
		return $fields;
380
	}
381
382
	/**
383
	 * @param int $user_id
384
	 */
385
	private function _show_profile_fields($user_id)
386
	{
387
		if ($profile_fields = $this->_get_profile_fields($user_id))
388
		{
389
			$cp_row = $this->profile_fields->generate_profile_fields_template_data($profile_fields);
390
391
			$this->ptemplate->assign_vars($cp_row['row']);
392
393
			foreach ($cp_row['blockrow'] as $field_data)
394
			{
395
				$this->ptemplate->assign_block_vars('custom_fields', $field_data);
396
			}
397
		}
398
	}
399
400
	/**
401
	 * @param array $row
402
	 * @return array
403
	 */
404
	private function _display_user(array $row)
405
	{
406
		if (!$row)
0 ignored issues
show
Bug Best Practice introduced by
The expression $row of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
407
		{
408
			return array();
409
		}
410
411
		$username = get_username_string('username', $row['user_id'], $row['username'], $row['user_colour']);
412
		$date_format = $this->user->lang('DATE_FORMAT');
413
		$rank = phpbb_get_user_rank($row, $row['user_posts']);
414
415
		$this->_show_profile_fields($row['user_id']);
416
417
		return array(
418
			'USERNAME'			=> $username,
419
			'AVATAR_IMG'		=> phpbb_get_user_avatar($row),
420
			'POSTS_PCT'			=> sprintf($this->user->lang('POST_PCT'), $this->_calculate_percent_posts($row['user_posts'])),
421
			'L_VIEW_PROFILE'	=> sprintf($this->user->lang('VIEW_USER_PROFILE'), $username),
422
			'JOINED'			=> $this->user->format_date($row['user_regdate'], "|$date_format|"),
423
			'VISITED'			=> $this->_get_last_visit_date($row['user_lastvisit'], $date_format),
424
			'POSTS'				=> $row['user_posts'],
425
			'RANK_TITLE'		=> $rank['title'],
426
			'RANK_IMG'			=> $rank['img'],
427
			'U_PROFILE'			=> get_username_string('profile', $row['user_id'], $row['username'], $row['user_colour']),
428
			'U_SEARCH_USER'		=> append_sid($this->phpbb_root_path . 'search.' . $this->php_ext, "author_id={$row['user_id']}&amp;sr=posts"),
429
		);
430
	}
431
432
	/**
433
	 * @param $user_posts
434
	 * @return int|mixed
435
	 */
436
	private function _calculate_percent_posts($user_posts)
437
	{
438
		return ($this->config['num_posts']) ? min(100, ($user_posts / $this->config['num_posts']) * 100) : 0;
439
	}
440
441
	/**
442
	 * @param int $last_visited
443
	 * @param string $date_format
444
	 * @return string
445
	 */
446
	private function _get_last_visit_date($last_visited, $date_format)
447
	{
448
		return ($last_visited) ? $this->user->format_date($last_visited, "|$date_format|") : '';
449
	}
450
451
	/**
452
	 * @return array
453
	 */
454
	private function _get_rotation_frequencies()
455
	{
456
		return array(
457
			'pageload'	=> 'ROTATE_PAGELOAD',
458
			'hourly'	=> 'ROTATE_HOURLY',
459
			'daily'		=> 'ROTATE_DAILY',
460
			'weekly'	=> 'ROTATE_WEEKLY',
461
			'monthly'	=> 'ROTATE_MONTHLY',
462
		);
463
	}
464
465
	/**
466
	 * @return array
467
	 */
468
	private function _get_query_types()
469
	{
470
		return array(
471
			'random'	=> 'RANDOM_MEMBER',
472
			'recent'	=> 'RECENT_MEMBER',
473
			'posts'		=> 'POSTS_MEMBER',
474
			'featured'	=> 'FEATURED_MEMBER',
475
		);
476
	}
477
478
	/**
479
	 * @return array
480
	 */
481
	private function _get_cpf_fields()
482
	{
483
		$sql = 'SELECT l.lang_name, f.field_ident
484
			FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f
485
			WHERE l.lang_id = ' . $this->user->get_iso_lang_id() . '
486
				AND f.field_active = 1
487
				AND f.field_no_view = 0
488
				AND f.field_hide = 0
489
				AND l.field_id = f.field_id
490
			ORDER BY f.field_order';
491
		$result = $this->db->sql_query($sql);
492
493
		$cpf_options = false;
494
		while ($row = $this->db->sql_fetchrow($result))
495
		{
496
			$cpf_options[$row['field_ident']] = $row['lang_name'];
497
		}
498
		$this->db->sql_freeresult($result);
499
500
		return $cpf_options;
501
	}
502
}
503