@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 DifferentialRevisionOperationController
4 extends DifferentialController {
5
6 public function handleRequest(AphrontRequest $request) {
7 $viewer = $this->getViewer();
8 $id = $request->getURIData('id');
9
10 $revision = id(new DifferentialRevisionQuery())
11 ->withIDs(array($id))
12 ->setViewer($viewer)
13 ->needActiveDiffs(true)
14 ->executeOne();
15 if (!$revision) {
16 return new Aphront404Response();
17 }
18
19 $detail_uri = "/D{$id}";
20
21 $op = new DrydockLandRepositoryOperation();
22 $barrier = $op->getBarrierToLanding($viewer, $revision);
23 if ($barrier) {
24 return $this->newDialog()
25 ->setTitle($barrier['title'])
26 ->appendParagraph($barrier['body'])
27 ->addCancelButton($detail_uri);
28 }
29
30 $diff = $revision->getActiveDiff();
31 $repository = $revision->getRepository();
32
33 $default_ref = $this->loadDefaultRef($repository, $diff);
34
35 if ($default_ref) {
36 $v_ref = array($default_ref->getPHID());
37 } else {
38 $v_ref = array();
39 }
40
41 $e_ref = true;
42
43 $errors = array();
44 if ($request->isFormPost()) {
45
46 $v_ref = $request->getArr('refPHIDs');
47 $ref_phid = head($v_ref);
48 if (!strlen($ref_phid)) {
49 $e_ref = pht('Required');
50 $errors[] = pht(
51 'You must select a branch to land this revision onto.');
52 } else {
53 $ref = $this->newRefQuery($repository)
54 ->withPHIDs(array($ref_phid))
55 ->executeOne();
56 if (!$ref) {
57 $e_ref = pht('Invalid');
58 $errors[] = pht(
59 'You must select a branch from this repository to land this '.
60 'revision onto.');
61 }
62 }
63
64 if (!$errors) {
65 // NOTE: The operation is locked to the current active diff, so if the
66 // revision is updated before the operation applies nothing sneaky
67 // occurs.
68
69 $target = 'branch:'.$ref->getRefName();
70
71 $operation = DrydockRepositoryOperation::initializeNewOperation($op)
72 ->setAuthorPHID($viewer->getPHID())
73 ->setObjectPHID($revision->getPHID())
74 ->setRepositoryPHID($repository->getPHID())
75 ->setRepositoryTarget($target)
76 ->setProperty('differential.diffPHID', $diff->getPHID());
77
78 $operation->save();
79 $operation->scheduleUpdate();
80
81 return id(new AphrontRedirectResponse())
82 ->setURI($detail_uri);
83 }
84 }
85
86 $ref_datasource = id(new DiffusionRefDatasource())
87 ->setParameters(
88 array(
89 'repositoryPHIDs' => array($repository->getPHID()),
90 'refTypes' => $this->getTargetableRefTypes(),
91 ));
92
93 $form = id(new AphrontFormView())
94 ->setUser($viewer)
95 ->appendRemarkupInstructions(
96 pht(
97 '(NOTE) This feature is new and experimental.'))
98 ->appendControl(
99 id(new AphrontFormTokenizerControl())
100 ->setLabel(pht('Onto Branch'))
101 ->setName('refPHIDs')
102 ->setLimit(1)
103 ->setError($e_ref)
104 ->setValue($v_ref)
105 ->setDatasource($ref_datasource));
106
107 return $this->newDialog()
108 ->setWidth(AphrontDialogView::WIDTH_FORM)
109 ->setTitle(pht('Land Revision'))
110 ->setErrors($errors)
111 ->appendForm($form)
112 ->addCancelButton($detail_uri)
113 ->addSubmitButton(pht('Land Revision'));
114 }
115
116 private function newRefQuery(PhabricatorRepository $repository) {
117 $viewer = $this->getViewer();
118
119 return id(new PhabricatorRepositoryRefCursorQuery())
120 ->setViewer($viewer)
121 ->withRepositoryPHIDs(array($repository->getPHID()))
122 ->withRefTypes($this->getTargetableRefTypes());
123 }
124
125 private function getTargetableRefTypes() {
126 return array(
127 PhabricatorRepositoryRefCursor::TYPE_BRANCH,
128 );
129 }
130
131 private function loadDefaultRef(
132 PhabricatorRepository $repository,
133 DifferentialDiff $diff) {
134 $default_name = $this->getDefaultRefName($repository, $diff);
135
136 if (!strlen($default_name)) {
137 return null;
138 }
139
140 return $this->newRefQuery($repository)
141 ->withRefNames(array($default_name))
142 ->executeOne();
143 }
144
145 private function getDefaultRefName(
146 PhabricatorRepository $repository,
147 DifferentialDiff $diff) {
148
149 $onto = $diff->loadTargetBranch();
150 if ($onto !== null) {
151 return $onto;
152 }
153
154 return $repository->getDefaultBranch();
155 }
156
157}