id = $data['id']; } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $viewer_phid = $user->getPHID(); $poll = id(new PhabricatorSlowvotePoll())->load($this->id); if (!$poll) { return new Aphront404Response(); } $options = id(new PhabricatorSlowvoteOption())->loadAllWhere( 'pollID = %d', $poll->getID()); $choices = id(new PhabricatorSlowvoteChoice())->loadAllWhere( 'pollID = %d', $poll->getID()); $comments = id(new PhabricatorSlowvoteComment())->loadAllWhere( 'pollID = %d', $poll->getID()); $choices_by_option = mgroup($choices, 'getOptionID'); $comments_by_user = mpull($comments, null, 'getAuthorPHID'); $choices_by_user = mgroup($choices, 'getAuthorPHID'); $viewer_choices = idx($choices_by_user, $viewer_phid, array()); $viewer_comment = idx($comments_by_user, $viewer_phid, null); $comment_text = null; if ($viewer_comment) { $comment_text = $viewer_comment->getCommentText(); } if ($request->isFormPost()) { $comment = idx($comments_by_user, $viewer_phid, null); if ($comment) { $comment->delete(); } $comment_text = $request->getStr('comments'); if (strlen($comment_text)) { id(new PhabricatorSlowvoteComment()) ->setAuthorPHID($viewer_phid) ->setPollID($poll->getID()) ->setCommentText($comment_text) ->save(); } $votes = $request->getArr('vote'); switch ($poll->getMethod()) { case PhabricatorSlowvotePoll::METHOD_PLURALITY: // Enforce only one vote. $votes = array_slice($votes, 0, 1); break; case PhabricatorSlowvotePoll::METHOD_APPROVAL: // No filtering. break; default: throw new Exception("Unknown poll method!"); } foreach ($viewer_choices as $viewer_choice) { $viewer_choice->delete(); } foreach ($votes as $vote) { id(new PhabricatorSlowvoteChoice()) ->setAuthorPHID($viewer_phid) ->setPollID($poll->getID()) ->setOptionID($vote) ->save(); } return id(new AphrontRedirectResponse())->setURI('/V'.$poll->getID()); } require_celerity_resource('phabricator-slowvote-css'); $phids = array_merge( mpull($choices, 'getAuthorPHID'), mpull($comments, 'getAuthorPHID'), array( $poll->getAuthorPHID(), )); $query = new PhabricatorObjectHandleData($phids); $query->setViewer($user); $handles = $query->loadHandles(); $objects = $query->loadObjects(); if ($poll->getShuffle()) { shuffle($options); } $option_markup = array(); foreach ($options as $option) { $option_markup[] = $this->renderPollOption( $poll, $viewer_choices, $option); } $comments_by_option = array(); switch ($poll->getMethod()) { case PhabricatorSlowvotePoll::METHOD_PLURALITY: $choice_ids = array(); foreach ($choices_by_user as $user_phid => $user_choices) { $choice_ids[$user_phid] = head($user_choices)->getOptionID(); } foreach ($comments as $comment) { $choice = idx($choice_ids, $comment->getAuthorPHID()); if ($choice) { $comments_by_option[$choice][] = $comment; } } break; case PhabricatorSlowvotePoll::METHOD_APPROVAL: // All comments are grouped in approval voting. break; default: throw new Exception("Unknown poll method!"); } $result_markup = $this->renderResultMarkup( $poll, $options, $choices, $comments, $viewer_choices, $choices_by_option, $comments_by_option, $handles, $objects); if ($viewer_choices) { $instructions = pht('Your vote has been recorded... but there is still ample time to '. 'rethink your position. Have you thoroughly considered all possible '. 'eventualities?'); } else { $instructions = pht('This is a weighty matter indeed. Consider your choices with the '. 'greatest of care.'); } $form = id(new AphrontFormView()) ->setUser($user) ->appendChild(hsprintf( '
%s
', $instructions)) ->appendChild( id(new AphrontFormMarkupControl()) ->setLabel(pht('Vote')) ->setValue($option_markup)) ->appendChild( id(new AphrontFormTextAreaControl()) ->setLabel(pht('Comments')) ->setHeight(AphrontFormTextAreaControl::HEIGHT_SHORT) ->setName('comments') ->setValue($comment_text)) ->appendChild( id(new AphrontFormSubmitControl()) ->setValue(pht('Engage in Deliberations'))); $panel = new AphrontPanelView(); $panel->setHeader($poll->getQuestion()); $panel->setWidth(AphrontPanelView::WIDTH_WIDE); $panel->setNoBackground(); $panel->appendChild($form); $panel->appendChild(hsprintf('%s
', $reason)); return $result_markup; } foreach ($options as $option) { $id = $option->getID(); $chosen = idx($choices_by_option, $id, array()); $users = array_select_keys($handles, mpull($chosen, 'getAuthorPHID')); if ($users) { $user_markup = array(); foreach ($users as $handle) { $object = idx($objects, $handle->getPHID()); if (!$object) { continue; } $profile_image = $handle->getImageURI(); $user_markup[] = phutil_tag( 'a', array( 'href' => $handle->getURI(), 'class' => 'phabricator-slowvote-facepile', ), phutil_tag( 'img', array( 'src' => $profile_image, ))); } } else { $user_markup = pht('This option has failed to appeal to anyone.'); } $comment_markup = $this->renderComments( idx($comments_by_option, $id, array()), $handles); $vote_count = $this->renderVoteCount( $poll, $choices, $chosen); $result_markup->appendChild(hsprintf( '