@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
at upstream/main 157 lines 4.4 kB view raw
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}