Completed
Pull Request — master (#131)
by Matt
01:30
created

vote   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 184
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 1
dl 0
loc 184
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
B submit() 0 81 7
A remove() 0 33 3
A get_voters() 0 21 2
A profile_url() 0 9 2
1
<?php
2
/**
3
 *
4
 * Ideas extension for the phpBB Forum Software package.
5
 *
6
 * @copyright (c) phpBB Limited <https://www.phpbb.com>
7
 * @license GNU General Public License, version 2 (GPL-2.0)
8
 *
9
 */
10
11
namespace phpbb\ideas\factory;
12
13
/**
14
 * Class for handling votes on ideas
15
 */
16
class vote extends base
17
{
18
	/** @var string */
19
	protected $profile_url;
20
21
	/**
22
	 * Submits a vote on an idea.
23
	 *
24
	 * @param array $idea    The idea returned by get_idea().
25
	 * @param int   $user_id The ID of the user voting.
26
	 * @param int   $value   Up (1) or down (0)?
27
	 *
28
	 * @return array|string Array of information or string on error.
29
	 */
30
	public function submit(&$idea, $user_id, $value)
31
	{
32
		// Validate $vote - must be 0 or 1
33
		if ($value !== 0 && $value !== 1)
34
		{
35
			return 'INVALID_VOTE';
36
		}
37
38
		// Check whether user has already voted - update if they have
39
		$sql = 'SELECT idea_id, vote_value
40
			FROM ' . $this->table_votes . '
41
			WHERE idea_id = ' . (int) $idea['idea_id'] . '
42
				AND user_id = ' . (int) $user_id;
43
		$this->db->sql_query_limit($sql, 1);
44
		if ($row = $this->db->sql_fetchrow())
45
		{
46
			if ($row['vote_value'] != $value)
47
			{
48
				$sql = 'UPDATE ' . $this->table_votes . '
49
					SET vote_value = ' . $value . '
50
					WHERE user_id = ' . (int) $user_id . '
51
						AND idea_id = ' . (int) $idea['idea_id'];
52
				$this->db->sql_query($sql);
53
54
				if ($value == 1)
55
				{
56
					// Change to upvote
57
					$idea['idea_votes_up']++;
58
					$idea['idea_votes_down']--;
59
				}
60
				else
61
				{
62
					// Change to downvote
63
					$idea['idea_votes_up']--;
64
					$idea['idea_votes_down']++;
65
				}
66
67
				$sql_ary = array(
68
					'idea_votes_up'	    => $idea['idea_votes_up'],
69
					'idea_votes_down'	=> $idea['idea_votes_down'],
70
				);
71
72
				$this->update_idea_data($sql_ary, $idea['idea_id'], $this->table_ideas);
73
			}
74
75
			return array(
76
				'message'	    => $this->language->lang('UPDATED_VOTE'),
77
				'votes_up'	    => $idea['idea_votes_up'],
78
				'votes_down'	=> $idea['idea_votes_down'],
79
				'points'        => $this->language->lang('TOTAL_POINTS', $idea['idea_votes_up'] - $idea['idea_votes_down']),
80
				'voters'		=> $this->get_voters($idea['idea_id']),
81
			);
82
		}
83
84
		// Insert vote into votes table.
85
		$sql_ary = array(
86
			'idea_id'		=> (int) $idea['idea_id'],
87
			'user_id'		=> (int) $user_id,
88
			'vote_value'	=> (int) $value,
89
		);
90
91
		$this->insert_idea_data($sql_ary, $this->table_votes);
92
93
		// Update number of votes in ideas table
94
		$idea['idea_votes_' . ($value ? 'up' : 'down')]++;
95
96
		$sql_ary = array(
97
			'idea_votes_up'	    => $idea['idea_votes_up'],
98
			'idea_votes_down'	=> $idea['idea_votes_down'],
99
		);
100
101
		$this->update_idea_data($sql_ary, $idea['idea_id'], $this->table_ideas);
102
103
		return array(
104
			'message'	    => $this->language->lang('VOTE_SUCCESS'),
105
			'votes_up'	    => $idea['idea_votes_up'],
106
			'votes_down'	=> $idea['idea_votes_down'],
107
			'points'        => $this->language->lang('TOTAL_POINTS', $idea['idea_votes_up'] - $idea['idea_votes_down']),
108
			'voters'		=> $this->get_voters($idea['idea_id']),
109
		);
110
	}
111
112
	/**
113
	 * Remove a user's vote from an idea
114
	 *
115
	 * @param array   $idea    The idea returned by get_idea().
116
	 * @param int     $user_id The ID of the user voting.
117
	 *
118
	 * @return array Array of information.
119
	 */
120
	public function remove(&$idea, $user_id)
121
	{
122
		// Only change something if user has already voted
123
		$sql = 'SELECT idea_id, vote_value
124
			FROM ' . $this->table_votes . '
125
			WHERE idea_id = ' . (int) $idea['idea_id'] . '
126
				AND user_id = ' . (int) $user_id;
127
		$this->db->sql_query_limit($sql, 1);
128
		if ($row = $this->db->sql_fetchrow())
129
		{
130
			$sql = 'DELETE FROM ' . $this->table_votes . '
131
				WHERE idea_id = ' . (int) $idea['idea_id'] . '
132
					AND user_id = ' . (int) $user_id;
133
			$this->db->sql_query($sql);
134
135
			$idea['idea_votes_' . ($row['vote_value'] == 1 ? 'up' : 'down')]--;
136
137
			$sql_ary = array(
138
				'idea_votes_up'	    => $idea['idea_votes_up'],
139
				'idea_votes_down'	=> $idea['idea_votes_down'],
140
			);
141
142
			$this->update_idea_data($sql_ary, $idea['idea_id'], $this->table_ideas);
143
		}
144
145
		return array(
146
			'message'	    => $this->language->lang('UPDATED_VOTE'),
147
			'votes_up'	    => $idea['idea_votes_up'],
148
			'votes_down'	=> $idea['idea_votes_down'],
149
			'points'        => $this->language->lang('TOTAL_POINTS', $idea['idea_votes_up'] - $idea['idea_votes_down']),
150
			'voters'		=> $this->get_voters($idea['idea_id']),
151
		);
152
	}
153
154
	/**
155
	 * Returns voter info on an idea.
156
	 *
157
	 * @param int $id ID of the idea.
158
	 *
159
	 * @return array Array of row data
160
	 */
161
	public function get_voters($id)
162
	{
163
		$sql = 'SELECT iv.user_id, iv.vote_value, u.username, u.user_colour
164
			FROM ' . $this->table_votes . ' as iv,
165
				' . USERS_TABLE . ' as u
166
			WHERE iv.idea_id = ' . (int) $id . '
167
				AND iv.user_id = u.user_id
168
			ORDER BY u.username ASC';
169
		$result = $this->db->sql_query($sql);
170
		$rows = $this->db->sql_fetchrowset($result);
171
		$this->db->sql_freeresult($result);
172
173
		// Process the username for the template now, so it is
174
		// ready to use in AJAX responses and DOM injections.
175
		foreach ($rows as &$row)
176
		{
177
			$row['user'] = get_username_string('full', $row['user_id'], $row['username'], $row['user_colour'], false, $this->profile_url());
178
		}
179
180
		return $rows;
181
	}
182
183
	/**
184
	 * Helper to generate the user profile URL with an
185
	 * absolute URL, which helps avoid problems when
186
	 * used in AJAX requests.
187
	 *
188
	 * @return string User profile URL
189
	 */
190
	protected function profile_url()
191
	{
192
		if (!isset($this->profile_url))
193
		{
194
			$this->profile_url = append_sid(generate_board_url() . "/memberlist.{$this->php_ext}", array('mode' => 'viewprofile'));
195
		}
196
197
		return $this->profile_url;
198
	}
199
}
200