@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
fork

Configure Feed

Select the types of activity you want to include in your feed.

Ability to close poll

Summary: Fixes T3566 List of poll actions should include ability to close an open poll or reopen a closed poll.

Test Plan: Poll author should be able to close/reopen poll. Non-author should get policy screen when attempting to close/reopen poll.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: epriestley, Korvin

Maniphest Tasks: T3566

Differential Revision: https://secure.phabricator.com/D8846

authored by

lkassianik and committed by
epriestley
9a827096 ea66aead

+189 -16
+2
resources/sql/autopatches/20140421.slowvotecolumnsisclosed.sql
··· 1 + ALTER TABLE {$NAMESPACE}_slowvote.slowvote_poll 2 + ADD COLUMN isClosed BOOL NOT NULL;
+2
src/__phutil_library_map__.php
··· 2092 2092 'PhabricatorSetupIssueView' => 'applications/config/view/PhabricatorSetupIssueView.php', 2093 2093 'PhabricatorSlowvoteCapabilityDefaultView' => 'applications/slowvote/capability/PhabricatorSlowvoteCapabilityDefaultView.php', 2094 2094 'PhabricatorSlowvoteChoice' => 'applications/slowvote/storage/PhabricatorSlowvoteChoice.php', 2095 + 'PhabricatorSlowvoteCloseController' => 'applications/slowvote/controller/PhabricatorSlowvoteCloseController.php', 2095 2096 'PhabricatorSlowvoteComment' => 'applications/slowvote/storage/PhabricatorSlowvoteComment.php', 2096 2097 'PhabricatorSlowvoteCommentController' => 'applications/slowvote/controller/PhabricatorSlowvoteCommentController.php', 2097 2098 'PhabricatorSlowvoteController' => 'applications/slowvote/controller/PhabricatorSlowvoteController.php', ··· 4968 4969 'PhabricatorSetupIssueView' => 'AphrontView', 4969 4970 'PhabricatorSlowvoteCapabilityDefaultView' => 'PhabricatorPolicyCapability', 4970 4971 'PhabricatorSlowvoteChoice' => 'PhabricatorSlowvoteDAO', 4972 + 'PhabricatorSlowvoteCloseController' => 'PhabricatorSlowvoteController', 4971 4973 'PhabricatorSlowvoteComment' => 'PhabricatorSlowvoteDAO', 4972 4974 'PhabricatorSlowvoteCommentController' => 'PhabricatorSlowvoteController', 4973 4975 'PhabricatorSlowvoteController' => 'PhabricatorController',
+1
src/applications/slowvote/application/PhabricatorApplicationSlowvote.php
··· 46 46 'edit/(?P<id>[1-9]\d*)/' => 'PhabricatorSlowvoteEditController', 47 47 '(?P<id>[1-9]\d*)/' => 'PhabricatorSlowvoteVoteController', 48 48 'comment/(?P<id>[1-9]\d*)/' => 'PhabricatorSlowvoteCommentController', 49 + 'close/(?P<id>[1-9]\d*)/' => 'PhabricatorSlowvoteCloseController', 49 50 ), 50 51 ); 51 52 }
+71
src/applications/slowvote/controller/PhabricatorSlowvoteCloseController.php
··· 1 + <?php 2 + 3 + final class PhabricatorSlowvoteCloseController 4 + extends PhabricatorSlowvoteController { 5 + 6 + private $id; 7 + 8 + public function willProcessRequest(array $data) { 9 + $this->id = $data['id']; 10 + } 11 + 12 + public function processRequest() { 13 + $request = $this->getRequest(); 14 + $user = $request->getUser(); 15 + 16 + $poll = id(new PhabricatorSlowvoteQuery()) 17 + ->setViewer($user) 18 + ->withIDs(array($this->id)) 19 + ->requireCapabilities( 20 + array( 21 + PhabricatorPolicyCapability::CAN_VIEW, 22 + PhabricatorPolicyCapability::CAN_EDIT, 23 + )) 24 + ->executeOne(); 25 + if (!$poll) { 26 + return new Aphront404Response(); 27 + } 28 + 29 + $close_uri = '/V'.$poll->getID(); 30 + 31 + if ($request->isFormPost()) { 32 + if ($poll->getIsClosed()) { 33 + $new_status = 0; 34 + } else { 35 + $new_status = 1; 36 + } 37 + 38 + $xactions = array(); 39 + 40 + $xactions[] = id(new PhabricatorSlowvoteTransaction()) 41 + ->setTransactionType(PhabricatorSlowvoteTransaction::TYPE_CLOSE) 42 + ->setNewValue($new_status); 43 + 44 + id(new PhabricatorSlowvoteEditor()) 45 + ->setActor($user) 46 + ->setContentSourceFromRequest($request) 47 + ->setContinueOnNoEffect(true) 48 + ->setContinueOnMissingFields(true) 49 + ->applyTransactions($poll, $xactions); 50 + 51 + return id(new AphrontRedirectResponse())->setURI($close_uri); 52 + } 53 + 54 + if ($poll->getIsClosed()) { 55 + $title = pht('Reopen Poll'); 56 + $content = pht('Are you sure you want to reopen the poll?'); 57 + $submit = pht('Reopen'); 58 + } else { 59 + $title = pht('Close Poll'); 60 + $content = pht('Are you sure you want to close the poll?'); 61 + $submit = pht('Close'); 62 + } 63 + 64 + return $this->newDialog() 65 + ->setTitle($title) 66 + ->appendChild($content) 67 + ->addSubmitButton($submit) 68 + ->addCancelButton($close_uri); 69 + } 70 + 71 + }
+1
src/applications/slowvote/controller/PhabricatorSlowvoteListController.php
··· 51 51 ->setObjectName('V'.$poll->getID()) 52 52 ->setHeader($poll->getQuestion()) 53 53 ->setHref('/V'.$poll->getID()) 54 + ->setDisabled($poll->getIsClosed()) 54 55 ->addIcon('none', $date_created); 55 56 56 57 $description = $poll->getDescription();
+16
src/applications/slowvote/controller/PhabricatorSlowvotePollController.php
··· 41 41 )); 42 42 } 43 43 44 + $header_icon = $poll->getIsClosed() ? 'oh-closed' : 'open'; 45 + $header_name = $poll->getIsClosed() ? pht('Closed') : pht('Open'); 46 + 44 47 $header = id(new PHUIHeaderView()) 45 48 ->setHeader($poll->getQuestion()) 46 49 ->setUser($user) 50 + ->setStatus($header_icon, '', $header_name) 47 51 ->setPolicyObject($poll); 48 52 49 53 $actions = $this->buildActionView($poll); ··· 91 95 $poll, 92 96 PhabricatorPolicyCapability::CAN_EDIT); 93 97 98 + $is_closed = $poll->getIsClosed(); 99 + $close_poll_text = $is_closed ? pht('Reopen Poll') : pht('Close Poll'); 100 + $close_poll_icon = $is_closed ? 'enable' : 'disable'; 101 + 94 102 $view->addAction( 95 103 id(new PhabricatorActionView()) 96 104 ->setName(pht('Edit Poll')) ··· 98 106 ->setHref($this->getApplicationURI('edit/'.$poll->getID().'/')) 99 107 ->setDisabled(!$can_edit) 100 108 ->setWorkflow(!$can_edit)); 109 + 110 + $view->addAction( 111 + id(new PhabricatorActionView()) 112 + ->setName($close_poll_text) 113 + ->setIcon($close_poll_icon) 114 + ->setHref($this->getApplicationURI('close/'.$poll->getID().'/')) 115 + ->setDisabled(!$can_edit) 116 + ->setWorkflow(true)); 101 117 102 118 return $view; 103 119 }
+3
src/applications/slowvote/controller/PhabricatorSlowvoteVoteController.php
··· 25 25 if (!$poll) { 26 26 return new Aphront404Response(); 27 27 } 28 + if ($poll->getIsClosed()) { 29 + return new Aphront400Response(); 30 + } 28 31 29 32 $options = $poll->getOptions(); 30 33 $user_choices = $poll->getViewerChoices($user);
+7
src/applications/slowvote/editor/PhabricatorSlowvoteEditor.php
··· 13 13 $types[] = PhabricatorSlowvoteTransaction::TYPE_DESCRIPTION; 14 14 $types[] = PhabricatorSlowvoteTransaction::TYPE_RESPONSES; 15 15 $types[] = PhabricatorSlowvoteTransaction::TYPE_SHUFFLE; 16 + $types[] = PhabricatorSlowvoteTransaction::TYPE_CLOSE; 16 17 17 18 return $types; 18 19 } ··· 54 55 return $object->getResponseVisibility(); 55 56 case PhabricatorSlowvoteTransaction::TYPE_SHUFFLE: 56 57 return $object->getShuffle(); 58 + case PhabricatorSlowvoteTransaction::TYPE_CLOSE: 59 + return $object->getIsClosed(); 57 60 } 58 61 } 59 62 ··· 66 69 case PhabricatorSlowvoteTransaction::TYPE_DESCRIPTION: 67 70 case PhabricatorSlowvoteTransaction::TYPE_RESPONSES: 68 71 case PhabricatorSlowvoteTransaction::TYPE_SHUFFLE: 72 + case PhabricatorSlowvoteTransaction::TYPE_CLOSE: 69 73 return $xaction->getNewValue(); 70 74 } 71 75 } ··· 86 90 break; 87 91 case PhabricatorSlowvoteTransaction::TYPE_SHUFFLE: 88 92 $object->setShuffle($xaction->getNewValue()); 93 + break; 94 + case PhabricatorSlowvoteTransaction::TYPE_CLOSE: 95 + $object->setIsClosed((int)$xaction->getNewValue()); 89 96 break; 90 97 } 91 98 }
+13
src/applications/slowvote/query/PhabricatorSlowvoteQuery.php
··· 10 10 private $phids; 11 11 private $authorPHIDs; 12 12 private $withVotesByViewer; 13 + private $isClosed; 13 14 14 15 private $needOptions; 15 16 private $needChoices; ··· 32 33 33 34 public function withVotesByViewer($with_vote) { 34 35 $this->withVotesByViewer = $with_vote; 36 + return $this; 37 + } 38 + 39 + public function withIsClosed($with_closed) { 40 + $this->isClosed = $with_closed; 35 41 return $this; 36 42 } 37 43 ··· 144 150 $conn_r, 145 151 'p.authorPHID IN (%Ls)', 146 152 $this->authorPHIDs); 153 + } 154 + 155 + if ($this->isClosed !== null) { 156 + $where[] = qsprintf( 157 + $conn_r, 158 + 'p.isClosed = %d', 159 + (int)$this->isClosed); 147 160 } 148 161 149 162 $where[] = $this->buildPagingClause($conn_r);
+29 -1
src/applications/slowvote/query/PhabricatorSlowvoteSearchEngine.php
··· 10 10 $this->readUsersFromRequest($request, 'authors')); 11 11 12 12 $saved->setParameter('voted', $request->getBool('voted')); 13 + $saved->setParameter('statuses', $request->getArr('statuses')); 13 14 14 15 return $saved; 15 16 } ··· 22 23 $query->withVotesByViewer(true); 23 24 } 24 25 26 + $statuses = $saved->getParameter('statuses', array()); 27 + if (count($statuses) == 1) { 28 + $status = head($statuses); 29 + if ($status == 'open') { 30 + $query->withIsClosed(false); 31 + } else { 32 + $query->withIsClosed(true); 33 + } 34 + } 35 + 25 36 return $query; 26 37 } 27 38 ··· 35 46 ->execute(); 36 47 37 48 $voted = $saved_query->getParameter('voted', false); 49 + $statuses = $saved_query->getParameter('statuses', array()); 38 50 39 51 $form 40 52 ->appendChild( ··· 49 61 'voted', 50 62 1, 51 63 pht("Show only polls I've voted in."), 52 - $voted)); 64 + $voted)) 65 + ->appendChild( 66 + id(new AphrontFormCheckboxControl()) 67 + ->setLabel(pht('Status')) 68 + ->addCheckbox( 69 + 'statuses[]', 70 + 'open', 71 + pht('Open'), 72 + in_array('open', $statuses)) 73 + ->addCheckbox( 74 + 'statuses[]', 75 + 'closed', 76 + pht('Closed'), 77 + in_array('closed', $statuses))); 53 78 } 54 79 55 80 protected function getURI($path) { ··· 58 83 59 84 public function getBuiltinQueryNames() { 60 85 $names = array( 86 + 'open' => pht('Open Polls'), 61 87 'all' => pht('All Polls'), 62 88 ); 63 89 ··· 74 100 $query->setQueryKey($query_key); 75 101 76 102 switch ($query_key) { 103 + case 'open': 104 + return $query->setParameter('statuses', array('open')); 77 105 case 'all': 78 106 return $query; 79 107 case 'authored':
+1
src/applications/slowvote/storage/PhabricatorSlowvotePoll.php
··· 24 24 protected $shuffle; 25 25 protected $method; 26 26 protected $viewPolicy; 27 + protected $isClosed = 0; 27 28 28 29 private $options = self::ATTACHABLE; 29 30 private $choices = self::ATTACHABLE;
+21
src/applications/slowvote/storage/PhabricatorSlowvoteTransaction.php
··· 7 7 const TYPE_DESCRIPTION = 'vote:description'; 8 8 const TYPE_RESPONSES = 'vote:responses'; 9 9 const TYPE_SHUFFLE = 'vote:shuffle'; 10 + const TYPE_CLOSE = 'vote:close'; 10 11 11 12 public function getApplicationName() { 12 13 return 'slowvote'; ··· 28 29 case PhabricatorSlowvoteTransaction::TYPE_DESCRIPTION: 29 30 case PhabricatorSlowvoteTransaction::TYPE_RESPONSES: 30 31 case PhabricatorSlowvoteTransaction::TYPE_SHUFFLE: 32 + case PhabricatorSlowvoteTransaction::TYPE_CLOSE: 31 33 return ($old === null); 32 34 } 33 35 ··· 74 76 $this->renderHandleLink($author_phid)); 75 77 } 76 78 break; 79 + case PhabricatorSlowvoteTransaction::TYPE_CLOSE: 80 + if ($new) { 81 + return pht( 82 + '%s closed this poll.', 83 + $this->renderHandleLink($author_phid)); 84 + } else { 85 + return pht( 86 + '%s reopened this poll.', 87 + $this->renderHandleLink($author_phid)); 88 + } 89 + 90 + break; 77 91 } 78 92 79 93 return parent::getTitle(); ··· 95 109 return 'fa-pencil'; 96 110 case PhabricatorSlowvoteTransaction::TYPE_SHUFFLE: 97 111 return 'fa-refresh'; 112 + case PhabricatorSlowvoteTransaction::TYPE_CLOSE: 113 + if ($new) { 114 + return 'fa-ban'; 115 + } else { 116 + return 'fa-pencil'; 117 + } 98 118 } 99 119 100 120 return parent::getIcon(); ··· 110 130 case PhabricatorSlowvoteTransaction::TYPE_DESCRIPTION: 111 131 case PhabricatorSlowvoteTransaction::TYPE_RESPONSES: 112 132 case PhabricatorSlowvoteTransaction::TYPE_SHUFFLE: 133 + case PhabricatorSlowvoteTransaction::TYPE_CLOSE: 113 134 return PhabricatorTransactions::COLOR_BLUE; 114 135 } 115 136
+22 -15
src/applications/slowvote/view/SlowvoteEmbedView.php
··· 128 128 ), 129 129 $quip); 130 130 131 - $submit = phutil_tag( 132 - 'div', 133 - array( 134 - 'class' => 'slowvote-footer', 135 - ), 136 - phutil_tag( 131 + if ($poll->getIsClosed()) { 132 + $submit = null; 133 + } else { 134 + $submit = phutil_tag( 137 135 'div', 138 136 array( 139 - 'class' => 'slowvote-footer-content', 137 + 'class' => 'slowvote-footer', 140 138 ), 141 - array( 142 - $hint, 143 - phutil_tag( 144 - 'button', 145 - array( 146 - ), 147 - pht('Engage in Deliberations')), 148 - ))); 139 + phutil_tag( 140 + 'div', 141 + array( 142 + 'class' => 'slowvote-footer-content', 143 + ), 144 + array( 145 + $hint, 146 + phutil_tag( 147 + 'button', 148 + array( 149 + ), 150 + pht('Engage in Deliberations')), 151 + ))); 152 + } 149 153 150 154 $body = phabricator_form( 151 155 $this->getUser(), ··· 251 255 PhabricatorSlowvotePoll::METHOD_APPROVAL => 'checkbox', 252 256 ); 253 257 258 + $closed = $this->getPoll()->getIsClosed(); 259 + 254 260 return phutil_tag( 255 261 'input', 256 262 array( ··· 258 264 'name' => 'vote[]', 259 265 'value' => $option->getID(), 260 266 'checked' => ($selected ? 'checked' : null), 267 + 'disabled' => ($closed ? 'disabled' : null), 261 268 )); 262 269 } 263 270