Skip to content

Commit 55a7110

Browse files
authored
Merge pull request #87 from topcoder-platform/issues-475_2
Issues-475: Up/Down Votes are counted separately
2 parents 86cf905 + 5dd27ec commit 55a7110

13 files changed

+418
-87
lines changed

Voting/class.voting.plugin.php

Lines changed: 221 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
class VotingPlugin extends Gdn_Plugin {
44

5+
/**
6+
* Database updates.
7+
*/
8+
public function structure() {
9+
include __DIR__.'/structure.php';
10+
}
511
/**
612
* Add JS & CSS to the page.
713
*/
@@ -15,10 +21,9 @@ public function addVotingBox($sender, $args) {
1521
$object = $args['Object'];
1622
$VoteType = $args['Type'] == 'Discussion' ? 'votediscussion' : 'votecomment';
1723
$id = $args['Type'] == 'Discussion' ? val('DiscussionID', $object) : val('CommentID', $object);
18-
$score = val('Score', $object);
24+
$pScore = val('PScore', $object);
25+
$nScore = val('NScore', $object);
1926
$cssClass = '';
20-
$voteUpUrl = '/discussion/'.$VoteType.'/'.$id.'/voteup/'.$session->TransientKey().'/';
21-
$voteDownUrl = '/discussion/'.$VoteType.'/'.$id.'/votedown/'.$session->TransientKey().'/';
2227
if (!$session->IsValid()) {
2328
$voteUpUrl = Gdn::Authenticator()->SignInUrl($sender->SelfUrl);
2429
$voteDownUrl = $voteUpUrl;
@@ -32,32 +37,11 @@ public function addVotingBox($sender, $args) {
3237
$commentModel = new CommentModel();
3338
$currentUserVote = $commentModel->GetUserScore($id, $session->UserID);
3439
}
35-
$cssClassVoteUp = $cssClassVoteDown = '';
36-
if($currentUserVote > 0) {
37-
$cssClassVoteUp = ' Voted';
38-
} else if($currentUserVote < 0){
39-
$cssClassVoteDown = ' Voted';
40-
}
4140

42-
$formattedScore = $this->formattedScore($score);
43-
echo '<span class="Voter">';
44-
echo Anchor(Wrap('Vote Up', 'span', array('class' => 'ArrowSprite SpriteUp'.$cssClassVoteUp , 'rel' => 'nofollow')), $voteUpUrl, 'VoteUp'.$cssClass);
45-
echo Wrap($formattedScore, 'span', array('class' => 'CountVoices'));
46-
echo Anchor(Wrap('Vote Down', 'span', array('class' => 'ArrowSprite SpriteDown'.$cssClassVoteDown, 'rel' => 'nofollow')), $voteDownUrl, 'VoteDown'.$cssClass);
47-
echo '</span>&nbsp;|&nbsp;';
41+
echo generateVoterBox($id,$args['Type'], $pScore, $nScore, $currentUserVote ).'<span class="line"></span>';
4842

4943
}
5044

51-
private function formattedScore($score) {
52-
if(StringIsNullOrEmpty($score)) {
53-
$formattedScore = '0';
54-
} else {
55-
$formattedScore = $score <= 0 ? Gdn_Format::BigNumber($score):'+' . Gdn_Format::BigNumber($score);
56-
}
57-
58-
return $formattedScore;
59-
}
60-
6145

6246
public function discussionController_BeforeInlineDiscussionOptions_handler($sender, $args) {
6347
$this->addVotingBox($sender, $args);
@@ -79,7 +63,145 @@ public function discussionController_render_Before($sender) {
7963
$this->AddJsCss($sender);
8064
}
8165

66+
/**
67+
* Sets the discussion score for specified user.
68+
*
69+
* @param int $discussionID Unique ID of discussion to update.
70+
* @param int $userID Unique ID of user setting score.
71+
* @param int $score New score for discussion.
72+
* @return int Total score.
73+
*/
74+
public function discussionModel_setUserScores_create($sender) {
75+
$discussionID = val(0, $sender->EventArguments);
76+
$userID = val(1, $sender->EventArguments);
77+
$score = val(2, $sender->EventArguments);
78+
$prevScore = val(3, $sender->EventArguments);
79+
80+
81+
// Insert or update the UserDiscussion row
82+
$sender->SQL->replace(
83+
'UserDiscussion',
84+
['Score' => $score],
85+
['DiscussionID' => $discussionID, 'UserID' => $userID]
86+
);
87+
88+
// Get the current total score
89+
$totalScore = $sender->SQL->select('Score', 'sum', 'TotalScore')
90+
->select('NScore', 'sum', 'TotalNScore')
91+
->select('PScore', 'sum', 'TotalPScore')
92+
->from('Discussion')
93+
->where('DiscussionID', $discussionID)
94+
->get()
95+
->firstRow();
96+
97+
$pScore = 0;
98+
$nScore = 0;
99+
if($totalScore) {
100+
$pScore = $totalScore->TotalPScore? $totalScore->TotalPScore : 0;
101+
$nScore = $totalScore->TotalNScore? $totalScore->TotalNScore: 0;
102+
}
103+
if ($prevScore == null) {
104+
$pScore = $score > 0? $pScore+1 : $pScore;
105+
$nScore = $score < 0? $nScore+1 : $nScore;
106+
$tScore = $pScore+$nScore;
107+
} else {
108+
if ($score == 0) { // cancelled a vote
109+
$pScore = $prevScore > 0 ? $pScore - 1 : $pScore;
110+
$nScore = $prevScore < 0 ? $nScore - 1 : $nScore;
111+
$tScore = $pScore + $nScore;
112+
} else { //change a vote
113+
$pScore = $pScore + $score ;
114+
$nScore = $nScore + (-1)*$score;
115+
$tScore = $pScore + $nScore;
116+
}
117+
}
118+
119+
// Update the Discussion's cached version
120+
$sender->SQL->update('Discussion')
121+
->set('Score', $tScore)
122+
->set('PScore', $pScore )
123+
->set('NScore', $nScore)
124+
->where('DiscussionID', $discussionID)
125+
->put();
126+
127+
$updatedTotalScores = $sender->SQL->select('Score', 'sum', 'TotalScore')
128+
->select('NScore', 'sum', 'TotalNScore')
129+
->select('PScore', 'sum', 'TotalPScore')
130+
->from('Discussion')
131+
->where('DiscussionID', $discussionID)
132+
->get()
133+
->firstRow();
134+
return $updatedTotalScores;
135+
}
82136

137+
/**
138+
* Upadte Comment Score value for the specified user and update Total Comment Scores
139+
*
140+
* @param int $commentID Unique ID of comment we're getting the score for.
141+
* @param int $userID Unique ID of user who scored the comment.
142+
*/
143+
public function commentModel_setUserScores_create($sender) {
144+
145+
$commentID = val(0, $sender->EventArguments);
146+
$userID = val(1, $sender->EventArguments);
147+
$score = val(2, $sender->EventArguments);
148+
$prevScore = val(3, $sender->EventArguments);
149+
150+
// Insert or update the UserComment row
151+
$sender->SQL->replace(
152+
'UserComment',
153+
['Score' => $score],
154+
['CommentID' => $commentID, 'UserID' => $userID]
155+
);
156+
157+
$totalScore = $sender->SQL->select('Score', 'sum', 'TotalScore')
158+
->select('NScore', 'sum', 'TotalNScore')
159+
->select('PScore', 'sum', 'TotalPScore')
160+
->from('Comment')
161+
->where('CommentID', $commentID)
162+
->get()
163+
->firstRow();
164+
165+
$pScore = 0;
166+
$nScore = 0;
167+
168+
if($totalScore) {
169+
$pScore = $totalScore->TotalPScore? $totalScore->TotalPScore : 0;
170+
$nScore = $totalScore->TotalNScore? $totalScore->TotalNScore: 0;
171+
}
172+
if ($prevScore == null) {
173+
$pScore = $score > 0? $pScore+1 : $pScore;
174+
$nScore = $score < 0? $nScore+1 : $nScore;
175+
$tScore = $pScore+$nScore;
176+
} else {
177+
if ($score == 0) { // cancelled a vote
178+
$pScore = $prevScore > 0 ? $pScore - 1 : $pScore;
179+
$nScore = $prevScore < 0 ? $nScore - 1 : $nScore;
180+
$tScore = $pScore + $nScore;
181+
} else { //change a vote
182+
$pScore = $pScore + $score ;
183+
$nScore = $nScore + (-1)*$score;
184+
$tScore = $pScore + $nScore;
185+
}
186+
}
187+
188+
// Update the comment's cached version
189+
$sender->SQL->update('Comment')
190+
->set('Score', $tScore)
191+
->set('PScore', $pScore )
192+
->set('NScore', $nScore)
193+
->where('CommentID', $commentID)
194+
->put();
195+
196+
$updatedTotalScores = $sender->SQL->select('Score', 'sum', 'TotalScore')
197+
->select('NScore', 'sum', 'TotalNScore')
198+
->select('PScore', 'sum', 'TotalPScore')
199+
->from('Comment')
200+
->where('CommentID', $commentID)
201+
->get()
202+
->firstRow();
203+
return $updatedTotalScores;
204+
}
83205
/**
84206
* Increment/decrement comment scores
85207
*/
@@ -110,31 +232,26 @@ public function discussionController_VoteComment_create($sender) {
110232
} else {
111233
$FinalVote = $NewUserVote;
112234
}
113-
114-
$Total = $CommentModel->SetUserScore($CommentID, $Session->UserID, $FinalVote);
115235
}
116-
$sender->DeliveryType(DELIVERY_TYPE_BOOL);
117-
$sender->SetJson('TotalScore', $this->formattedScore($Total));
118-
$sender->SetJson('FinalVote', $FinalVote);
119-
$sender->SetJson('VoteUpCssClass', $FinalVote > 0? 'Voted':'');
120-
$sender->SetJson('VoteDownCssClass', $FinalVote < 0? 'Voted':'');
121-
$sender->Render();
236+
237+
$Total = $CommentModel->SetUserScores($CommentID, $Session->UserID, $FinalVote, $OldUserVote);
238+
$sender->DeliveryType(DELIVERY_TYPE_VIEW);
239+
$voterBoxID = '#Voter_Comment_'.$CommentID;
240+
$pScore = val('TotalPScore', $Total);
241+
$nScore = val('TotalNScore', $Total);
242+
$html = generateVoterBox($CommentID,'Comment', $pScore, $nScore, $FinalVote);
243+
$sender->jsonTarget($voterBoxID, $html, 'ReplaceWith');
244+
$sender->render('Blank', 'Utility', 'Dashboard');
122245
}
123246

124247
/**
125248
* Increment/decrement discussion scores
126249
*/
127250
public function discussionController_VoteDiscussion_create($sender) {
128251
$DiscussionID = GetValue(0, $sender->RequestArgs, 0);
129-
$TransientKey = GetValue(1, $sender->RequestArgs);
130-
$VoteType = FALSE;
131-
if ($TransientKey == 'voteup' || $TransientKey == 'votedown') {
132-
$VoteType = $TransientKey;
133-
$TransientKey = GetValue(2, $sender->RequestArgs);
134-
}
252+
$VoteType = GetValue(1, $sender->RequestArgs);
253+
$TransientKey = GetValue(2, $sender->RequestArgs);
135254
$Session = Gdn::Session();
136-
$NewUserVote = 0;
137-
$Total = 0;
138255
if ($Session->IsValid() && $Session->ValidateTransientKey($TransientKey) && $DiscussionID > 0) {
139256
$DiscussionModel = new DiscussionModel();
140257
$OldUserVote = $DiscussionModel->GetUserScore($DiscussionID, $Session->UserID);
@@ -157,14 +274,15 @@ public function discussionController_VoteDiscussion_create($sender) {
157274
} else {
158275
$FinalVote = $NewUserVote;
159276
}
160-
$Total = $DiscussionModel->SetUserScore($DiscussionID, $Session->UserID, $FinalVote);
277+
$Total = $DiscussionModel->SetUserScores($DiscussionID, $Session->UserID, $FinalVote,$OldUserVote);
278+
$sender->DeliveryType(DELIVERY_TYPE_VIEW);
279+
$voterBoxID = '#Voter_Discussion_'.$DiscussionID;
280+
$pScore = val('TotalPScore', $Total);
281+
$nScore = val('TotalNScore', $Total);
282+
$html = generateVoterBox($DiscussionID,'Discussion', $pScore, $nScore, $FinalVote);
283+
$sender->jsonTarget($voterBoxID, $html, 'ReplaceWith');
284+
$sender->render('Blank', 'Utility', 'Dashboard');
161285
}
162-
$sender->DeliveryType(DELIVERY_TYPE_BOOL);
163-
$sender->SetJson('TotalScore', $this->formattedScore($Total));
164-
$sender->SetJson('FinalVote', $FinalVote);
165-
$sender->SetJson('VoteUpCssClass', $FinalVote > 0? 'Voted':'');
166-
$sender->SetJson('VoteDownCssClass', $FinalVote < 0? 'Voted':'');
167-
$sender->Render();
168286
}
169287

170288
/**
@@ -182,6 +300,7 @@ public function PostController_Render_Before($Sender) {
182300
}
183301

184302
public function Setup() {
303+
$this->structure();
185304
}
186305

187306
public function OnDisable() {
@@ -198,4 +317,58 @@ public function dashboardNavModule_init_handler($sender) {
198317
'voting.comments', '', $sort);
199318

200319
}
320+
}
321+
322+
if (!function_exists('formattedNScore')) {
323+
function formattedNScore($score)
324+
{
325+
if (StringIsNullOrEmpty($score)) {
326+
$formattedScore = '-0';
327+
} else {
328+
$formattedScore = '-' . Gdn_Format::BigNumber($score);
329+
}
330+
331+
return $formattedScore;
332+
}
333+
}
334+
335+
if (!function_exists('formattedPScore')) {
336+
function formattedPScore($score)
337+
{
338+
if (StringIsNullOrEmpty($score)) {
339+
$formattedScore = '+0';
340+
} else {
341+
$formattedScore = '+' . Gdn_Format::BigNumber($score);
342+
}
343+
344+
return $formattedScore;
345+
}
346+
}
347+
348+
if (!function_exists('generateVoterBox')) {
349+
function generateVoterBox($id, $VoteType, $pScore, $nScore, $currentUserVote)
350+
{
351+
$cssClassVoteUp = 'SpriteVoteUp';
352+
$cssClassVoteDown = 'SpriteVoteDown';
353+
if($currentUserVote > 0) {
354+
$cssClassVoteUp = 'SpriteVoteUpActive';
355+
} else if($currentUserVote < 0){
356+
$cssClassVoteDown = 'SpriteVoteDownActive';
357+
}
358+
359+
$voterBoxID = 'Voter_' . $VoteType . '_' . $id;
360+
$voteUpUrl = '/discussion/vote' . strtolower($VoteType) . '/' . $id . '/voteup/' . Gdn::session()->TransientKey() . '/';
361+
$voteDownUrl = '/discussion/vote' . strtolower($VoteType) . '/' . $id . '/votedown/' . Gdn::session()->TransientKey() . '/';
362+
$result = '<span id="' . $voterBoxID . '" class="Voter">';
363+
$result .= Anchor(Wrap('', 'span', array('class' => 'icon ' . $cssClassVoteUp, 'rel' => 'nofollow')), $voteUpUrl, 'VoteUp');
364+
$counts = formattedPScore($pScore);
365+
if(!StringIsNullOrEmpty($nScore) && $nScore != 0) {
366+
$counts .= '<span class="VoiceDivider">/</span>' . formattedNScore($nScore);
367+
}
368+
$result .= Wrap($counts, 'span', array('class' => 'CountVoices'));
369+
$result .= Anchor(Wrap('', 'span', array('class' => 'icon ' . $cssClassVoteDown, 'rel' => 'nofollow')), $voteDownUrl, 'VoteDown');
370+
$result .= '</span>';
371+
372+
return $result;
373+
}
201374
}

0 commit comments

Comments
 (0)