Correct a parameter order swap in "diffusion.historyquery" for Mercurial
[phabricator.git] / src / applications / releeph / controller / request / ReleephRequestEditController.php
blobaf7adc2c8328210243270fb06018e42191a9c914
1 <?php
3 final class ReleephRequestEditController extends ReleephBranchController {
5 public function handleRequest(AphrontRequest $request) {
6 $action = $request->getURIData('action');
7 $request_id = $request->getURIData('requestID');
8 $branch_id = $request->getURIData('branchID');
9 $viewer = $request->getViewer();
11 if ($request_id) {
12 $pull = id(new ReleephRequestQuery())
13 ->setViewer($viewer)
14 ->withIDs(array($request_id))
15 ->requireCapabilities(
16 array(
17 PhabricatorPolicyCapability::CAN_VIEW,
18 PhabricatorPolicyCapability::CAN_EDIT,
20 ->executeOne();
21 if (!$pull) {
22 return new Aphront404Response();
25 $branch = $pull->getBranch();
27 $is_edit = true;
28 } else {
29 $branch = id(new ReleephBranchQuery())
30 ->setViewer($viewer)
31 ->withIDs(array($branch_id))
32 ->executeOne();
33 if (!$branch) {
34 return new Aphront404Response();
37 $pull = id(new ReleephRequest())
38 ->setRequestUserPHID($viewer->getPHID())
39 ->setBranchID($branch->getID())
40 ->setInBranch(0)
41 ->attachBranch($branch);
43 $is_edit = false;
45 $this->setBranch($branch);
47 $product = $branch->getProduct();
49 $request_identifier = $request->getStr('requestIdentifierRaw');
50 $e_request_identifier = true;
52 // Load all the ReleephFieldSpecifications
53 $selector = $branch->getProduct()->getReleephFieldSelector();
54 $fields = $selector->getFieldSpecifications();
55 foreach ($fields as $field) {
56 $field
57 ->setReleephProject($product)
58 ->setReleephBranch($branch)
59 ->setReleephRequest($pull);
62 $field_list = PhabricatorCustomField::getObjectFields(
63 $pull,
64 PhabricatorCustomField::ROLE_EDIT);
65 foreach ($field_list->getFields() as $field) {
66 $field
67 ->setReleephProject($product)
68 ->setReleephBranch($branch)
69 ->setReleephRequest($pull);
71 $field_list->readFieldsFromStorage($pull);
74 if ($branch_id) {
75 $cancel_uri = $this->getApplicationURI('branch/'.$branch_id.'/');
76 } else {
77 $cancel_uri = '/'.$pull->getMonogram();
80 // Make edits
81 $errors = array();
82 if ($request->isFormPost()) {
83 $xactions = array();
85 // The commit-identifier being requested...
86 if (!$is_edit) {
87 if ($request_identifier ===
88 ReleephRequestTypeaheadControl::PLACEHOLDER) {
90 $errors[] = pht('No commit ID was provided.');
91 $e_request_identifier = pht('Required');
92 } else {
93 $pr_commit = null;
94 $finder = id(new ReleephCommitFinder())
95 ->setUser($viewer)
96 ->setReleephProject($product);
97 try {
98 $pr_commit = $finder->fromPartial($request_identifier);
99 } catch (Exception $e) {
100 $e_request_identifier = pht('Invalid');
101 $errors[] = pht(
102 'Request %s is probably not a valid commit.',
103 $request_identifier);
104 $errors[] = $e->getMessage();
107 if (!$errors) {
108 $object_phid = $finder->getRequestedObjectPHID();
109 if (!$object_phid) {
110 $object_phid = $pr_commit->getPHID();
113 $pull->setRequestedObjectPHID($object_phid);
117 if (!$errors) {
118 $existing = id(new ReleephRequest())
119 ->loadOneWhere('requestCommitPHID = %s AND branchID = %d',
120 $pr_commit->getPHID(), $branch->getID());
121 if ($existing) {
122 return id(new AphrontRedirectResponse())
123 ->setURI('/releeph/request/edit/'.$existing->getID().
124 '?existing=1');
127 $xactions[] = id(new ReleephRequestTransaction())
128 ->setTransactionType(ReleephRequestTransaction::TYPE_REQUEST)
129 ->setNewValue($pr_commit->getPHID());
131 $xactions[] = id(new ReleephRequestTransaction())
132 ->setTransactionType(ReleephRequestTransaction::TYPE_USER_INTENT)
133 // To help hide these implicit intents...
134 ->setMetadataValue('isRQCreate', true)
135 ->setMetadataValue('userPHID', $viewer->getPHID())
136 ->setMetadataValue(
137 'isAuthoritative',
138 $product->isAuthoritative($viewer))
139 ->setNewValue(ReleephRequest::INTENT_WANT);
143 // TODO: This should happen implicitly while building transactions
144 // instead.
145 foreach ($field_list->getFields() as $field) {
146 $field->readValueFromRequest($request);
149 if (!$errors) {
150 foreach ($fields as $field) {
151 if ($field->isEditable()) {
152 try {
153 $data = $request->getRequestData();
154 $value = idx($data, $field->getRequiredStorageKey());
155 $field->validate($value);
156 $xactions[] = id(new ReleephRequestTransaction())
157 ->setTransactionType(ReleephRequestTransaction::TYPE_EDIT_FIELD)
158 ->setMetadataValue('fieldClass', get_class($field))
159 ->setNewValue($value);
160 } catch (ReleephFieldParseException $ex) {
161 $errors[] = $ex->getMessage();
167 if (!$errors) {
168 $editor = id(new ReleephRequestTransactionalEditor())
169 ->setActor($viewer)
170 ->setContinueOnNoEffect(true)
171 ->setContentSourceFromRequest($request);
172 $editor->applyTransactions($pull, $xactions);
173 return id(new AphrontRedirectResponse())->setURI($cancel_uri);
177 $handle_phids = array(
178 $pull->getRequestUserPHID(),
179 $pull->getRequestCommitPHID(),
181 $handle_phids = array_filter($handle_phids);
182 if ($handle_phids) {
183 $handles = id(new PhabricatorHandleQuery())
184 ->setViewer($viewer)
185 ->withPHIDs($handle_phids)
186 ->execute();
187 } else {
188 $handles = array();
191 $age_string = '';
192 if ($is_edit) {
193 $age_string = phutil_format_relative_time(
194 time() - $pull->getDateCreated()).' ago';
197 // Warn the user if we've been redirected here because we tried to
198 // re-request something.
199 $notice_view = null;
200 if ($request->getInt('existing')) {
201 $notice_messages = array(
202 pht('You are editing an existing pick request!'),
203 pht(
204 'Requested %s by %s',
205 $age_string,
206 $handles[$pull->getRequestUserPHID()]->renderLink()),
208 $notice_view = id(new PHUIInfoView())
209 ->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
210 ->setErrors($notice_messages);
213 $form = id(new AphrontFormView())
214 ->setUser($viewer);
216 if ($is_edit) {
217 $form
218 ->appendChild(
219 id(new AphrontFormMarkupControl())
220 ->setLabel(pht('Original Commit'))
221 ->setValue(
222 $handles[$pull->getRequestCommitPHID()]->renderLink()))
223 ->appendChild(
224 id(new AphrontFormMarkupControl())
225 ->setLabel(pht('Requestor'))
226 ->setValue(hsprintf(
227 '%s %s',
228 $handles[$pull->getRequestUserPHID()]->renderLink(),
229 $age_string)));
230 } else {
231 $origin = null;
232 $diff_rev_id = $request->getStr('D');
233 if ($diff_rev_id) {
234 $diff_rev = id(new DifferentialRevisionQuery())
235 ->setViewer($viewer)
236 ->withIDs(array($diff_rev_id))
237 ->executeOne();
238 $origin = '/D'.$diff_rev->getID();
239 $title = sprintf(
240 'D%d: %s',
241 $diff_rev_id,
242 $diff_rev->getTitle());
243 $form
244 ->addHiddenInput('requestIdentifierRaw', 'D'.$diff_rev_id)
245 ->appendChild(
246 id(new AphrontFormStaticControl())
247 ->setLabel(pht('Diff'))
248 ->setValue($title));
249 } else {
250 $origin = $branch->getURI();
251 $repo = $product->getRepository();
252 $branch_cut_point = id(new PhabricatorRepositoryCommit())
253 ->loadOneWhere(
254 'phid = %s',
255 $branch->getCutPointCommitPHID());
256 $form->appendChild(
257 id(new ReleephRequestTypeaheadControl())
258 ->setName('requestIdentifierRaw')
259 ->setLabel(pht('Commit ID'))
260 ->setRepo($repo)
261 ->setValue($request_identifier)
262 ->setError($e_request_identifier)
263 ->setStartTime($branch_cut_point->getEpoch())
264 ->setCaption(
265 pht(
266 'Start typing to autocomplete on commit title, '.
267 'or give a Phabricator commit identifier like rFOO1234.')));
271 $field_list->appendFieldsToForm($form);
273 $crumbs = $this->buildApplicationCrumbs();
275 if ($is_edit) {
276 $title = pht('Edit Pull Request');
277 $submit_name = pht('Save');
278 $header_icon = 'fa-pencil';
280 $crumbs->addTextCrumb($pull->getMonogram(), '/'.$pull->getMonogram());
281 $crumbs->addTextCrumb(pht('Edit'));
282 } else {
283 $title = pht('Create Pull Request');
284 $submit_name = pht('Create Pull Request');
285 $header_icon = 'fa-plus-square';
287 $crumbs->addTextCrumb(pht('New Pull Request'));
290 $form->appendChild(
291 id(new AphrontFormSubmitControl())
292 ->addCancelButton($cancel_uri, pht('Cancel'))
293 ->setValue($submit_name));
295 $box = id(new PHUIObjectBoxView())
296 ->setHeaderText(pht('Request'))
297 ->setFormErrors($errors)
298 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
299 ->appendChild($form);
301 $crumbs->setBorder(true);
303 $header = id(new PHUIHeaderView())
304 ->setHeader($title)
305 ->setHeaderIcon($header_icon);
307 $view = id(new PHUITwoColumnView())
308 ->setHeader($header)
309 ->setFooter(array(
310 $notice_view,
311 $box,
314 return $this->newPage()
315 ->setTitle($title)
316 ->setCrumbs($crumbs)
317 ->appendChild($view);