Passed
Push — develop ( b3eda6...9f2d35 )
by Daniel
03:59 queued 40s
created

poll::get_poll_options()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 22
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 15
nc 2
nop 4
dl 0
loc 22
ccs 17
cts 17
cp 1
crap 2
rs 9.7666
c 0
b 0
f 0
1
<?php
2
3
/**
4
 *
5
 * @package sitemaker
6
 * @copyright (c) 2013 Daniel A. (blitze)
7
 * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
8
 *
9
 */
10
11
namespace blitze\sitemaker\services;
12
13
class poll
14
{
15
	/** @var \phpbb\auth\auth */
16
	protected $auth;
17
18
	/** @var \phpbb\config\config */
19
	protected $config;
20
21
	/** @var \phpbb\db\driver\driver_interface */
22
	protected $db;
23
24
	/** @var \phpbb\request\request_interface */
25
	protected $request;
26
27
	/** @var \phpbb\language\language */
28
	protected $translator;
29
30
	/** @var \phpbb\user */
31
	protected $user;
32
33
	/** @var \blitze\sitemaker\services\util */
34
	protected $sitemaker;
35
36
	/** @var string */
37
	protected $phpbb_root_path;
38
39
	/** @var string */
40
	protected $php_ext;
41
42
	/**
43
	 * Constructor
44
	 *
45
	 * @param \phpbb\auth\auth						$auth				Permission object
46
	 * @param \phpbb\config\config					$config				Config object
47
	 * @param \phpbb\db\driver\driver_interface		$db	 				Database connection
48
	 * @param \phpbb\request\request_interface		$request			Request object
49
	 * @param \phpbb\language\language				$translator			Language object
50
	 * @param \phpbb\user							$user				User object
51
	 * @param \blitze\sitemaker\services\util		$sitemaker			Sitemaker Object
52
	 * @param string								$phpbb_root_path	Path to the phpbb includes directory.
53
	 * @param string								$php_ext			php file extension
54 4
	 */
55
	public function __construct(\phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\request\request_interface $request, \phpbb\language\language $translator, \phpbb\user $user, \blitze\sitemaker\services\util $sitemaker, $phpbb_root_path, $php_ext)
56 4
	{
57 4
		$this->auth = $auth;
58 4
		$this->config = $config;
59 4
		$this->db = $db;
60 4
		$this->request = $request;
61 4
		$this->translator = $translator;
62 4
		$this->user = $user;
63 4
		$this->sitemaker = $sitemaker;
64 4
		$this->phpbb_root_path = $phpbb_root_path;
65 4
		$this->php_ext = $php_ext;
66
	}
67
68
	/**
69
	 * @param array $topic_data
70
	 * @return array
71 2
	 */
72
	public function build(array $topic_data)
73 2
	{
74
		$this->translator->add_lang('viewtopic');
75 2
76 2
		$forum_id = (int) $topic_data['forum_id'];
77
		$topic_id = (int) $topic_data['topic_id'];
78 2
79 2
		$cur_voted_id = $this->get_users_votes($topic_id);
80 2
		$s_can_vote = $this->user_can_vote($forum_id, $topic_data, $cur_voted_id);
81
		$viewtopic_url = append_sid("{$this->phpbb_root_path}viewtopic.{$this->php_ext}", "f=$forum_id&amp;t=$topic_id");
82 2
83 2
		$poll_total = $poll_most = 0;
84 2
		$poll_info = $this->get_poll_info($topic_data, $poll_total, $poll_most);
85
		$poll_end = $topic_data['poll_length'] + $topic_data['poll_start'];
86 2
87
		return array(
88 2
			'POLL_QUESTION'		=> $topic_data['poll_title'],
89 2
			'TOTAL_VOTES' 		=> $poll_total,
90 2
			'POLL_LEFT_CAP_IMG'	=> $this->user->img('poll_left'),
91 2
			'POLL_RIGHT_CAP_IMG' => $this->user->img('poll_right'),
92 2
93
			'MAX_VOTES'			=> $this->translator->lang('MAX_OPTIONS_SELECT', (int) $topic_data['poll_max_options']),
94 2
			'POLL_LENGTH'		=> $this->get_poll_length_lang($topic_data['poll_length'], $poll_end),
95 2
			'POLL_OPTIONS'		=> $this->get_poll_options($cur_voted_id, $poll_info, $poll_total, $poll_most),
96
97 2
			'S_CAN_VOTE'		=> $s_can_vote,
98 2
			'S_DISPLAY_RESULTS'	=> $this->show_results($s_can_vote, $cur_voted_id),
99 2
			'S_IS_MULTI_CHOICE'	=> $this->poll_is_multiple_choice($topic_data['poll_max_options']),
100 2
			'S_POLL_ACTION'		=> $viewtopic_url,
101 2
			'S_FORM_TOKEN'		=> $this->sitemaker->get_form_key('posting'),
102
103 2
			'U_VIEW_RESULTS'	=> $viewtopic_url . '&amp;view=viewpoll',
104 2
		);
105 2
	}
106
107
	/**
108
	 * @param int $forum_id
109
	 * @param array $topic_data
110
	 * @param array $cur_voted_id
111
	 * @return bool
112
	 */
113 2
	private function user_can_vote($forum_id, array $topic_data, array $cur_voted_id)
114
	{
115
		return ($this->user_is_authorized($forum_id, $topic_data, $cur_voted_id) &&
116 2
			$this->poll_is_still_open($topic_data) &&
117 2
			$this->is_topic_status_eligible($topic_data));
118 1
	}
119 2
120
	/**
121
	 * @param int $forum_id
122
	 * @param array $topic_data
123
	 * @param array $cur_voted_id
124
	 * @return bool
125
	 */
126
	private function user_is_authorized($forum_id, array $topic_data, array $cur_voted_id)
127
	{
128 2
		return ($this->auth->acl_get('f_vote', $forum_id) && $this->user_can_change_vote($forum_id, $topic_data, $cur_voted_id));
129
	}
130 2
131
	/**
132
	 * @param int $forum_id
133
	 * @param array $topic_data
134
	 * @param array $cur_voted_id
135
	 * @return bool
136
	 */
137
	private function user_can_change_vote($forum_id, array $topic_data, array $cur_voted_id)
138
	{
139 2
		return (!sizeof($cur_voted_id) || ($this->auth->acl_get('f_votechg', $forum_id) && $topic_data['poll_vote_change']));
140
	}
141 2
142
	/**
143
	 * @param array $topic_data
144
	 * @return bool
145
	 */
146
	private function poll_is_still_open(array $topic_data)
147
	{
148 1
		return (($topic_data['poll_length'] != 0 && $topic_data['poll_start'] + $topic_data['poll_length'] > time()) || $topic_data['poll_length'] == 0);
149
	}
150 1
151
	/**
152
	 * @param array $topic_data
153
	 * @return bool
154
	 */
155
	private function is_topic_status_eligible(array $topic_data)
156
	{
157 1
		return ($topic_data['topic_status'] != ITEM_LOCKED && $topic_data['forum_status'] != ITEM_LOCKED);
158
	}
159 1
160
	/**
161
	 * @param array $topic_data
162
	 * @param int $poll_total
163
	 * @param int $poll_most
164
	 * @return array
165
	 */
166
	private function get_poll_info(array $topic_data, &$poll_total, &$poll_most)
167
	{
168 2
		$topic_id = (int) $topic_data['topic_id'];
169
		$post_id = (int) $topic_data['topic_first_post_id'];
170 2
171 2
		$sql = 'SELECT o.*, p.bbcode_bitfield, p.bbcode_uid
172
			FROM ' . POLL_OPTIONS_TABLE . ' o, ' . POSTS_TABLE . " p
173
			WHERE o.topic_id = $topic_id
174 2
				AND p.post_id = $post_id
175
				AND p.topic_id = o.topic_id
176 2
			ORDER BY o.poll_option_id";
177
		$result = $this->db->sql_query($sql);
178 2
179 2
		$poll_info = array();
180
		while ($row = $this->db->sql_fetchrow($result))
181 2
		{
182 2
			$poll_info[] = $row;
183
			$poll_total += $row['poll_option_total'];
184 2
			$poll_most = ($row['poll_option_total'] >= $poll_most) ? $row['poll_option_total'] : $poll_most;
185 2
		}
186 2
		$this->db->sql_freeresult($result);
187 2
188 2
		return $this->parse_poll($topic_data, $poll_info);
189
	}
190 2
191
	/**
192
	 * @param array $topic_data
193
	 * @param array $poll_info
194
	 * @return array
195
	 */
196
	private function parse_poll(array &$topic_data, array $poll_info)
197
	{
198 2
		$parse_flags = ($poll_info[0]['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0) | OPTION_FLAG_SMILIES;
199
200 2
		for ($i = 0, $size = sizeof($poll_info); $i < $size; $i++)
201
		{
202 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);
203
		}
204 2
205 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);
206
207 2
		return $poll_info;
208
	}
209 2
210
	/**
211
	 * @param array $cur_voted_id
212
	 * @param array $poll_info
213
	 * @param int $poll_total
214
	 * @param int $poll_most
215
	 * @return array
216
	 */
217
	private function get_poll_options(array $cur_voted_id, array $poll_info, $poll_total, $poll_most)
218
	{
219 2
		$options = [];
220
		foreach ($poll_info as $poll_option)
221 2
		{
222
			$option_pct = $this->calculate_option_percent($poll_option['poll_option_total'], $poll_total);
223 2
			$option_pct_rel = $this->calculate_option_percent_rel($poll_option['poll_option_total'], $poll_most);
224 2
225
			$options[] = array(
226 2
				'POLL_OPTION_ID' 			=> $poll_option['poll_option_id'],
227 2
				'POLL_OPTION_CAPTION' 		=> $poll_option['poll_option_text'],
228 2
				'POLL_OPTION_RESULT' 		=> $poll_option['poll_option_total'],
229 2
				'POLL_OPTION_PERCENT' 		=> sprintf("%.1d%%", round($option_pct * 100)),
230 2
				'POLL_OPTION_PERCENT_REL' 	=> sprintf("%.1d%%", round($option_pct_rel * 100)),
231 2
				'POLL_OPTION_PCT'			=> round($option_pct * 100),
232 2
				'POLL_OPTION_WIDTH'     	=> round($option_pct * 250),
233 2
				'POLL_OPTION_VOTED'			=> $this->user_has_voted_option($poll_option['poll_option_id'], $cur_voted_id),
234 2
				'POLL_OPTION_MOST_VOTES'	=> $this->is_most_voted($poll_option['poll_option_total'], $poll_most),
235 2
			);
236 2
		}
237 2
238 2
		return $options;
239
	}
240
241
	/**
242
	 * @param int $topic_id
243
	 * @return array
244 2
	 */
245
	private function get_users_votes($topic_id)
246 2
	{
247 2
		$cur_voted_id = array();
248 2
		if ($this->user->data['is_registered'])
249
		{
250 1
			$sql = 'SELECT poll_option_id
251 1
			FROM ' . POLL_VOTES_TABLE . '
252 1
			WHERE topic_id = ' . (int) $topic_id . '
253 1
				AND vote_user_id = ' . (int) $this->user->data['user_id'];
254
			$result = $this->db->sql_query($sql);
255 1
256
			while ($row = $this->db->sql_fetchrow($result))
257 1
			{
258 1
				$cur_voted_id[] = $row['poll_option_id'];
259 1
			}
260 1
			$this->db->sql_freeresult($result);
261
		}
262
		else
263
		{
264
			// Cookie based guest tracking ... I don't like this but hum ho
265
			// it's oft requested. This relies on "nice" users who don't feel
266 1
			// the need to delete cookies to mess with results.
267 1
			if ($this->request->is_set($this->config['cookie_name'] . '_poll_' . $topic_id, \phpbb\request\request_interface::COOKIE))
0 ignored issues
show
Bug introduced by
phpbb\request\request_interface::COOKIE of type integer is incompatible with the type phpbb\request\request_interface expected by parameter $super_global of phpbb\request\request_interface::is_set(). ( Ignorable by Annotation )

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

267
			if ($this->request->is_set($this->config['cookie_name'] . '_poll_' . $topic_id, /** @scrutinizer ignore-type */ \phpbb\request\request_interface::COOKIE))
Loading history...
268 1
			{
269 1
				$cur_voted_id = explode(',', $this->request->variable($this->config['cookie_name'] . '_poll_' . $topic_id, '', true, \phpbb\request\request_interface::COOKIE));
0 ignored issues
show
Bug introduced by
phpbb\request\request_interface::COOKIE of type integer is incompatible with the type phpbb\request\request_interface expected by parameter $super_global of phpbb\request\request_interface::variable(). ( Ignorable by Annotation )

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

269
				$cur_voted_id = explode(',', $this->request->variable($this->config['cookie_name'] . '_poll_' . $topic_id, '', true, /** @scrutinizer ignore-type */ \phpbb\request\request_interface::COOKIE));
Loading history...
270 1
				$cur_voted_id = array_map('intval', $cur_voted_id);
271
			}
272
		}
273 2
274
		return $cur_voted_id;
275
	}
276
277
	/**
278
	 * @param int $poll_option_id
279
	 * @param array $cur_voted_id
280
	 * @return bool
281 2
	 */
282
	private function user_has_voted_option($poll_option_id, array $cur_voted_id)
283 2
	{
284
		return (in_array($poll_option_id, $cur_voted_id)) ? true : false;
285
	}
286
287
	/**
288
	 * @param int $poll_option_total
289
	 * @param int $poll_total
290
	 * @return float|int
291 2
	 */
292
	private function calculate_option_percent($poll_option_total, $poll_total)
293 2
	{
294
		return ($poll_total > 0) ? $poll_option_total / $poll_total : 0;
295
	}
296
297
	/**
298
	 * @param int $poll_option_total
299
	 * @param int $poll_most
300
	 * @return float|int
301 2
	 */
302
	private function calculate_option_percent_rel($poll_option_total, $poll_most)
303 2
	{
304
		return ($poll_most > 0) ? $poll_option_total / $poll_most : 0;
305
	}
306
307
	/**
308
	 * @param int $poll_option_total
309
	 * @param int $poll_most
310
	 * @return bool
311 2
	 */
312
	private function is_most_voted($poll_option_total, $poll_most)
313 2
	{
314
		return ($poll_option_total > 0 && $poll_option_total == $poll_most) ? true : false;
315
	}
316
317
	/**
318
	 * @param int $poll_max_options
319
	 * @return bool
320 2
	 */
321
	private function poll_is_multiple_choice($poll_max_options)
322 2
	{
323
		return ($poll_max_options > 1) ? true : false;
324
	}
325
326
	/**
327
	 * @param int $poll_length
328
	 * @param int $poll_end
329
	 * @return string
330 2
	 */
331
	private function get_poll_length_lang($poll_length, $poll_end)
332 2
	{
333
		return ($poll_length) ? $this->translator->lang(($poll_end > time()) ? 'POLL_RUN_TILL' : 'POLL_ENDED_AT', $this->user->format_date($poll_end)) : '';
334
	}
335
336
	/**
337
	 * @param bool $s_can_vote
338
	 * @param array $cur_voted_id
339
	 * @return bool
340 2
	 */
341
	private function show_results($s_can_vote, array $cur_voted_id)
342 2
	{
343
		return (!$s_can_vote || ($s_can_vote && sizeof($cur_voted_id))) ? true : false;
344
	}
345
}
346