Completed
Push — master ( 24ebcc...799b0c )
by Daniel
10:31
created

forum_poll::_get_topic_data()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 22
ccs 15
cts 15
cp 1
rs 9.2
cc 1
eloc 15
nc 1
nop 0
crap 1
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
class forum_poll extends \blitze\sitemaker\services\blocks\driver\block
13
{
14
	/** @var \phpbb\auth\auth */
15
	protected $auth;
16
17
	/** @var \phpbb\cache\driver\driver_interface */
18
	protected $cache;
19
20
	/** @var \phpbb\config\config */
21
	protected $config;
22
23
	/** @var \phpbb\db\driver\driver_interface */
24
	protected $db;
25
26
	/** @var \phpbb\request\request_interface */
27
	protected $request;
28
29
	/** @var \phpbb\user */
30
	protected $user;
31
32
	/** @var \blitze\sitemaker\services\forum\data */
33
	protected $forum;
34
35
	/** @var \blitze\sitemaker\services\util */
36
	protected $sitemaker;
37
38
	/** @var string */
39
	protected $phpbb_root_path;
40
41
	/** @var string */
42
	protected $php_ext;
43
44
	/** @var array */
45
	private $settings = array();
46
47
	/**
48
	 * Constructor
49
	 *
50
	 * @param \phpbb\auth\auth						$auth				Permission object
51
	 * @param \phpbb\cache\driver\driver_interface	$cache				Cache driver interface
52
	 * @param \phpbb\config\config					$config				Config object
53
	 * @param \phpbb\db\driver\driver_interface		$db	 				Database connection
54
	 * @param \phpbb\request\request_interface		$request			Request object
55
	 * @param \phpbb\user							$user				User object
56
	 * @param \blitze\sitemaker\services\forum\data	$forum				Forum Data object
57
	 * @param \blitze\sitemaker\services\util		$sitemaker			Sitemaker Object
58
	 * @param string								$phpbb_root_path	Path to the phpbb includes directory.
59
	 * @param string								$php_ext			php file extension
60
	 */
61 3
	public function __construct(\phpbb\auth\auth $auth, \phpbb\cache\driver\driver_interface $cache, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\request\request_interface $request, \phpbb\user $user, \blitze\sitemaker\services\forum\data $forum, \blitze\sitemaker\services\util $sitemaker, $phpbb_root_path, $php_ext)
62
	{
63 3
		$this->auth = $auth;
64 3
		$this->cache = $cache;
65 3
		$this->config = $config;
66 3
		$this->db = $db;
67 3
		$this->request = $request;
68 3
		$this->user = $user;
69 3
		$this->forum = $forum;
70 3
		$this->sitemaker = $sitemaker;
71 3
		$this->phpbb_root_path = $phpbb_root_path;
72 3
		$this->php_ext = $php_ext;
73 3
	}
74
75
	/**
76
	 * {@inheritdoc}
77
	 */
78 1
	public function get_config(array $settings)
79
	{
80 1
		$forum_options = $this->_get_forum_options();
81 1
		$group_options = $this->_get_group_options();
82 1
		$topic_type_options = array(POST_NORMAL => 'POST_NORMAL', POST_STICKY => 'POST_STICKY', POST_ANNOUNCE => 'POST_ANNOUNCEMENT', POST_GLOBAL => 'POST_GLOBAL');
83 1
		$sort_options = array('' => 'RANDOM', FORUMS_ORDER_FIRST_POST	=> 'FIRST_POST_TIME', FORUMS_ORDER_LAST_POST => 'LAST_POST_TIME', FORUMS_ORDER_LAST_READ => 'LAST_READ_TIME');
84
85
		return array(
86 1
			'legend1'		=> $this->user->lang('SETTINGS'),
87 1
			'user_ids'		=> array('lang' => 'POLL_FROM_USERS', 'validate' => 'string', 'type' => 'textarea:3:40', 'maxlength' => 2, 'explain' => true, 'default' => ''),
88 1
			'group_ids'		=> array('lang' => 'POLL_FROM_GROUPS', 'validate' => 'string', 'type' => 'multi_select', 'options' => $group_options, 'default' => array(), 'explain' => true),
89 1
			'topic_ids'		=> array('lang' => 'POLL_FROM_TOPICS', 'validate' => 'string', 'type' => 'textarea:3:40', 'maxlength' => 2, 'explain' => true, 'default' => ''),
90 1
			'forum_ids'		=> array('lang' => 'POLL_FROM_FORUMS', 'validate' => 'string', 'type' => 'multi_select', 'options' => $forum_options, 'default' => array(), 'explain' => true),
91 1
			'topic_type'	=> array('lang' => 'TOPIC_TYPE', 'validate' => 'string', 'type' => 'checkbox', 'options' => $topic_type_options, 'default' => array(POST_NORMAL), 'explain' => false),
92 1
			'order_by'		=> array('lang' => 'ORDER_BY', 'validate' => 'string', 'type' => 'select', 'options' => $sort_options, 'default' => 0, 'explain' => false),
93 1
		);
94
	}
95
96
	/**
97
	 * {@inheritdoc}
98
	 */
99 2
	public function display(array $bdata, $edit_mode = false)
100
	{
101 2
		$this->user->add_lang('viewtopic');
102
103 2
		$this->settings = $bdata['settings'];
104
105 2
		if (!($topic_data = $this->_get_topic_data()))
106 2
		{
107
			return array(
108
				'title'		=> '',
109
				'content'	=> '',
110
			);
111
		}
112
113 2
		$forum_id = (int) $topic_data['forum_id'];
114 2
		$topic_id = (int) $topic_data['topic_id'];
115
116 2
		$viewtopic_url = append_sid("{$this->phpbb_root_path}viewtopic.{$this->php_ext}", "f=$forum_id&amp;t=$topic_id");
117 2
		$cur_voted_id = $this->_get_users_votes($topic_id);
118 2
		$s_can_vote = $this->_user_can_vote($forum_id, $topic_data, $cur_voted_id);
119
120 2
		$poll_total = $poll_most = 0;
121 2
		$poll_info = $this->_get_poll_info($topic_data, $poll_total, $poll_most);
122 2
		$poll_info = $this->_parse_poll($topic_data, $poll_info);
123 2
		$poll_end = $topic_data['poll_length'] + $topic_data['poll_start'];
124
125 2
		$this->_build_poll_options($cur_voted_id, $poll_info, $poll_total, $poll_most);
126
127 2
		$this->ptemplate->assign_vars(array(
128 2
			'POLL_QUESTION'		=> $topic_data['poll_title'],
129 2
			'TOTAL_VOTES' 		=> $poll_total,
130 2
			'POLL_LEFT_CAP_IMG'	=> $this->user->img('poll_left'),
131 2
			'POLL_RIGHT_CAP_IMG'=> $this->user->img('poll_right'),
132
133 2
			'L_MAX_VOTES'		=> $this->user->lang('MAX_OPTIONS_SELECT', (int) $topic_data['poll_max_options']),
134 2
			'L_POLL_LENGTH'		=> $this->_get_poll_length_lang($topic_data['poll_length'], $poll_end),
135
136 2
			'S_CAN_VOTE'		=> $s_can_vote,
137 2
			'S_DISPLAY_RESULTS'	=> $this->_show_results($s_can_vote, $cur_voted_id),
138 2
			'S_IS_MULTI_CHOICE'	=> $this->_poll_is_multiple_choice($topic_data['poll_max_options']),
139 2
			'S_POLL_ACTION'		=> $viewtopic_url,
140 2
			'S_FORM_TOKEN'		=> $this->sitemaker->get_form_key('posting'),
141
142 2
			'U_VIEW_RESULTS'	=> $viewtopic_url . '&amp;view=viewpoll',
143 2
		));
144
145
		return array(
146 2
			'title'		=> 'POLL',
147 2
			'content'	=> $this->ptemplate->render_view('blitze/sitemaker', 'blocks/forum_poll.html', 'forum_poll_block')
148 2
		);
149
	}
150
151
	/**
152
	 * @return array|null
153
	 */
154 2
	private function _get_topic_data()
155
	{
156
		$sql_array = array(
157
			'WHERE'		=> array(
158 2
				't.poll_start <> 0',
159 2
			),
160 2
		);
161
162 2
		$this->_limit_by_user($sql_array);
163 2
		$this->_limit_by_topic($sql_array);
164 2
		$this->_limit_by_group($sql_array);
165
166 2
		$this->forum->query()
167 2
			->fetch_forum($this->settings['forum_ids'])
168 2
			->fetch_topic_type($this->settings['topic_type'])
169 2
			->set_sorting($this->_get_sorting())
170 2
			->fetch_custom($sql_array)
171 2
			->build();
172 2
		$topic_data = $this->forum->get_topic_data(1);
173
174 2
		return array_shift($topic_data);
175
	}
176
177
	/**
178
	 * @param array $topic_data
179
	 * @param int $poll_total
180
	 * @param int $poll_most
181
	 * @return array
182
	 */
183 2
	private function _get_poll_info(array $topic_data, &$poll_total, &$poll_most)
184
	{
185 2
		$topic_id = (int) $topic_data['topic_id'];
186 2
		$post_id = (int) $topic_data['topic_first_post_id'];
187
188
		$sql = 'SELECT o.*, p.bbcode_bitfield, p.bbcode_uid
189 2
			FROM ' . POLL_OPTIONS_TABLE . ' o, ' . POSTS_TABLE . " p
190
			WHERE o.topic_id = $topic_id
191 2
				AND p.post_id = $post_id
192
				AND p.topic_id = o.topic_id
193 2
			ORDER BY o.poll_option_id";
194 2
		$result = $this->db->sql_query($sql);
195
196 2
		$poll_info = array();
197 2
		while ($row = $this->db->sql_fetchrow($result))
198
		{
199 2
			$poll_info[] = $row;
200 2
			$poll_total += $row['poll_option_total'];
201 2
			$poll_most = ($row['poll_option_total'] >= $poll_most) ? $row['poll_option_total'] : $poll_most;
202 2
		}
203 2
		$this->db->sql_freeresult($result);
204
205 2
		return $poll_info;
206
	}
207
208
	/**
209
	 * @param array $topic_data
210
	 * @param array $poll_info
211
	 * @return array
212
	 */
213 2
	private function _parse_poll(array &$topic_data, array $poll_info)
214
	{
215 2
		$parse_flags = ($poll_info[0]['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0) | OPTION_FLAG_SMILIES;
216
217 2
		for ($i = 0, $size = sizeof($poll_info); $i < $size; $i++)
218
		{
219 2
			$poll_info[$i]['poll_option_text'] = generate_text_for_display($poll_info[$i]['poll_option_text'], $poll_info[$i]['bbcode_uid'], $poll_info[$i]['bbcode_bitfield'], $parse_flags, true);
220 2
		}
221
222 2
		$topic_data['poll_title'] = generate_text_for_display($topic_data['poll_title'], $poll_info[0]['bbcode_uid'], $poll_info[0]['bbcode_bitfield'], $parse_flags, true);
223
224 2
		return $poll_info;
225
	}
226
227
	/**
228
	 * @param array $cur_voted_id
229
	 * @param array $poll_info
230
	 * @param int $poll_total
231
	 * @param int $poll_most
232
	 */
233 2
	private function _build_poll_options(array $cur_voted_id, array $poll_info, $poll_total, $poll_most)
234
	{
235 2
		foreach ($poll_info as $poll_option)
236
		{
237 2
			$option_pct = $this->_calculate_option_percent($poll_option['poll_option_total'], $poll_total);
238 2
			$option_pct_rel = $this->_calculate_option_percent_rel($poll_option['poll_option_total'], $poll_most);
239
240 2
			$this->ptemplate->assign_block_vars('poll_option', array(
241 2
				'POLL_OPTION_ID' 			=> $poll_option['poll_option_id'],
242 2
				'POLL_OPTION_CAPTION' 		=> $poll_option['poll_option_text'],
243 2
				'POLL_OPTION_RESULT' 		=> $poll_option['poll_option_total'],
244 2
				'POLL_OPTION_PERCENT' 		=> sprintf("%.1d%%", round($option_pct * 100)),
245 2
				'POLL_OPTION_PERCENT_REL' 	=> sprintf("%.1d%%", round($option_pct_rel * 100)),
246 2
				'POLL_OPTION_PCT'			=> round($option_pct * 100),
247 2
				'POLL_OPTION_WIDTH'     	=> round($option_pct * 250),
248 2
				'POLL_OPTION_VOTED'			=> $this->_user_has_voted_option($poll_option['poll_option_id'], $cur_voted_id),
249 2
				'POLL_OPTION_MOST_VOTES'	=> $this->_is_most_voted($poll_option['poll_option_total'], $poll_most),
250 2
			));
251 2
		}
252 2
	}
253
254
	/**
255
	 * @param array $sql_array
256
	 */
257 2
	private function _limit_by_user(array &$sql_array)
258
	{
259 2
		$from_users_ary = array_filter(explode(',', str_replace(' ', '', $this->settings['user_ids'])));
260 2
		$sql_array['WHERE'][] = (sizeof($from_users_ary)) ? $this->db->sql_in_set('t.topic_poster', $from_users_ary) : '';
261 2
	}
262
263
	/**
264
	 * @param array $sql_array
265
	 */
266 2
	private function _limit_by_topic(array &$sql_array)
267
	{
268 2
		$from_topics_ary = array_filter(explode(',', str_replace(' ', '', $this->settings['topic_ids'])));
269 2
		$sql_array['WHERE'][] = (sizeof($from_topics_ary)) ? $this->db->sql_in_set('t.topic_id', $from_topics_ary) : '';
270 2
	}
271
272
	/**
273
	 * @param array $sql_array
274
	 */
275 2
	private function _limit_by_group(array &$sql_array)
276
	{
277 2
		if (!empty($this->settings['group_ids']))
278 2
		{
279 1
			$sql_array['FROM'][USER_GROUP_TABLE] = 'ug';
280 1
			$sql_array['WHERE'][] = 't.topic_poster = ug.user_id';
281 1
			$sql_array['WHERE'][] = $this->db->sql_in_set('ug.group_id', $this->settings['group_ids']);
282 1
		}
283 2
	}
284
285
	/**
286
	 * @param int $topic_id
287
	 * @return array
288
	 */
289 2
	private function _get_users_votes($topic_id)
290
	{
291 2
		$cur_voted_id = array();
292 2
		if ($this->user->data['is_registered'])
293 2
		{
294
			$sql = 'SELECT poll_option_id
295 1
			FROM ' . POLL_VOTES_TABLE . '
296 1
			WHERE topic_id = ' . $topic_id . '
297 1
				AND vote_user_id = ' . $this->user->data['user_id'];
298 1
			$result = $this->db->sql_query($sql);
299
300 1
			while ($row = $this->db->sql_fetchrow($result))
301
			{
302
				$cur_voted_id[] = $row['poll_option_id'];
303
			}
304 1
			$this->db->sql_freeresult($result);
305 1
		}
306
		else
307
		{
308
			// Cookie based guest tracking ... I don't like this but hum ho
309
			// it's oft requested. This relies on "nice" users who don't feel
310
			// the need to delete cookies to mess with results.
311 1
			if ($this->request->is_set($this->config['cookie_name'] . '_poll_' . $topic_id, \phpbb\request\request_interface::COOKIE))
312 1
			{
313 1
				$cur_voted_id = explode(',', $this->request->variable($this->config['cookie_name'] . '_poll_' . $topic_id, '', true, \phpbb\request\request_interface::COOKIE));
314 1
				$cur_voted_id = array_map('intval', $cur_voted_id);
315 1
			}
316
		}
317
318 2
		return $cur_voted_id;
319
	}
320
321
	/**
322
	 * @param int $poll_option_id
323
	 * @param array $cur_voted_id
324
	 * @return bool
325
	 */
326 2
	private function _user_has_voted_option($poll_option_id, array $cur_voted_id)
327
	{
328 2
		return (in_array($poll_option_id, $cur_voted_id)) ? true : false;
329
	}
330
331
	/**
332
	 * @param int $poll_option_total
333
	 * @param int $poll_total
334
	 * @return float|int
335
	 */
336 2
	private function _calculate_option_percent($poll_option_total, $poll_total)
337
	{
338 2
		return ($poll_total > 0) ? $poll_option_total / $poll_total : 0;
339
	}
340
341
	/**
342
	 * @param int $poll_option_total
343
	 * @param int $poll_most
344
	 * @return float|int
345
	 */
346 2
	private function _calculate_option_percent_rel($poll_option_total, $poll_most)
347
	{
348 2
		return ($poll_most > 0) ? $poll_option_total / $poll_most : 0;
349
	}
350
351
	/**
352
	 * @param int $poll_option_total
353
	 * @param int $poll_most
354
	 * @return bool
355
	 */
356 2
	private function _is_most_voted($poll_option_total, $poll_most)
357
	{
358 2
		return ($poll_option_total > 0 && $poll_option_total == $poll_most) ? true : false;
359
	}
360
361
	/**
362
	 * @param int $poll_max_options
363
	 * @return bool
364
	 */
365 2
	private function _poll_is_multiple_choice($poll_max_options)
366
	{
367 2
		return ($poll_max_options > 1) ? true : false;
368
	}
369
370
	/**
371
	 * @param int $poll_length
372
	 * @param int $poll_end
373
	 * @return string
374
	 */
375 2
	private function _get_poll_length_lang($poll_length, $poll_end)
376
	{
377 2
		return ($poll_length) ? sprintf($this->user->lang(($poll_end > time()) ? 'POLL_RUN_TILL' : 'POLL_ENDED_AT'), $this->user->format_date($poll_end)) : '';
378
	}
379
380
	/**
381
	 * @param bool $s_can_vote
382
	 * @param array $cur_voted_id
383
	 * @return bool
384
	 */
385 2
	private function _show_results($s_can_vote, array $cur_voted_id)
386
	{
387 2
		return (!$s_can_vote || ($s_can_vote && sizeof($cur_voted_id))) ? true : false;
388
	}
389
390
	/**
391
	 * @param int $forum_id
392
	 * @param array $topic_data
393
	 * @param array $cur_voted_id
394
	 * @return bool
395
	 */
396 2
	private function _user_can_vote($forum_id, array $topic_data, array $cur_voted_id)
397
	{
398 2
		return ($this->auth->acl_get('f_vote', $forum_id) &&
399 2
			(($topic_data['poll_length'] != 0 && $topic_data['poll_start'] + $topic_data['poll_length'] > time()) || $topic_data['poll_length'] == 0) &&
400 2
			$topic_data['topic_status'] != ITEM_LOCKED &&
401 2
			$topic_data['forum_status'] != ITEM_LOCKED &&
402 2
			(!sizeof($cur_voted_id) ||
403 2
			($this->auth->acl_get('f_votechg', $forum_id) && $topic_data['poll_vote_change']))) ? true : false;
404
	}
405
406
	/**
407
	 * @return string
408
	 */
409 2
	private function _get_sorting()
410
	{
411
		$sort_order = array(
412 2
			FORUMS_ORDER_FIRST_POST		=> 't.topic_time',
413 2
			FORUMS_ORDER_LAST_POST		=> 't.topic_last_post_time',
414 2
			FORUMS_ORDER_LAST_READ		=> 't.topic_last_view_time'
415 2
		);
416
417 2
		return (isset($sort_order[$this->settings['order_by']])) ? $sort_order[$this->settings['order_by']] : 'RAND()';
418
	}
419
420
	/**
421
	 * @return array
422
	 */
423 1
	private function _get_forum_options()
424
	{
425 1
		if (!function_exists('make_forum_select'))
426 1
		{
427 1
			include($this->phpbb_root_path . 'includes/functions_admin.' . $this->php_ext);
428 1
		}
429
430 1
		$forumlist = make_forum_select(false, false, true, false, false, false, true);
431
432 1
		$forum_options = array('' => 'ALL');
433 1
		foreach ($forumlist as $row)
434
		{
435
			$forum_options[$row['forum_id']] = $row['padding'] . $row['forum_name'];
436 1
		}
437
438 1
		return $forum_options;
439
	}
440
441
	/**
442
	 * @return array
443
	 */
444 1
	private function _get_group_options()
445
	{
446
		$sql = 'SELECT group_id, group_name
447 1
			FROM ' . GROUPS_TABLE . '
448 1
			WHERE group_type = ' . GROUP_SPECIAL . '
449 1
			ORDER BY group_name ASC';
450 1
		$result = $this->db->sql_query($sql);
451
452 1
		$group_options = array('' => 'ALL');
453 1
		while ($row = $this->db->sql_fetchrow($result))
454
		{
455 1
			$group_options[$row['group_id']] = $this->user->lang('G_' . $row['group_name']);
456 1
		}
457 1
		$this->db->sql_freeresult($result);
458
459 1
		return $group_options;
460
	}
461
}
462