diff --git a/src/applications/slowvote/controller/PhabricatorSlowvoteVoteController.php b/src/applications/slowvote/controller/PhabricatorSlowvoteVoteController.php --- a/src/applications/slowvote/controller/PhabricatorSlowvoteVoteController.php +++ b/src/applications/slowvote/controller/PhabricatorSlowvoteVoteController.php @@ -7,6 +7,10 @@ $viewer = $request->getViewer(); $id = $request->getURIData('id'); + if (!$request->isFormPost()) { + return id(new Aphront404Response()); + } + $poll = id(new PhabricatorSlowvoteQuery()) ->setViewer($viewer) ->withIDs(array($id)) @@ -16,31 +20,36 @@ if (!$poll) { return new Aphront404Response(); } + if ($poll->getIsClosed()) { return new Aphront400Response(); } $options = $poll->getOptions(); - $viewer_choices = $poll->getViewerChoices($viewer); - - $old_votes = mpull($viewer_choices, null, 'getOptionID'); + $options = mpull($options, null, 'getID'); - if (!$request->isFormPost()) { - return id(new Aphront404Response()); - } + $old_votes = $poll->getViewerChoices($viewer); + $old_votes = mpull($old_votes, null, 'getOptionID'); $votes = $request->getArr('vote'); $votes = array_fuse($votes); - $this->updateVotes($viewer, $poll, $old_votes, $votes); + $method = $poll->getMethod(); + $is_plurality = ($method == PhabricatorSlowvotePoll::METHOD_PLURALITY); - return id(new AphrontRedirectResponse())->setURI('/V'.$poll->getID()); - } + if ($is_plurality && count($votes) > 1) { + throw new Exception( + pht('In this poll, you may only vote for one option.')); + } - private function updateVotes($viewer, $poll, $old_votes, $votes) { - if (!empty($votes) && count($votes) > 1 && - $poll->getMethod() == PhabricatorSlowvotePoll::METHOD_PLURALITY) { - return id(new Aphront400Response()); + foreach ($votes as $vote) { + if (!isset($options[$vote])) { + throw new Exception( + pht( + 'Option ("%s") is not a valid poll option. You may only '. + 'vote for valid options.', + $vote)); + } } foreach ($old_votes as $old_vote) { @@ -60,6 +69,9 @@ ->setOptionID($vote) ->save(); } + + return id(new AphrontRedirectResponse()) + ->setURI($poll->getURI()); } }