Skip to content

Commit 9a82709

Browse files
lkassianikepriestley
authored andcommitted
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
1 parent ea66aea commit 9a82709

13 files changed

+189
-16
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ALTER TABLE {$NAMESPACE}_slowvote.slowvote_poll
2+
ADD COLUMN isClosed BOOL NOT NULL;

src/__phutil_library_map__.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2092,6 +2092,7 @@
20922092
'PhabricatorSetupIssueView' => 'applications/config/view/PhabricatorSetupIssueView.php',
20932093
'PhabricatorSlowvoteCapabilityDefaultView' => 'applications/slowvote/capability/PhabricatorSlowvoteCapabilityDefaultView.php',
20942094
'PhabricatorSlowvoteChoice' => 'applications/slowvote/storage/PhabricatorSlowvoteChoice.php',
2095+
'PhabricatorSlowvoteCloseController' => 'applications/slowvote/controller/PhabricatorSlowvoteCloseController.php',
20952096
'PhabricatorSlowvoteComment' => 'applications/slowvote/storage/PhabricatorSlowvoteComment.php',
20962097
'PhabricatorSlowvoteCommentController' => 'applications/slowvote/controller/PhabricatorSlowvoteCommentController.php',
20972098
'PhabricatorSlowvoteController' => 'applications/slowvote/controller/PhabricatorSlowvoteController.php',
@@ -4968,6 +4969,7 @@
49684969
'PhabricatorSetupIssueView' => 'AphrontView',
49694970
'PhabricatorSlowvoteCapabilityDefaultView' => 'PhabricatorPolicyCapability',
49704971
'PhabricatorSlowvoteChoice' => 'PhabricatorSlowvoteDAO',
4972+
'PhabricatorSlowvoteCloseController' => 'PhabricatorSlowvoteController',
49714973
'PhabricatorSlowvoteComment' => 'PhabricatorSlowvoteDAO',
49724974
'PhabricatorSlowvoteCommentController' => 'PhabricatorSlowvoteController',
49734975
'PhabricatorSlowvoteController' => 'PhabricatorController',

src/applications/slowvote/application/PhabricatorApplicationSlowvote.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public function getRoutes() {
4646
'edit/(?P<id>[1-9]\d*)/' => 'PhabricatorSlowvoteEditController',
4747
'(?P<id>[1-9]\d*)/' => 'PhabricatorSlowvoteVoteController',
4848
'comment/(?P<id>[1-9]\d*)/' => 'PhabricatorSlowvoteCommentController',
49+
'close/(?P<id>[1-9]\d*)/' => 'PhabricatorSlowvoteCloseController',
4950
),
5051
);
5152
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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+
}

src/applications/slowvote/controller/PhabricatorSlowvoteListController.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public function renderResultsList(
5151
->setObjectName('V'.$poll->getID())
5252
->setHeader($poll->getQuestion())
5353
->setHref('/V'.$poll->getID())
54+
->setDisabled($poll->getIsClosed())
5455
->addIcon('none', $date_created);
5556

5657
$description = $poll->getDescription();

src/applications/slowvote/controller/PhabricatorSlowvotePollController.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,13 @@ public function processRequest() {
4141
));
4242
}
4343

44+
$header_icon = $poll->getIsClosed() ? 'oh-closed' : 'open';
45+
$header_name = $poll->getIsClosed() ? pht('Closed') : pht('Open');
46+
4447
$header = id(new PHUIHeaderView())
4548
->setHeader($poll->getQuestion())
4649
->setUser($user)
50+
->setStatus($header_icon, '', $header_name)
4751
->setPolicyObject($poll);
4852

4953
$actions = $this->buildActionView($poll);
@@ -91,6 +95,10 @@ private function buildActionView(PhabricatorSlowvotePoll $poll) {
9195
$poll,
9296
PhabricatorPolicyCapability::CAN_EDIT);
9397

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+
94102
$view->addAction(
95103
id(new PhabricatorActionView())
96104
->setName(pht('Edit Poll'))
@@ -99,6 +107,14 @@ private function buildActionView(PhabricatorSlowvotePoll $poll) {
99107
->setDisabled(!$can_edit)
100108
->setWorkflow(!$can_edit));
101109

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));
117+
102118
return $view;
103119
}
104120

src/applications/slowvote/controller/PhabricatorSlowvoteVoteController.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ public function processRequest() {
2525
if (!$poll) {
2626
return new Aphront404Response();
2727
}
28+
if ($poll->getIsClosed()) {
29+
return new Aphront400Response();
30+
}
2831

2932
$options = $poll->getOptions();
3033
$user_choices = $poll->getViewerChoices($user);

src/applications/slowvote/editor/PhabricatorSlowvoteEditor.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public function getTransactionTypes() {
1313
$types[] = PhabricatorSlowvoteTransaction::TYPE_DESCRIPTION;
1414
$types[] = PhabricatorSlowvoteTransaction::TYPE_RESPONSES;
1515
$types[] = PhabricatorSlowvoteTransaction::TYPE_SHUFFLE;
16+
$types[] = PhabricatorSlowvoteTransaction::TYPE_CLOSE;
1617

1718
return $types;
1819
}
@@ -54,6 +55,8 @@ protected function getCustomTransactionOldValue(
5455
return $object->getResponseVisibility();
5556
case PhabricatorSlowvoteTransaction::TYPE_SHUFFLE:
5657
return $object->getShuffle();
58+
case PhabricatorSlowvoteTransaction::TYPE_CLOSE:
59+
return $object->getIsClosed();
5760
}
5861
}
5962

@@ -66,6 +69,7 @@ protected function getCustomTransactionNewValue(
6669
case PhabricatorSlowvoteTransaction::TYPE_DESCRIPTION:
6770
case PhabricatorSlowvoteTransaction::TYPE_RESPONSES:
6871
case PhabricatorSlowvoteTransaction::TYPE_SHUFFLE:
72+
case PhabricatorSlowvoteTransaction::TYPE_CLOSE:
6973
return $xaction->getNewValue();
7074
}
7175
}
@@ -87,6 +91,9 @@ protected function applyCustomInternalTransaction(
8791
case PhabricatorSlowvoteTransaction::TYPE_SHUFFLE:
8892
$object->setShuffle($xaction->getNewValue());
8993
break;
94+
case PhabricatorSlowvoteTransaction::TYPE_CLOSE:
95+
$object->setIsClosed((int)$xaction->getNewValue());
96+
break;
9097
}
9198
}
9299

src/applications/slowvote/query/PhabricatorSlowvoteQuery.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ final class PhabricatorSlowvoteQuery
1010
private $phids;
1111
private $authorPHIDs;
1212
private $withVotesByViewer;
13+
private $isClosed;
1314

1415
private $needOptions;
1516
private $needChoices;
@@ -35,6 +36,11 @@ public function withVotesByViewer($with_vote) {
3536
return $this;
3637
}
3738

39+
public function withIsClosed($with_closed) {
40+
$this->isClosed = $with_closed;
41+
return $this;
42+
}
43+
3844
public function needOptions($need_options) {
3945
$this->needOptions = $need_options;
4046
return $this;
@@ -146,6 +152,13 @@ private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
146152
$this->authorPHIDs);
147153
}
148154

155+
if ($this->isClosed !== null) {
156+
$where[] = qsprintf(
157+
$conn_r,
158+
'p.isClosed = %d',
159+
(int)$this->isClosed);
160+
}
161+
149162
$where[] = $this->buildPagingClause($conn_r);
150163
return $this->formatWhereClause($where);
151164
}

src/applications/slowvote/query/PhabricatorSlowvoteSearchEngine.php

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public function buildSavedQueryFromRequest(AphrontRequest $request) {
1010
$this->readUsersFromRequest($request, 'authors'));
1111

1212
$saved->setParameter('voted', $request->getBool('voted'));
13+
$saved->setParameter('statuses', $request->getArr('statuses'));
1314

1415
return $saved;
1516
}
@@ -22,6 +23,16 @@ public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
2223
$query->withVotesByViewer(true);
2324
}
2425

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+
2536
return $query;
2637
}
2738

@@ -35,6 +46,7 @@ public function buildSearchForm(
3546
->execute();
3647

3748
$voted = $saved_query->getParameter('voted', false);
49+
$statuses = $saved_query->getParameter('statuses', array());
3850

3951
$form
4052
->appendChild(
@@ -49,7 +61,20 @@ public function buildSearchForm(
4961
'voted',
5062
1,
5163
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)));
5378
}
5479

5580
protected function getURI($path) {
@@ -58,6 +83,7 @@ protected function getURI($path) {
5883

5984
public function getBuiltinQueryNames() {
6085
$names = array(
86+
'open' => pht('Open Polls'),
6187
'all' => pht('All Polls'),
6288
);
6389

@@ -74,6 +100,8 @@ public function buildSavedQueryFromBuiltin($query_key) {
74100
$query->setQueryKey($query_key);
75101

76102
switch ($query_key) {
103+
case 'open':
104+
return $query->setParameter('statuses', array('open'));
77105
case 'all':
78106
return $query;
79107
case 'authored':

0 commit comments

Comments
 (0)