@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class PhabricatorSlowvoteVoteController
4 extends PhabricatorSlowvoteController {
5
6 public function handleRequest(AphrontRequest $request) {
7 $viewer = $request->getViewer();
8 $id = $request->getURIData('id');
9
10 if (!$request->isFormPost()) {
11 return id(new Aphront404Response());
12 }
13
14 $poll = id(new PhabricatorSlowvoteQuery())
15 ->setViewer($viewer)
16 ->withIDs(array($id))
17 ->needOptions(true)
18 ->needViewerChoices(true)
19 ->executeOne();
20 if (!$poll) {
21 return new Aphront404Response();
22 }
23
24 if ($poll->isClosed()) {
25 return new Aphront400Response();
26 }
27
28 $options = $poll->getOptions();
29 $options = mpull($options, null, 'getID');
30
31 $old_votes = $poll->getViewerChoices($viewer);
32 $old_votes = mpull($old_votes, null, 'getOptionID');
33
34 $votes = $request->getArr('vote');
35 $votes = array_fuse($votes);
36
37 $method = $poll->getMethod();
38 $is_plurality = ($method == SlowvotePollVotingMethod::METHOD_PLURALITY);
39
40 if (!$votes) {
41 if ($is_plurality) {
42 $message = pht('You must vote for something.');
43 } else {
44 $message = pht('You must vote for at least one option.');
45 }
46
47 return $this->newDialog()
48 ->setTitle(pht('Stand For Something'))
49 ->appendParagraph($message)
50 ->addCancelButton($poll->getURI());
51 }
52
53 if ($is_plurality && count($votes) > 1) {
54 throw new Exception(
55 pht('In this poll, you may only vote for one option.'));
56 }
57
58 foreach ($votes as $vote) {
59 if (!isset($options[$vote])) {
60 throw new Exception(
61 pht(
62 'Option ("%s") is not a valid poll option. You may only '.
63 'vote for valid options.',
64 $vote));
65 }
66 }
67
68 $poll->openTransaction();
69 $poll->beginReadLocking();
70
71 $poll->reload();
72
73 $old_votes = id(new PhabricatorSlowvoteChoice())->loadAllWhere(
74 'pollID = %d AND authorPHID = %s',
75 $poll->getID(),
76 $viewer->getPHID());
77 $old_votes = mpull($old_votes, null, 'getOptionID');
78
79 foreach ($old_votes as $old_vote) {
80 if (idx($votes, $old_vote->getOptionID())) {
81 continue;
82 }
83
84 $old_vote->delete();
85 }
86
87 foreach ($votes as $vote) {
88 if (idx($old_votes, $vote)) {
89 continue;
90 }
91
92 id(new PhabricatorSlowvoteChoice())
93 ->setAuthorPHID($viewer->getPHID())
94 ->setPollID($poll->getID())
95 ->setOptionID($vote)
96 ->save();
97 }
98
99 $poll->endReadLocking();
100 $poll->saveTransaction();
101
102 return id(new AphrontRedirectResponse())
103 ->setURI($poll->getURI());
104 }
105
106}