@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
fork

Configure Feed

Select the types of activity you want to include in your feed.

Remove ReleephProjectController

Summary:
Ref T3657. General changes here:

- Removes `ReleephProjectController`, which is the source of T3657.
- Mostly moves requests from "RQ" as a monogram to "Y" (looks like a merge, mnemonic for "yank"?, we don't have too many characters left). This should be essentially only cosmetic. This reduces ambiguity with "rQ" and "R123", which are current and future repository monograms. This will continue in the next few diffs.
- Makes requests implement policies correctly.

Test Plan: Created, edited, browsed requests.

Reviewers: chad, btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T3657

Differential Revision: https://secure.phabricator.com/D8766

+273 -386
+6 -6
resources/celerity/map.php
··· 98 98 'rsrc/css/application/releeph/releeph-branch.css' => 'b8821d2d', 99 99 'rsrc/css/application/releeph/releeph-colors.css' => '2d2d6aa8', 100 100 'rsrc/css/application/releeph/releeph-core.css' => '140b959d', 101 - 'rsrc/css/application/releeph/releeph-intents.css' => '7364ac97', 102 - 'rsrc/css/application/releeph/releeph-preview-branch.css' => '0e383ca3', 101 + 'rsrc/css/application/releeph/releeph-intents.css' => '39065521', 102 + 'rsrc/css/application/releeph/releeph-preview-branch.css' => 'b7a6f4a5', 103 103 'rsrc/css/application/releeph/releeph-project.css' => 'ee1f9f57', 104 104 'rsrc/css/application/releeph/releeph-request-differential-create-dialog.css' => '8d8b92cd', 105 105 'rsrc/css/application/releeph/releeph-request-typeahead.css' => '667a48ae', 106 - 'rsrc/css/application/releeph/releeph-status.css' => 'a20631d9', 106 + 'rsrc/css/application/releeph/releeph-status.css' => 'd119a005', 107 107 'rsrc/css/application/search/search-results.css' => 'f240504c', 108 108 'rsrc/css/application/settings/settings.css' => 'ea8f5915', 109 109 'rsrc/css/application/slowvote/slowvote.css' => '266df6a1', ··· 777 777 'releeph-branch' => 'b8821d2d', 778 778 'releeph-colors' => '2d2d6aa8', 779 779 'releeph-core' => '140b959d', 780 - 'releeph-intents' => '7364ac97', 781 - 'releeph-preview-branch' => '0e383ca3', 780 + 'releeph-intents' => '39065521', 781 + 'releeph-preview-branch' => 'b7a6f4a5', 782 782 'releeph-project' => 'ee1f9f57', 783 783 'releeph-request-differential-create-dialog' => '8d8b92cd', 784 784 'releeph-request-typeahead-css' => '667a48ae', 785 - 'releeph-status' => 'a20631d9', 785 + 'releeph-status' => 'd119a005', 786 786 'setup-issue-css' => '69e640e7', 787 787 'sprite-actions-css' => '969ad0e5', 788 788 'sprite-apps-css' => '6973a52b',
+8 -8
src/__phutil_library_map__.php
··· 2542 2542 'ReleephProductTransactionQuery' => 'applications/releeph/query/ReleephProductTransactionQuery.php', 2543 2543 'ReleephProductViewController' => 'applications/releeph/controller/project/ReleephProductViewController.php', 2544 2544 'ReleephProject' => 'applications/releeph/storage/ReleephProject.php', 2545 - 'ReleephProjectController' => 'applications/releeph/controller/ReleephProjectController.php', 2546 2545 'ReleephProjectQuery' => 'applications/releeph/query/ReleephProjectQuery.php', 2547 2546 'ReleephReasonFieldSpecification' => 'applications/releeph/field/specification/ReleephReasonFieldSpecification.php', 2548 2547 'ReleephRequest' => 'applications/releeph/storage/ReleephRequest.php', 2549 2548 'ReleephRequestActionController' => 'applications/releeph/controller/request/ReleephRequestActionController.php', 2550 2549 'ReleephRequestCommentController' => 'applications/releeph/controller/request/ReleephRequestCommentController.php', 2550 + 'ReleephRequestController' => 'applications/releeph/controller/request/ReleephRequestController.php', 2551 2551 'ReleephRequestDifferentialCreateController' => 'applications/releeph/controller/request/ReleephRequestDifferentialCreateController.php', 2552 2552 'ReleephRequestEditController' => 'applications/releeph/controller/request/ReleephRequestEditController.php', 2553 2553 'ReleephRequestHeaderListView' => 'applications/releeph/view/request/header/ReleephRequestHeaderListView.php', ··· 5527 5527 'ReleephPHIDTypeRequest' => 'PhabricatorPHIDType', 5528 5528 'ReleephProductActionController' => 'ReleephProductController', 5529 5529 'ReleephProductController' => 'ReleephController', 5530 - 'ReleephProductCreateController' => 'ReleephProjectController', 5530 + 'ReleephProductCreateController' => 'ReleephProductController', 5531 5531 'ReleephProductEditController' => 'ReleephProductController', 5532 5532 'ReleephProductEditor' => 'PhabricatorApplicationTransactionEditor', 5533 5533 'ReleephProductHistoryController' => 'ReleephProductController', ··· 5549 5549 0 => 'ReleephDAO', 5550 5550 1 => 'PhabricatorPolicyInterface', 5551 5551 ), 5552 - 'ReleephProjectController' => 'ReleephController', 5553 5552 'ReleephProjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 5554 5553 'ReleephReasonFieldSpecification' => 'ReleephFieldSpecification', 5555 5554 'ReleephRequest' => ··· 5558 5557 1 => 'PhabricatorPolicyInterface', 5559 5558 2 => 'PhabricatorCustomFieldInterface', 5560 5559 ), 5561 - 'ReleephRequestActionController' => 'ReleephProjectController', 5562 - 'ReleephRequestCommentController' => 'ReleephProjectController', 5563 - 'ReleephRequestDifferentialCreateController' => 'ReleephProjectController', 5564 - 'ReleephRequestEditController' => 'ReleephProjectController', 5560 + 'ReleephRequestActionController' => 'ReleephRequestController', 5561 + 'ReleephRequestCommentController' => 'ReleephRequestController', 5562 + 'ReleephRequestController' => 'ReleephController', 5563 + 'ReleephRequestDifferentialCreateController' => 'ReleephController', 5564 + 'ReleephRequestEditController' => 'ReleephBranchController', 5565 5565 'ReleephRequestHeaderListView' => 'AphrontView', 5566 5566 'ReleephRequestHeaderView' => 'AphrontView', 5567 5567 'ReleephRequestIntentsView' => 'AphrontView', ··· 5576 5576 'ReleephRequestTransactionalEditor' => 'PhabricatorApplicationTransactionEditor', 5577 5577 'ReleephRequestTypeaheadControl' => 'AphrontFormControl', 5578 5578 'ReleephRequestTypeaheadController' => 'PhabricatorTypeaheadDatasourceController', 5579 - 'ReleephRequestViewController' => 'ReleephProjectController', 5579 + 'ReleephRequestViewController' => 'ReleephBranchController', 5580 5580 'ReleephRequestorFieldSpecification' => 'ReleephFieldSpecification', 5581 5581 'ReleephRevisionFieldSpecification' => 'ReleephFieldSpecification', 5582 5582 'ReleephSeverityFieldSpecification' => 'ReleephLevelFieldSpecification',
+10 -9
src/applications/releeph/application/PhabricatorApplicationReleeph.php
··· 31 31 32 32 public function getRoutes() { 33 33 return array( 34 + '/Y(?P<requestID>[1-9]\d*)' => 'ReleephRequestViewController', 35 + 36 + // TODO: Remove these older routes eventually. 34 37 '/RQ(?P<requestID>[1-9]\d*)' => 'ReleephRequestViewController', 38 + '/releeph/request/(?P<requestID>[1-9]\d*)/' 39 + => 'ReleephRequestViewController', 40 + 35 41 '/releeph/' => array( 36 42 '' => 'ReleephProductListController', 37 43 'project/' => array( ··· 45 51 'history/' => 'ReleephProductHistoryController', 46 52 ), 47 53 ), 54 + 48 55 'branch/' => array( 49 56 'edit/(?P<branchID>[1-9]\d*)/' => 50 57 'ReleephBranchEditController', ··· 55 62 'history/' => 'ReleephBranchHistoryController', 56 63 '(?:query/(?P<queryKey>[^/]+)/)?' => 'ReleephBranchViewController', 57 64 ), 65 + 'pull/(?P<branchID>[1-9]\d*)/' => 66 + 'ReleephRequestEditController', 58 67 ), 68 + 59 69 'request/' => array( 60 - '(?P<requestID>[1-9]\d*)/' => 'ReleephRequestViewController', 61 70 'create/' => 'ReleephRequestEditController', 62 71 'differentialcreate/' => array( 63 72 'D(?P<diffRevID>[1-9]\d*)' => ··· 71 80 'ReleephRequestTypeaheadController', 72 81 'comment/(?P<requestID>[1-9]\d*)/' => 73 82 'ReleephRequestCommentController', 74 - ), 75 - 76 - // Branch navigation made pretty, as it's the most common: 77 - '(?P<projectName>[^/]+)/(?P<branchName>[^/]+)/' => array( 78 - '(?:query/(?P<queryKey>[^/]+)/)?' => 'ReleephBranchViewController', 79 - 'edit/' => 'ReleephBranchEditController', 80 - 'request/' => 'ReleephRequestEditController', 81 - '(?P<action>close|re-open)/' => 'ReleephBranchAccessController', 82 83 ), 83 84 ) 84 85 );
-155
src/applications/releeph/controller/ReleephProjectController.php
··· 1 - <?php 2 - 3 - abstract class ReleephProjectController extends ReleephController { 4 - 5 - private $releephProject; 6 - private $releephBranch; 7 - private $releephRequest; 8 - 9 - /** 10 - * ReleephController will take care of loading any Releeph* objects 11 - * referenced in the URL. 12 - */ 13 - public function willProcessRequest(array $data) { 14 - $viewer = $this->getRequest()->getUser(); 15 - 16 - // Project 17 - $project = null; 18 - $project_id = idx($data, 'projectID'); 19 - $project_name = idx($data, 'projectName'); 20 - if ($project_id) { 21 - $project = id(new ReleephProjectQuery()) 22 - ->setViewer($viewer) 23 - ->withIDs(array($project_id)) 24 - ->executeOne(); 25 - if (!$project) { 26 - throw new Exception( 27 - "ReleephProject with id '{$project_id}' not found!"); 28 - } 29 - } elseif ($project_name) { 30 - $project = id(new ReleephProject()) 31 - ->loadOneWhere('name = %s', $project_name); 32 - if (!$project) { 33 - throw new Exception( 34 - "ReleephProject with name '{$project_name}' not found!"); 35 - } 36 - } 37 - 38 - // Branch 39 - $branch = null; 40 - $branch_id = idx($data, 'branchID'); 41 - $branch_name = idx($data, 'branchName'); 42 - if ($branch_id) { 43 - $branch = id(new ReleephBranchQuery()) 44 - ->setViewer($viewer) 45 - ->withIDs(array($branch_id)) 46 - ->executeOne(); 47 - if (!$branch) { 48 - throw new Exception("Branch with id '{$branch_id}' not found!"); 49 - } 50 - } elseif ($branch_name) { 51 - if (!$project) { 52 - throw new Exception( 53 - "You cannot refer to a branch by name without also referring ". 54 - "to a ReleephProject (branch names are only unique in projects)."); 55 - } 56 - $branch = id(new ReleephBranch())->loadOneWhere( 57 - 'basename = %s AND releephProjectID = %d', 58 - $branch_name, 59 - $project->getID()); 60 - if (!$branch) { 61 - throw new Exception( 62 - "ReleephBranch with basename '{$branch_name}' not found ". 63 - "in project '{$project->getName()}'!"); 64 - } 65 - // Do the branch query again, properly, to hit policies and load attached 66 - // data. 67 - // TODO: Clean this up with T3657. 68 - $branch = id(new ReleephBranchQuery()) 69 - ->setViewer($viewer) 70 - ->withIDs(array($branch->getID())) 71 - ->executeOne(); 72 - if (!$branch) { 73 - throw new Exception('404!'); 74 - } 75 - } 76 - 77 - // Request 78 - $request = null; 79 - $request_id = idx($data, 'requestID'); 80 - if ($request_id) { 81 - $request = id(new ReleephRequest())->load($request_id); 82 - if (!$request) { 83 - throw new Exception( 84 - "ReleephRequest with id '{$request_id}' not found!"); 85 - } 86 - } 87 - 88 - // Fill in the gaps 89 - if ($request && !$branch) { 90 - $branch = $request->loadReleephBranch(); 91 - } 92 - 93 - if ($branch && !$project) { 94 - $project = $branch->loadReleephProject(); 95 - } 96 - 97 - // Set! 98 - $this->releephProject = $project; 99 - $this->releephBranch = $branch; 100 - $this->releephRequest = $request; 101 - } 102 - 103 - protected function getReleephProject() { 104 - if (!$this->releephProject) { 105 - throw new Exception( 106 - 'This controller did not load a ReleephProject from the URL $data.'); 107 - } 108 - return $this->releephProject; 109 - } 110 - 111 - protected function getReleephBranch() { 112 - if (!$this->releephBranch) { 113 - throw new Exception( 114 - 'This controller did not load a ReleephBranch from the URL $data.'); 115 - } 116 - return $this->releephBranch; 117 - } 118 - 119 - protected function getReleephRequest() { 120 - if (!$this->releephRequest) { 121 - throw new Exception( 122 - 'This controller did not load a ReleephRequest from the URL $data.'); 123 - } 124 - return $this->releephRequest; 125 - } 126 - 127 - protected function buildApplicationCrumbs() { 128 - $crumbs = parent::buildApplicationCrumbs(); 129 - 130 - // TODO: The massive amount of derps here should be fixed once URIs get 131 - // sorted out; see T3657. 132 - 133 - try { 134 - $project = $this->getReleephProject(); 135 - $project_id = $project->getID(); 136 - $project_uri = $this->getApplicationURI("project/{$project_id}/"); 137 - 138 - $crumbs->addTextCrumb($project->getName(), $project_uri); 139 - } catch (Exception $ex) { 140 - // TODO: This is derps. 141 - } 142 - 143 - try { 144 - $branch = $this->getReleephBranch(); 145 - $branch_uri = $branch->getURI(); 146 - $crumbs->addTextCrumb($branch->getDisplayNameWithDetail(), $branch_uri); 147 - } catch (Exception $ex) { 148 - // TODO: This is also derps. 149 - } 150 - 151 - return $crumbs; 152 - } 153 - 154 - 155 - }
+2 -3
src/applications/releeph/controller/branch/ReleephBranchViewController.php
··· 52 52 $requests); 53 53 54 54 $list = id(new ReleephRequestHeaderListView()) 55 - ->setOriginType('branch') 56 55 ->setUser($viewer) 57 56 ->setAphrontRequest($this->getRequest()) 58 57 ->setReleephProject($branch->getProduct()) ··· 87 86 $crumbs = parent::buildApplicationCrumbs(); 88 87 89 88 $branch = $this->getBranch(); 90 - $create_uri = $branch->getURI('request/'); 89 + 91 90 $crumbs->addAction( 92 91 id(new PHUIListItemView()) 93 - ->setHref($create_uri) 92 + ->setHref($this->getApplicationURI('branch/pull/'.$branch->getID().'/')) 94 93 ->setName(pht('New Pull Request')) 95 94 ->setIcon('create') 96 95 ->setDisabled(!$branch->isActive()));
+1 -1
src/applications/releeph/controller/project/ReleephProductCreateController.php
··· 1 1 <?php 2 2 3 - final class ReleephProductCreateController extends ReleephProjectController { 3 + final class ReleephProductCreateController extends ReleephProductController { 4 4 5 5 public function processRequest() { 6 6 $request = $this->getRequest();
+32 -26
src/applications/releeph/controller/request/ReleephRequestActionController.php
··· 1 1 <?php 2 2 3 - final class ReleephRequestActionController extends ReleephProjectController { 3 + final class ReleephRequestActionController 4 + extends ReleephRequestController { 4 5 5 6 private $action; 7 + private $requestID; 6 8 7 9 public function willProcessRequest(array $data) { 8 - parent::willProcessRequest($data); 9 10 $this->action = $data['action']; 11 + $this->requestID = $data['requestID']; 10 12 } 11 13 12 14 public function processRequest() { 13 15 $request = $this->getRequest(); 16 + $viewer = $request->getUser(); 17 + 18 + $pull = id(new ReleephRequestQuery()) 19 + ->setViewer($viewer) 20 + ->withIDs(array($this->requestID)) 21 + ->executeOne(); 22 + if (!$pull) { 23 + return new Aphront404Response(); 24 + } 14 25 15 - $releeph_project = $this->getReleephProject(); 16 - $releeph_branch = $this->getReleephBranch(); 17 - $releeph_request = $this->getReleephRequest(); 26 + $branch = $pull->getBranch(); 27 + $product = $branch->getProduct(); 18 28 19 - $releeph_branch->populateReleephRequestHandles( 20 - $request->getUser(), array($releeph_request)); 29 + $branch->populateReleephRequestHandles($viewer, array($pull)); 21 30 22 31 $action = $this->action; 23 32 24 - $user = $request->getUser(); 25 - 26 - $origin_uri = $releeph_request->loadReleephBranch()->getURI(); 33 + $origin_uri = '/'.$pull->getMonogram(); 27 34 28 35 $editor = id(new ReleephRequestTransactionalEditor()) 29 - ->setActor($user) 36 + ->setActor($viewer) 30 37 ->setContinueOnNoEffect(true) 31 38 ->setContentSourceFromRequest($request); 32 39 ··· 43 50 ->setTransactionType(ReleephRequestTransaction::TYPE_USER_INTENT) 44 51 ->setMetadataValue( 45 52 'isAuthoritative', 46 - $releeph_project->isAuthoritative($user)) 53 + $product->isAuthoritative($viewer)) 47 54 ->setNewValue($intent); 48 55 break; 49 56 50 57 case 'mark-manually-picked': 51 58 case 'mark-manually-reverted': 52 59 if ( 53 - $releeph_request->getRequestUserPHID() === $user->getPHID() || 54 - $releeph_project->isAuthoritative($user)) { 60 + $pull->getRequestUserPHID() === $viewer->getPHID() || 61 + $product->isAuthoritative($viewer)) { 55 62 56 63 // We're all good! 57 64 } else { ··· 84 91 throw new Exception("unknown or unimplemented action {$action}"); 85 92 } 86 93 87 - $editor->applyTransactions($releeph_request, $xactions); 94 + $editor->applyTransactions($pull, $xactions); 88 95 89 96 // If we're adding a new user to userIntents, we'll have to re-populate 90 97 // request handles to load that user's data. 91 98 // 92 99 // This is cheap enough to do every time. 93 - $this->getReleephBranch()->populateReleephRequestHandles( 94 - $user, array($releeph_request)); 100 + $branch->populateReleephRequestHandles($viewer, array($pull)); 95 101 96 102 $list = id(new ReleephRequestHeaderListView()) 97 - ->setReleephProject($this->getReleephProject()) 98 - ->setReleephBranch($this->getReleephBranch()) 99 - ->setReleephRequests(array($releeph_request)) 100 - ->setUser($request->getUser()) 101 - ->setAphrontRequest($this->getRequest()) 102 - ->setOriginType('request'); 103 + ->setReleephProject($product) 104 + ->setReleephBranch($branch) 105 + ->setReleephRequests(array($pull)) 106 + ->setUser($viewer) 107 + ->setAphrontRequest($request); 103 108 104 - return id(new AphrontAjaxResponse())->setContent(array( 105 - 'markup' => head($list->renderInner()) 106 - )); 109 + return id(new AphrontAjaxResponse())->setContent( 110 + array( 111 + 'markup' => hsprintf('%s', $list->renderInner()), 112 + )); 107 113 } 108 114 }
+20 -8
src/applications/releeph/controller/request/ReleephRequestCommentController.php
··· 1 1 <?php 2 2 3 3 final class ReleephRequestCommentController 4 - extends ReleephProjectController { 4 + extends ReleephRequestController { 5 + 6 + private $requestID; 7 + 8 + public function willProcessRequest(array $data) { 9 + $this->requestID = $data['requestID']; 10 + } 5 11 6 12 public function processRequest() { 7 13 $request = $this->getRequest(); 8 - $user = $request->getUser(); 9 - 10 - $rq = $this->getReleephRequest(); 14 + $viewer = $request->getUser(); 11 15 12 16 if (!$request->isFormPost()) { 13 17 return new Aphront400Response(); 14 18 } 15 19 20 + $pull = id(new ReleephRequestQuery()) 21 + ->setViewer($viewer) 22 + ->withIDs(array($this->requestID)) 23 + ->executeOne(); 24 + if (!$pull) { 25 + return new Aphront404Response(); 26 + } 27 + 16 28 $is_preview = $request->isPreviewRequest(); 17 29 $draft = PhabricatorDraft::buildFromRequest($request); 18 30 19 - $view_uri = $this->getApplicationURI('/RQ'.$rq->getID()); 31 + $view_uri = $this->getApplicationURI('/'.$pull->getMonogram()); 20 32 21 33 $xactions = array(); 22 34 $xactions[] = id(new ReleephRequestTransaction()) ··· 26 38 ->setContent($request->getStr('comment'))); 27 39 28 40 $editor = id(new ReleephRequestTransactionalEditor()) 29 - ->setActor($user) 41 + ->setActor($viewer) 30 42 ->setContinueOnNoEffect($request->isContinueRequest()) 31 43 ->setContentSourceFromRequest($request) 32 44 ->setIsPreview($is_preview); 33 45 34 46 try { 35 - $xactions = $editor->applyTransactions($rq, $xactions); 47 + $xactions = $editor->applyTransactions($pull, $xactions); 36 48 } catch (PhabricatorApplicationTransactionNoEffectException $ex) { 37 49 return id(new PhabricatorApplicationTransactionNoEffectResponse()) 38 50 ->setCancelURI($view_uri) ··· 45 57 46 58 if ($request->isAjax()) { 47 59 return id(new PhabricatorApplicationTransactionResponse()) 48 - ->setViewer($user) 60 + ->setViewer($viewer) 49 61 ->setTransactions($xactions) 50 62 ->setIsPreview($is_preview) 51 63 ->setAnchorOffset($request->getStr('anchor'));
+5
src/applications/releeph/controller/request/ReleephRequestController.php
··· 1 + <?php 2 + 3 + abstract class ReleephRequestController extends ReleephController { 4 + 5 + }
+3 -1
src/applications/releeph/controller/request/ReleephRequestDifferentialCreateController.php
··· 1 1 <?php 2 2 3 + // TODO: After T2222, this is likely unreachable? 4 + 3 5 final class ReleephRequestDifferentialCreateController 4 - extends ReleephProjectController { 6 + extends ReleephController { 5 7 6 8 private $revisionID; 7 9 private $revision;
+81 -79
src/applications/releeph/controller/request/ReleephRequestEditController.php
··· 1 1 <?php 2 2 3 - final class ReleephRequestEditController extends ReleephProjectController { 3 + final class ReleephRequestEditController extends ReleephBranchController { 4 4 5 - private $id; 5 + private $requestID; 6 + private $branchID; 6 7 7 8 public function willProcessRequest(array $data) { 8 - $this->id = idx($data, 'requestID'); 9 - parent::willProcessRequest($data); 9 + $this->requestID = idx($data, 'requestID'); 10 + $this->branchID = idx($data, 'branchID'); 10 11 } 11 12 12 13 public function processRequest() { 13 14 $request = $this->getRequest(); 14 - $user = $request->getUser(); 15 - 16 - $releeph_project = $this->getReleephProject(); 17 - $releeph_branch = $this->getReleephBranch(); 18 - 19 - $request_identifier = $request->getStr('requestIdentifierRaw'); 20 - $e_request_identifier = true; 15 + $viewer = $request->getUser(); 21 16 22 - // Load the RQ we're editing, or create a new one 23 - if ($this->id) { 24 - $rq = id(new ReleephRequestQuery()) 25 - ->setViewer($user) 26 - ->withIDs(array($this->id)) 17 + if ($this->requestID) { 18 + $pull = id(new ReleephRequestQuery()) 19 + ->setViewer($viewer) 20 + ->withIDs(array($this->requestID)) 27 21 ->requireCapabilities( 28 22 array( 29 23 PhabricatorPolicyCapability::CAN_VIEW, 30 24 PhabricatorPolicyCapability::CAN_EDIT, 31 25 )) 32 26 ->executeOne(); 27 + if (!$pull) { 28 + return new Aphront404Response(); 29 + } 30 + 31 + $branch = $pull->getBranch(); 32 + 33 33 $is_edit = true; 34 34 } else { 35 - $is_edit = false; 36 - $rq = id(new ReleephRequest()) 37 - ->setRequestUserPHID($user->getPHID()) 38 - ->setBranchID($releeph_branch->getID()) 35 + $branch = id(new ReleephBranchQuery()) 36 + ->setViewer($viewer) 37 + ->withIDs(array($this->branchID)) 38 + ->executeOne(); 39 + if (!$branch) { 40 + return new Aphront404Response(); 41 + } 42 + 43 + $pull = id(new ReleephRequest()) 44 + ->setRequestUserPHID($viewer->getPHID()) 45 + ->setBranchID($branch->getID()) 39 46 ->setInBranch(0); 47 + 48 + $is_edit = false; 40 49 } 50 + $this->setBranch($branch); 51 + 52 + $product = $branch->getProduct(); 53 + 54 + $request_identifier = $request->getStr('requestIdentifierRaw'); 55 + $e_request_identifier = true; 41 56 42 57 // Load all the ReleephFieldSpecifications 43 - $selector = $this->getReleephProject()->getReleephFieldSelector(); 58 + $selector = $branch->getProduct()->getReleephFieldSelector(); 44 59 $fields = $selector->getFieldSpecifications(); 45 60 foreach ($fields as $field) { 46 61 $field 47 - ->setReleephProject($releeph_project) 48 - ->setReleephBranch($releeph_branch) 49 - ->setReleephRequest($rq); 62 + ->setReleephProject($product) 63 + ->setReleephBranch($branch) 64 + ->setReleephRequest($pull); 50 65 } 51 66 52 67 $field_list = PhabricatorCustomField::getObjectFields( 53 - $rq, 68 + $pull, 54 69 PhabricatorCustomField::ROLE_EDIT); 55 70 foreach ($field_list->getFields() as $field) { 56 71 $field 57 - ->setReleephProject($releeph_project) 58 - ->setReleephBranch($releeph_branch) 59 - ->setReleephRequest($rq); 72 + ->setReleephProject($product) 73 + ->setReleephBranch($branch) 74 + ->setReleephRequest($pull); 60 75 } 61 - $field_list->readFieldsFromStorage($rq); 76 + $field_list->readFieldsFromStorage($pull); 62 77 63 78 64 - // <aidehua> epriestley: Is it common to pass around a referer URL to 65 - // return from whence one came? [...] 66 - // <epriestley> If you only have two places, maybe consider some parameter 67 - // rather than the full URL. 68 - switch ($request->getStr('origin')) { 69 - case 'request': 70 - $origin_uri = '/RQ'.$rq->getID(); 71 - break; 72 - 73 - case 'branch': 74 - default: 75 - $origin_uri = $releeph_branch->getURI(); 76 - break; 79 + if ($this->branchID) { 80 + $cancel_uri = $this->getApplicationURI('branch/'.$this->branchID.'/'); 81 + } else { 82 + $cancel_uri = '/'.$pull->getMonogram(); 77 83 } 78 84 79 85 // Make edits ··· 91 97 } else { 92 98 $pr_commit = null; 93 99 $finder = id(new ReleephCommitFinder()) 94 - ->setUser($user) 95 - ->setReleephProject($releeph_project); 100 + ->setUser($viewer) 101 + ->setReleephProject($product); 96 102 try { 97 103 $pr_commit = $finder->fromPartial($request_identifier); 98 104 } catch (Exception $e) { ··· 115 121 if (!$errors) { 116 122 $existing = id(new ReleephRequest()) 117 123 ->loadOneWhere('requestCommitPHID = %s AND branchID = %d', 118 - $pr_commit->getPHID(), $releeph_branch->getID()); 124 + $pr_commit->getPHID(), $branch->getID()); 119 125 if ($existing) { 120 126 return id(new AphrontRedirectResponse()) 121 127 ->setURI('/releeph/request/edit/'.$existing->getID(). ··· 130 136 ->setTransactionType(ReleephRequestTransaction::TYPE_USER_INTENT) 131 137 // To help hide these implicit intents... 132 138 ->setMetadataValue('isRQCreate', true) 133 - ->setMetadataValue('userPHID', $user->getPHID()) 139 + ->setMetadataValue('userPHID', $viewer->getPHID()) 134 140 ->setMetadataValue( 135 141 'isAuthoritative', 136 - $releeph_project->isAuthoritative($user)) 142 + $product->isAuthoritative($viewer)) 137 143 ->setNewValue(ReleephRequest::INTENT_WANT); 138 144 } 139 145 } ··· 164 170 165 171 if (!$errors) { 166 172 $editor = id(new ReleephRequestTransactionalEditor()) 167 - ->setActor($user) 173 + ->setActor($viewer) 168 174 ->setContinueOnNoEffect(true) 169 175 ->setContentSourceFromRequest($request); 170 - $editor->applyTransactions($rq, $xactions); 171 - return id(new AphrontRedirectResponse())->setURI($origin_uri); 176 + $editor->applyTransactions($pull, $xactions); 177 + return id(new AphrontRedirectResponse())->setURI($cancel_uri); 172 178 } 173 179 } 174 180 175 - $releeph_branch->populateReleephRequestHandles($user, array($rq)); 176 - $handles = $rq->getHandles(); 181 + $branch->populateReleephRequestHandles($viewer, array($pull)); 182 + $handles = $pull->getHandles(); 177 183 178 184 $age_string = ''; 179 185 if ($is_edit) { 180 186 $age_string = phabricator_format_relative_time( 181 - time() - $rq->getDateCreated()) . ' ago'; 187 + time() - $pull->getDateCreated()) . ' ago'; 182 188 } 183 189 184 190 // Warn the user if we've been redirected here because we tried to ··· 190 196 hsprintf( 191 197 "Requested %s by %s", 192 198 $age_string, 193 - $handles[$rq->getRequestUserPHID()]->renderLink()) 199 + $handles[$pull->getRequestUserPHID()]->renderLink()) 194 200 ); 195 201 $notice_view = id(new AphrontErrorView()) 196 202 ->setSeverity(AphrontErrorView::SEVERITY_NOTICE) 197 203 ->setErrors($notice_messages); 198 204 } 199 205 200 - /** 201 - * Build the rest of the page 202 - */ 203 - $error_view = null; 204 - if ($errors) { 205 - $error_view = new AphrontErrorView(); 206 - $error_view->setErrors($errors); 207 - } 208 - 209 206 $form = id(new AphrontFormView()) 210 - ->setUser($user); 207 + ->setUser($viewer); 211 208 212 209 if ($is_edit) { 213 210 $form ··· 215 212 id(new AphrontFormMarkupControl()) 216 213 ->setLabel('Original Commit') 217 214 ->setValue( 218 - $handles[$rq->getRequestCommitPHID()]->renderLink())) 215 + $handles[$pull->getRequestCommitPHID()]->renderLink())) 219 216 ->appendChild( 220 217 id(new AphrontFormMarkupControl()) 221 218 ->setLabel('Requestor') 222 219 ->setValue(hsprintf( 223 220 '%s %s', 224 - $handles[$rq->getRequestUserPHID()]->renderLink(), 221 + $handles[$pull->getRequestUserPHID()]->renderLink(), 225 222 $age_string))); 226 223 } else { 227 224 $origin = null; 228 225 $diff_rev_id = $request->getStr('D'); 229 226 if ($diff_rev_id) { 230 227 $diff_rev = id(new DifferentialRevisionQuery()) 231 - ->setViewer($user) 228 + ->setViewer($viewer) 232 229 ->withIDs(array($diff_rev_id)) 233 230 ->executeOne(); 234 231 $origin = '/D'.$diff_rev->getID(); ··· 243 240 ->setLabel('Diff') 244 241 ->setValue($title)); 245 242 } else { 246 - $origin = $releeph_branch->getURI(); 247 - $repo = $releeph_project->loadPhabricatorRepository(); 243 + $origin = $branch->getURI(); 244 + $repo = $product->loadPhabricatorRepository(); 248 245 $branch_cut_point = id(new PhabricatorRepositoryCommit()) 249 246 ->loadOneWhere( 250 247 'phid = %s', 251 - $releeph_branch->getCutPointCommitPHID()); 248 + $branch->getCutPointCommitPHID()); 252 249 $form->appendChild( 253 250 id(new ReleephRequestTypeaheadControl()) 254 251 ->setName('requestIdentifierRaw') ··· 268 265 $crumbs = $this->buildApplicationCrumbs(); 269 266 270 267 if ($is_edit) { 271 - $title = pht('Edit Releeph Request'); 268 + $title = pht('Edit Pull Request'); 272 269 $submit_name = pht('Save'); 273 270 274 - $crumbs->addTextCrumb('RQ'.$rq->getID(), '/RQ'.$rq->getID()); 271 + $crumbs->addTextCrumb($pull->getMonogram(), '/'.$pull->getMonogram()); 275 272 $crumbs->addTextCrumb(pht('Edit')); 276 - 277 273 } else { 278 - $title = pht('Create Releeph Request'); 279 - $submit_name = pht('Create'); 280 - $crumbs->addTextCrumb(pht('New Request')); 274 + $title = pht('Create Pull Request'); 275 + $submit_name = pht('Create Pull Request'); 276 + 277 + $crumbs->addTextCrumb(pht('New Pull Request')); 281 278 } 282 279 283 280 $form->appendChild( 284 281 id(new AphrontFormSubmitControl()) 285 - ->addCancelButton($origin_uri, 'Cancel') 282 + ->addCancelButton($cancel_uri, 'Cancel') 286 283 ->setValue($submit_name)); 287 284 285 + $box = id(new PHUIObjectBoxView()) 286 + ->setHeaderText($title) 287 + ->setFormErrors($errors) 288 + ->appendChild($form); 289 + 288 290 return $this->buildApplicationPage( 289 291 array( 290 292 $crumbs, 291 293 $notice_view, 292 - $error_view, 293 - $form, 294 + $box, 294 295 ), 295 296 array( 296 297 'title' => $title, 298 + 'device' => true, 297 299 )); 298 300 } 299 301 }
+57 -59
src/applications/releeph/controller/request/ReleephRequestViewController.php
··· 1 1 <?php 2 2 3 - final class ReleephRequestViewController extends ReleephProjectController { 3 + final class ReleephRequestViewController 4 + extends ReleephBranchController { 5 + 6 + private $requestID; 7 + 8 + public function willProcessRequest(array $data) { 9 + $this->requestID = $data['requestID']; 10 + } 4 11 5 12 public function processRequest() { 6 13 $request = $this->getRequest(); 14 + $viewer = $request->getUser(); 7 15 8 - $uri_path = $request->getRequestURI()->getPath(); 9 - $legacy_prefix = '/releeph/request/'; 10 - if (strncmp($uri_path, $legacy_prefix, strlen($legacy_prefix)) === 0) { 11 - return id(new AphrontRedirectResponse()) 12 - ->setURI('/RQ'.$this->getReleephRequest()->getID()); 16 + $pull = id(new ReleephRequestQuery()) 17 + ->setViewer($viewer) 18 + ->withIDs(array($this->requestID)) 19 + ->executeOne(); 20 + if (!$pull) { 21 + return new Aphront404Response(); 13 22 } 23 + $this->setBranch($pull->getBranch()); 14 24 15 - $releeph_request = $this->getReleephRequest(); 16 - $releeph_branch = $this->getReleephBranch(); 17 - $releeph_project = $this->getReleephProject(); 25 + // Redirect older URIs to new "Y" URIs. 26 + // TODO: Get rid of this eventually. 27 + $actual_path = $request->getRequestURI()->getPath(); 28 + $expect_path = '/'.$pull->getMonogram(); 29 + if ($actual_path != $expect_path) { 30 + return id(new AphrontRedirectResponse())->setURI($expect_path); 31 + } 18 32 19 - $releeph_branch->populateReleephRequestHandles( 20 - $request->getUser(), array($releeph_request)); 33 + // TODO: Break this 1:1 stuff? 34 + $branch = $pull->getBranch(); 21 35 22 - $rq_view = 23 - id(new ReleephRequestHeaderListView()) 24 - ->setReleephProject($releeph_project) 25 - ->setReleephBranch($releeph_branch) 26 - ->setReleephRequests(array($releeph_request)) 27 - ->setUser($request->getUser()) 28 - ->setAphrontRequest($this->getRequest()) 29 - ->setReloadOnStateChange(true) 30 - ->setOriginType('request'); 36 + // TODO: Very gross. 37 + $branch->populateReleephRequestHandles( 38 + $viewer, 39 + array($pull)); 31 40 32 - $user = $request->getUser(); 41 + $rq_view = id(new ReleephRequestHeaderListView()) 42 + ->setReleephProject($branch->getProduct()) 43 + ->setReleephBranch($branch) 44 + ->setReleephRequests(array($pull)) 45 + ->setUser($viewer) 46 + ->setAphrontRequest($request) 47 + ->setReloadOnStateChange(true); 33 48 34 49 $engine = id(new PhabricatorMarkupEngine()) 35 - ->setViewer($user); 50 + ->setViewer($viewer); 36 51 37 52 $xactions = id(new ReleephRequestTransactionQuery()) 38 - ->setViewer($user) 39 - ->withObjectPHIDs(array($releeph_request->getPHID())) 53 + ->setViewer($viewer) 54 + ->withObjectPHIDs(array($pull->getPHID())) 40 55 ->execute(); 41 56 42 - foreach ($xactions as $xaction) { 43 - if ($xaction->getComment()) { 44 - $engine->addObject( 45 - $xaction->getComment(), 46 - PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); 47 - } 48 - } 49 - $engine->process(); 50 - 51 57 $timeline = id(new PhabricatorApplicationTransactionView()) 52 58 ->setUser($request->getUser()) 53 - ->setObjectPHID($releeph_request->getPHID()) 54 - ->setTransactions($xactions) 55 - ->setMarkupEngine($engine); 59 + ->setObjectPHID($pull->getPHID()) 60 + ->setTransactions($xactions); 56 61 57 - $add_comment_header = pht('Plea or yield'); 62 + $add_comment_header = pht('Plea or Yield'); 58 63 59 64 $draft = PhabricatorDraft::newFromUserAndKey( 60 - $user, 61 - $releeph_request->getPHID()); 65 + $viewer, 66 + $pull->getPHID()); 62 67 63 - $title = hsprintf("RQ%d: %s", 64 - $releeph_request->getID(), 65 - $releeph_request->getSummaryForDisplay()); 68 + $title = hsprintf( 69 + "%s %s", 70 + $pull->getMonogram(), 71 + $pull->getSummaryForDisplay()); 66 72 67 73 $add_comment_form = id(new PhabricatorApplicationTransactionCommentView()) 68 - ->setUser($user) 69 - ->setObjectPHID($releeph_request->getPHID()) 74 + ->setUser($viewer) 75 + ->setObjectPHID($pull->getPHID()) 70 76 ->setDraft($draft) 71 77 ->setHeaderText($add_comment_header) 72 78 ->setAction($this->getApplicationURI( 73 - '/request/comment/'.$releeph_request->getID().'/')) 74 - ->setSubmitButtonName('Comment'); 79 + '/request/comment/'.$pull->getID().'/')) 80 + ->setSubmitButtonName(pht('Comment')); 75 81 76 - $crumbs = $this->buildApplicationCrumbs() 77 - ->addTextCrumb($releeph_project->getName(), $releeph_project->getURI()) 78 - ->addTextCrumb( 79 - $releeph_branch->getDisplayNameWithDetail(), 80 - $releeph_branch->getURI()) 81 - ->addTextCrumb( 82 - 'RQ'.$releeph_request->getID(), 83 - '/RQ'.$releeph_request->getID()); 82 + $crumbs = $this->buildApplicationCrumbs(); 83 + $crumbs->addTextCrumb($pull->getMonogram(), '/'.$pull->getMonogram()); 84 84 85 85 return $this->buildStandardPageResponse( 86 86 array( 87 87 $crumbs, 88 - array( 89 - $rq_view, 90 - $timeline, 91 - $add_comment_form, 92 - ) 88 + $rq_view, 89 + $timeline, 90 + $add_comment_form, 93 91 ), 94 92 array( 95 93 'title' => $title
+15
src/applications/releeph/query/ReleephRequestQuery.php
··· 118 118 } 119 119 } 120 120 121 + $branch_ids = array_unique(mpull($requests, 'getBranchID')); 122 + $branches = id(new ReleephBranchQuery()) 123 + ->withIDs($branch_ids) 124 + ->setViewer($this->getViewer()) 125 + ->execute(); 126 + $branches = mpull($branches, null, 'getID'); 127 + foreach ($requests as $key => $request) { 128 + $branch = idx($branches, $request->getBranchID()); 129 + if (!$branch) { 130 + unset($requests[$key]); 131 + continue; 132 + } 133 + $request->attachBranch($branch); 134 + } 135 + 121 136 return $requests; 122 137 } 123 138
+6 -4
src/applications/releeph/storage/ReleephBranch.php
··· 181 181 182 182 183 183 public function getCapabilities() { 184 - return $this->getProject()->getCapabilities(); 184 + return $this->getProduct()->getCapabilities(); 185 185 } 186 186 187 187 public function getPolicy($capability) { 188 - return $this->getProject()->getPolicy($capability); 188 + return $this->getProduct()->getPolicy($capability); 189 189 } 190 190 191 191 public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { 192 - return $this->getProject()->hasAutomaticCapability($capability, $viewer); 192 + return $this->getProduct()->hasAutomaticCapability($capability, $viewer); 193 193 } 194 194 195 195 public function describeAutomaticCapability($capability) { 196 - return null; 196 + return pht( 197 + 'Release branches have the same policies as the product they are a '. 198 + 'part of.'); 197 199 } 198 200 199 201
+20 -3
src/applications/releeph/storage/ReleephRequest.php
··· 22 22 23 23 // Pre-populated handles that we'll bulk load in ReleephBranch 24 24 private $handles = self::ATTACHABLE; 25 + 25 26 private $customFields = self::ATTACHABLE; 27 + private $branch = self::ATTACHABLE; 26 28 27 29 28 30 ··· 87 89 88 90 public function getStatus() { 89 91 return $this->calculateStatus(); 92 + } 93 + 94 + public function getMonogram() { 95 + return 'Y'.$this->getID(); 96 + } 97 + 98 + public function getBranch() { 99 + return $this->assertAttached($this->branch); 100 + } 101 + 102 + public function attachBranch(ReleephBranch $branch) { 103 + $this->branch = $branch; 104 + return $this; 90 105 } 91 106 92 107 private function calculateStatus() { ··· 305 320 } 306 321 307 322 public function getPolicy($capability) { 308 - return PhabricatorPolicies::POLICY_USER; 323 + return $this->getBranch()->getPolicy($capability); 309 324 } 310 325 311 326 public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { 312 - return false; 327 + return $this->getBranch()->hasAutomaticCapability($capability, $viewer); 313 328 } 314 329 315 330 public function describeAutomaticCapability($capability) { 316 - return null; 331 + return pht( 332 + 'Pull requests have the same policies as the branches they are '. 333 + 'requested against.'); 317 334 } 318 335 319 336
-7
src/applications/releeph/view/request/header/ReleephRequestHeaderListView.php
··· 3 3 final class ReleephRequestHeaderListView 4 4 extends AphrontView { 5 5 6 - private $originType; 7 6 private $releephProject; 8 7 private $releephBranch; 9 8 private $releephRequests; ··· 11 10 private $reload = false; 12 11 13 12 private $errors = array(); 14 - 15 - public function setOriginType($origin) { 16 - $this->originType = $origin; 17 - return $this; 18 - } 19 13 20 14 public function setReleephProject(ReleephProject $rp) { 21 15 $this->releephProject = $rp; ··· 113 107 $views[] = id(new ReleephRequestHeaderView()) 114 108 ->setUser($this->user) 115 109 ->setAphrontRequest($this->aphrontRequest) 116 - ->setOriginType($this->originType) 117 110 ->setReleephProject($this->releephProject) 118 111 ->setReleephBranch($this->releephBranch) 119 112 ->setReleephRequest($releeph_request)
+1 -13
src/applications/releeph/view/request/header/ReleephRequestHeaderView.php
··· 8 8 private $releephRequest; 9 9 private $releephBranch; 10 10 private $releephProject; 11 - private $originType; 12 11 private $fieldGroups; 13 12 14 13 public function setAphrontRequest(AphrontRequest $request) { ··· 31 30 return $this; 32 31 } 33 32 34 - public function setOriginType($origin) { 35 - // For the Edit controller 36 - $this->originType = $origin; 37 - return $this; 38 - } 39 - 40 33 public function setReleephFieldGroups(array $field_groups) { 41 34 $this->fieldGroups = $field_groups; 42 35 return $this; 43 - } 44 - 45 - protected function getOrigin() { 46 - return $this->originType; 47 36 } 48 37 49 38 public function render() { ··· 262 251 $right_buttons[] = phutil_tag( 263 252 'a', 264 253 array( 265 - 'href' => '/releeph/request/edit/'.$this->releephRequest->getID(). 266 - '?origin='.$this->originType, 254 + 'href' => '/releeph/request/edit/'.$this->releephRequest->getID().'/', 267 255 'class' => 'small blue button', 268 256 ), 269 257 'Edit');
+2 -2
webroot/rsrc/css/application/releeph/releeph-intents.css
··· 17 17 } 18 18 19 19 .releeph-intents .arrow.want { 20 - background-image: url('/rsrc/custom/image/icon/tango/go-next.png'); 20 + /* TODO: Icon. */ 21 21 } 22 22 23 23 .releeph-intents .arrow.pass { 24 - background-image: url('/rsrc/custom/image/icon/tango/go-previous-gray.png'); 24 + /* TODO: Icon. */ 25 25 } 26 26 27 27 .releeph-intents a {
+2 -1
webroot/rsrc/css/application/releeph/releeph-preview-branch.css
··· 11 11 padding-left: 22px; 12 12 background-repeat: no-repeat; 13 13 background-size: 16px auto; 14 - background-image: url(/rsrc/custom/image/releeph/releeph_warning.png); 15 14 float: left; 16 15 position: absolute; 17 16 top: 2.5em; 17 + 18 + /* TODO: This had a background that's still at Facebook? */ 18 19 } 19 20 20 21 .releeph-preview-branch .name {
+2 -1
webroot/rsrc/css/application/releeph/releeph-status.css
··· 22 22 padding-left: 22px; 23 23 background-repeat: no-repeat; 24 24 background-size: 16px auto; 25 - background-image: url(/rsrc/custom/image/releeph/releeph_warning.png); 25 + 26 + /* TODO: This had a background that's still at Facebook? */ 26 27 }