@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 PhabricatorSlowvoteEditController
4 extends PhabricatorSlowvoteController {
5
6 public function handleRequest(AphrontRequest $request) {
7 $viewer = $request->getViewer();
8 $id = $request->getURIData('id');
9
10 if ($id) {
11 $poll = id(new PhabricatorSlowvoteQuery())
12 ->setViewer($viewer)
13 ->withIDs(array($id))
14 ->requireCapabilities(
15 array(
16 PhabricatorPolicyCapability::CAN_VIEW,
17 PhabricatorPolicyCapability::CAN_EDIT,
18 ))
19 ->executeOne();
20 if (!$poll) {
21 return new Aphront404Response();
22 }
23 $is_new = false;
24 } else {
25 $poll = PhabricatorSlowvotePoll::initializeNewPoll($viewer);
26 $is_new = true;
27 }
28
29 if ($is_new) {
30 $v_projects = array();
31 } else {
32 $v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs(
33 $poll->getPHID(),
34 PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
35 $v_projects = array_reverse($v_projects);
36 }
37
38 $e_question = true;
39 $e_response = true;
40 $errors = array();
41
42 $v_question = $poll->getQuestion();
43 $v_description = $poll->getDescription();
44 $v_responses = $poll->getResponseVisibility();
45 $v_shuffle = $poll->getShuffle();
46 $v_space = $poll->getSpacePHID();
47
48 $responses = $request->getArr('response');
49 if ($request->isFormPost()) {
50 $v_question = $request->getStr('question');
51 $v_description = $request->getStr('description');
52 $v_responses = $request->getStr('responses');
53 $v_shuffle = (int)$request->getBool('shuffle');
54 $v_view_policy = $request->getStr('viewPolicy');
55 $v_projects = $request->getArr('projects');
56
57 $v_space = $request->getStr('spacePHID');
58
59 if ($is_new) {
60 $poll->setMethod($request->getStr('method'));
61 }
62
63 if (!strlen($v_question)) {
64 $e_question = pht('Required');
65 $errors[] = pht('You must ask a poll question.');
66 } else {
67 $e_question = null;
68 }
69
70 if ($is_new) {
71 // NOTE: Make sure common and useful response "0" is preserved.
72 foreach ($responses as $key => $response) {
73 if (!strlen($response)) {
74 unset($responses[$key]);
75 }
76 }
77
78 if (empty($responses)) {
79 $errors[] = pht('You must offer at least one response.');
80 $e_response = pht('Required');
81 } else {
82 $e_response = null;
83 }
84 }
85
86 $template = new PhabricatorSlowvoteTransaction();
87 $xactions = array();
88
89 if ($is_new) {
90 $xactions[] = id(new PhabricatorSlowvoteTransaction())
91 ->setTransactionType(PhabricatorTransactions::TYPE_CREATE);
92 }
93
94 $xactions[] = id(clone $template)
95 ->setTransactionType(
96 PhabricatorSlowvoteQuestionTransaction::TRANSACTIONTYPE)
97 ->setNewValue($v_question);
98
99 $xactions[] = id(clone $template)
100 ->setTransactionType(
101 PhabricatorSlowvoteDescriptionTransaction::TRANSACTIONTYPE)
102 ->setNewValue($v_description);
103
104 $xactions[] = id(clone $template)
105 ->setTransactionType(
106 PhabricatorSlowvoteResponsesTransaction::TRANSACTIONTYPE)
107 ->setNewValue($v_responses);
108
109 $xactions[] = id(clone $template)
110 ->setTransactionType(
111 PhabricatorSlowvoteShuffleTransaction::TRANSACTIONTYPE)
112 ->setNewValue($v_shuffle);
113
114 $xactions[] = id(clone $template)
115 ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
116 ->setNewValue($v_view_policy);
117
118 $xactions[] = id(clone $template)
119 ->setTransactionType(PhabricatorTransactions::TYPE_SPACE)
120 ->setNewValue($v_space);
121
122 if (empty($errors)) {
123 $proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
124 $xactions[] = id(new PhabricatorSlowvoteTransaction())
125 ->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
126 ->setMetadataValue('edge:type', $proj_edge_type)
127 ->setNewValue(array('=' => array_fuse($v_projects)));
128
129 $editor = id(new PhabricatorSlowvoteEditor())
130 ->setActor($viewer)
131 ->setContinueOnNoEffect(true)
132 ->setContentSourceFromRequest($request);
133
134 $xactions = $editor->applyTransactions($poll, $xactions);
135
136 if ($is_new) {
137 $poll->save();
138
139 foreach ($responses as $response) {
140 $option = new PhabricatorSlowvoteOption();
141 $option->setName($response);
142 $option->setPollID($poll->getID());
143 $option->save();
144 }
145 }
146
147 return id(new AphrontRedirectResponse())
148 ->setURI($poll->getURI());
149 } else {
150 $poll->setViewPolicy($v_view_policy);
151 }
152 }
153
154 $form = id(new AphrontFormView())
155 ->setAction($request->getrequestURI())
156 ->setViewer($viewer)
157 ->appendChild(
158 id(new AphrontFormTextControl())
159 ->setLabel(pht('Question'))
160 ->setName('question')
161 ->setValue($v_question)
162 ->setError($e_question))
163 ->appendChild(
164 id(new PhabricatorRemarkupControl())
165 ->setViewer($viewer)
166 ->setLabel(pht('Description'))
167 ->setName('description')
168 ->setValue($v_description))
169 ->appendControl(
170 id(new AphrontFormTokenizerControl())
171 ->setLabel(pht('Project Tags'))
172 ->setName('projects')
173 ->setValue($v_projects)
174 ->setDatasource(new PhabricatorProjectDatasource()));
175
176 if ($is_new) {
177 for ($ii = 0; $ii < 10; $ii++) {
178 $n = ($ii + 1);
179 $response = id(new AphrontFormTextControl())
180 ->setLabel(pht('Response %d', $n))
181 ->setName('response[]')
182 ->setValue(idx($responses, $ii, ''));
183
184 if ($ii == 0) {
185 $response->setError($e_response);
186 }
187
188 $form->appendChild($response);
189 }
190 }
191
192 $vote_type_map = SlowvotePollVotingMethod::getAll();
193 $vote_type_options = mpull($vote_type_map, 'getNameForEdit');
194
195 $method = $poll->getMethod();
196 if (!isset($vote_type_options[$method])) {
197 $method_object =
198 SlowvotePollVotingMethod::newVotingMethodObject(
199 $method);
200
201 $vote_type_options = array(
202 $method => $method_object->getNameForEdit(),
203 ) + $vote_type_options;
204 }
205
206 $response_type_map = SlowvotePollResponseVisibility::getAll();
207 $response_type_options = mpull($response_type_map, 'getNameForEdit');
208
209 $visibility = $poll->getResponseVisibility();
210 if (!isset($response_type_options[$visibility])) {
211 $visibility_object =
212 SlowvotePollResponseVisibility::newResponseVisibilityObject(
213 $visibility);
214
215 $response_type_options = array(
216 $visibility => $visibility_object->getNameForEdit(),
217 ) + $response_type_options;
218 }
219
220 if ($is_new) {
221 $form->appendChild(
222 id(new AphrontFormSelectControl())
223 ->setLabel(pht('Vote Type'))
224 ->setName('method')
225 ->setValue($poll->getMethod())
226 ->setOptions($vote_type_options));
227 } else {
228 $form->appendChild(
229 id(new AphrontFormStaticControl())
230 ->setLabel(pht('Vote Type'))
231 ->setValue(idx($vote_type_options, $poll->getMethod())));
232 }
233
234 if ($is_new) {
235 $title = pht('Create Slowvote');
236 $button = pht('Create');
237 $cancel_uri = $this->getApplicationURI();
238 $header_icon = 'fa-plus-square';
239 } else {
240 $title = pht('Edit Poll: %s', $poll->getQuestion());
241 $button = pht('Save Changes');
242 $cancel_uri = '/V'.$poll->getID();
243 $header_icon = 'fa-pencil';
244 }
245
246 $policies = id(new PhabricatorPolicyQuery())
247 ->setViewer($viewer)
248 ->setObject($poll)
249 ->execute();
250
251 $form
252 ->appendChild(
253 id(new AphrontFormSelectControl())
254 ->setLabel(pht('Responses'))
255 ->setName('responses')
256 ->setValue($v_responses)
257 ->setOptions($response_type_options))
258 ->appendChild(
259 id(new AphrontFormCheckboxControl())
260 ->setLabel(pht('Shuffle'))
261 ->addCheckbox(
262 'shuffle',
263 1,
264 pht('Show choices in random order.'),
265 $v_shuffle))
266 ->appendChild(
267 id(new AphrontFormPolicyControl())
268 ->setViewer($viewer)
269 ->setName('viewPolicy')
270 ->setPolicyObject($poll)
271 ->setPolicies($policies)
272 ->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
273 ->setSpacePHID($v_space))
274 ->appendChild(
275 id(new AphrontFormSubmitControl())
276 ->setValue($button)
277 ->addCancelButton($cancel_uri));
278
279 $crumbs = $this->buildApplicationCrumbs();
280 $crumbs->addTextCrumb($title);
281 $crumbs->setBorder(true);
282
283 $form_box = id(new PHUIObjectBoxView())
284 ->setHeaderText($title)
285 ->setFormErrors($errors)
286 ->setBackground(PHUIObjectBoxView::WHITE_CONFIG)
287 ->setForm($form);
288
289 $view = id(new PHUITwoColumnView())
290 ->setFooter($form_box);
291
292 return $this->newPage()
293 ->setTitle($title)
294 ->setCrumbs($crumbs)
295 ->appendChild(
296 array(
297 $view,
298 ));
299 }
300
301}