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

Allow the new Differential EditEngine form to create/update diffs for revisions

Summary: Ref T11114. Much of this is around making the "comment-while-updating" flow work correctly.

Test Plan:
- Created new diffs by copy/pasting, then:
- used one to create a new revision;
- used one to update an existing revision, with a comment.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T11114

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

+174 -7
+4
src/__phutil_library_map__.php
··· 2514 2514 'PhabricatorDisabledUserController' => 'applications/auth/controller/PhabricatorDisabledUserController.php', 2515 2515 'PhabricatorDisplayPreferencesSettingsPanel' => 'applications/settings/panel/PhabricatorDisplayPreferencesSettingsPanel.php', 2516 2516 'PhabricatorDisqusAuthProvider' => 'applications/auth/provider/PhabricatorDisqusAuthProvider.php', 2517 + 'PhabricatorDividerEditField' => 'applications/transactions/editfield/PhabricatorDividerEditField.php', 2517 2518 'PhabricatorDividerProfileMenuItem' => 'applications/search/menuitem/PhabricatorDividerProfileMenuItem.php', 2518 2519 'PhabricatorDivinerApplication' => 'applications/diviner/application/PhabricatorDivinerApplication.php', 2519 2520 'PhabricatorDoorkeeperApplication' => 'applications/doorkeeper/application/PhabricatorDoorkeeperApplication.php', ··· 3825 3826 'PhabricatorStreamingProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorStreamingProtocolAdapter.php', 3826 3827 'PhabricatorStringListEditField' => 'applications/transactions/editfield/PhabricatorStringListEditField.php', 3827 3828 'PhabricatorStringSetting' => 'applications/settings/setting/PhabricatorStringSetting.php', 3829 + 'PhabricatorSubmitEditField' => 'applications/transactions/editfield/PhabricatorSubmitEditField.php', 3828 3830 'PhabricatorSubscribableInterface' => 'applications/subscriptions/interface/PhabricatorSubscribableInterface.php', 3829 3831 'PhabricatorSubscribedToObjectEdgeType' => 'applications/transactions/edges/PhabricatorSubscribedToObjectEdgeType.php', 3830 3832 'PhabricatorSubscribersEditField' => 'applications/transactions/editfield/PhabricatorSubscribersEditField.php', ··· 7468 7470 'PhabricatorDisabledUserController' => 'PhabricatorAuthController', 7469 7471 'PhabricatorDisplayPreferencesSettingsPanel' => 'PhabricatorEditEngineSettingsPanel', 7470 7472 'PhabricatorDisqusAuthProvider' => 'PhabricatorOAuth2AuthProvider', 7473 + 'PhabricatorDividerEditField' => 'PhabricatorEditField', 7471 7474 'PhabricatorDividerProfileMenuItem' => 'PhabricatorProfileMenuItem', 7472 7475 'PhabricatorDivinerApplication' => 'PhabricatorApplication', 7473 7476 'PhabricatorDoorkeeperApplication' => 'PhabricatorApplication', ··· 9024 9027 'PhabricatorStreamingProtocolAdapter' => 'PhabricatorProtocolAdapter', 9025 9028 'PhabricatorStringListEditField' => 'PhabricatorEditField', 9026 9029 'PhabricatorStringSetting' => 'PhabricatorSetting', 9030 + 'PhabricatorSubmitEditField' => 'PhabricatorEditField', 9027 9031 'PhabricatorSubscribedToObjectEdgeType' => 'PhabricatorEdgeType', 9028 9032 'PhabricatorSubscribersEditField' => 'PhabricatorTokenizerEditField', 9029 9033 'PhabricatorSubscribersQuery' => 'PhabricatorQuery',
+2
src/applications/differential/application/PhabricatorDifferentialApplication.php
··· 69 69 => 'DifferentialRevisionEditController', 70 70 $this->getEditRoutePattern('editpro/') 71 71 => 'DifferentialRevisionEditProController', 72 + $this->getEditRoutePattern('attach/(?P<diffID>[^/]+)/to/') 73 + => 'DifferentialRevisionEditProController', 72 74 'land/(?:(?P<id>[1-9]\d*))/(?P<strategy>[^/]+)/' 73 75 => 'DifferentialRevisionLandController', 74 76 'closedetails/(?P<phid>[^/]+)/'
+47 -3
src/applications/differential/controller/DifferentialRevisionEditProController.php
··· 4 4 extends DifferentialController { 5 5 6 6 public function handleRequest(AphrontRequest $request) { 7 - return id(new DifferentialRevisionEditEngine()) 8 - ->setController($this) 9 - ->buildResponse(); 7 + $viewer = $this->getViewer(); 8 + 9 + // If we have a Diff ID, this is an "/attach/123/to/456/" action. The 10 + // user just created a diff and is trying to use it to create or update 11 + // a revision. 12 + $diff_id = $request->getURIData('diffID'); 13 + 14 + if ($diff_id) { 15 + $diff = id(new DifferentialDiffQuery()) 16 + ->setViewer($viewer) 17 + ->withIDs(array($diff_id)) 18 + ->executeOne(); 19 + if (!$diff) { 20 + return new Aphront404Response(); 21 + } 22 + 23 + if ($diff->getRevisionID()) { 24 + $revision = $diff->getRevision(); 25 + return $this->newDialog() 26 + ->setTitle(pht('Diff Already Attached')) 27 + ->appendParagraph( 28 + pht( 29 + 'This diff is already attached to a revision.')) 30 + ->addCancelButton($revision->getURI(), pht('Continue')); 31 + } 32 + } else { 33 + $diff = null; 34 + } 35 + 36 + $revision_id = $request->getURIData('id'); 37 + if (!$diff && !$revision_id) { 38 + return $this->newDialog() 39 + ->setTitle(pht('Diff Required')) 40 + ->appendParagraph( 41 + pht( 42 + 'You can not create a revision without a diff.')) 43 + ->addCancelButton($this->getApplicationURI()); 44 + } 45 + 46 + $engine = id(new DifferentialRevisionEditEngine()) 47 + ->setController($this); 48 + 49 + if ($diff) { 50 + $engine->setDiff($diff); 51 + } 52 + 53 + return $engine->buildResponse(); 10 54 } 11 55 12 56 }
+62 -1
src/applications/differential/editor/DifferentialRevisionEditEngine.php
··· 3 3 final class DifferentialRevisionEditEngine 4 4 extends PhabricatorEditEngine { 5 5 6 + private $diff; 7 + 6 8 const ENGINECONST = 'differential.revision'; 7 9 8 10 public function getEngineName() { ··· 33 35 34 36 protected function newObjectQuery() { 35 37 return id(new DifferentialRevisionQuery()) 38 + ->needActiveDiffs(true) 36 39 ->needReviewerStatus(true); 37 40 } 38 41 ··· 41 44 } 42 45 43 46 protected function getObjectEditTitleText($object) { 44 - return pht('Edit Revision: %s', $object->getTitle()); 47 + $monogram = $object->getMonogram(); 48 + $title = $object->getTitle(); 49 + 50 + $diff = $this->getDiff(); 51 + if ($diff) { 52 + return pht('Update Revision %s: %s', $monogram, $title); 53 + } else { 54 + return pht('Edit Revision %s: %s', $monogram, $title); 55 + } 45 56 } 46 57 47 58 protected function getObjectEditShortText($object) { ··· 60 71 return $object->getURI(); 61 72 } 62 73 74 + public function setDiff(DifferentialDiff $diff) { 75 + $this->diff = $diff; 76 + return $this; 77 + } 78 + 79 + public function getDiff() { 80 + return $this->diff; 81 + } 82 + 63 83 protected function buildCustomEditFields($object) { 64 84 65 85 $plan_required = PhabricatorEnv::getEnvConfig( ··· 68 88 $object, 69 89 'differential:test-plan'); 70 90 91 + $diff = $this->getDiff(); 92 + if ($diff) { 93 + $diff_phid = $diff->getPHID(); 94 + } else { 95 + $diff_phid = null; 96 + } 97 + 98 + $is_update = ($diff && $object->getID()); 99 + 71 100 $fields = array(); 101 + 102 + $fields[] = id(new PhabricatorHandlesEditField()) 103 + ->setKey('update') 104 + ->setLabel(pht('Update Diff')) 105 + ->setDescription(pht('New diff to create or update the revision with.')) 106 + ->setConduitDescription(pht('Create or update a revision with a diff.')) 107 + ->setConduitTypeDescription(pht('PHID of the diff.')) 108 + ->setTransactionType(DifferentialTransaction::TYPE_UPDATE) 109 + ->setHandleParameterType(new AphrontPHIDListHTTPParameterType()) 110 + ->setSingleValue($diff_phid) 111 + ->setIsReorderable(false) 112 + ->setIsDefaultable(false) 113 + ->setIsInvisible(true) 114 + ->setIsLockable(false); 115 + 116 + if ($is_update) { 117 + $fields[] = id(new PhabricatorInstructionsEditField()) 118 + ->setKey('update.help') 119 + ->setValue(pht('Describe the updates you have made to the diff.')); 120 + $fields[] = id(new PhabricatorCommentEditField()) 121 + ->setKey('update.comment') 122 + ->setLabel(pht('Comment')) 123 + ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) 124 + ->setIsWebOnly(true) 125 + ->setDescription(pht('Comments providing context for the update.')); 126 + $fields[] = id(new PhabricatorSubmitEditField()) 127 + ->setKey('update.submit') 128 + ->setValue($this->getObjectEditButtonText($object)); 129 + $fields[] = id(new PhabricatorDividerEditField()) 130 + ->setKey('update.note'); 131 + } 132 + 72 133 $fields[] = id(new PhabricatorTextEditField()) 73 134 ->setKey('title') 74 135 ->setLabel(pht('Title'))
+22 -3
src/applications/transactions/editfield/PhabricatorCommentEditField.php
··· 3 3 final class PhabricatorCommentEditField 4 4 extends PhabricatorEditField { 5 5 6 + private $isWebOnly; 7 + 8 + public function setIsWebOnly($is_web_only) { 9 + $this->isWebOnly = $is_web_only; 10 + return $this; 11 + } 12 + 13 + public function getIsWebOnly() { 14 + return $this->isWebOnly; 15 + } 16 + 6 17 protected function newControl() { 7 18 return new PhabricatorRemarkupControl(); 8 19 } ··· 12 23 } 13 24 14 25 protected function newConduitParameterType() { 15 - return new ConduitStringParameterType(); 26 + if ($this->getIsWebOnly()) { 27 + return null; 28 + } else { 29 + return new ConduitStringParameterType(); 30 + } 16 31 } 17 32 18 33 public function shouldGenerateTransactionsFromSubmit() { 19 - return false; 34 + return !$this->isPrimaryCommentField(); 20 35 } 21 36 22 37 public function shouldGenerateTransactionsFromComment() { 23 - return true; 38 + return $this->isPrimaryCommentField(); 39 + } 40 + 41 + private function isPrimaryCommentField() { 42 + return ($this->getKey() === 'comment'); 24 43 } 25 44 26 45 }
+18
src/applications/transactions/editfield/PhabricatorDividerEditField.php
··· 1 + <?php 2 + 3 + final class PhabricatorDividerEditField 4 + extends PhabricatorEditField { 5 + 6 + protected function renderControl() { 7 + return new AphrontFormDividerControl(); 8 + } 9 + 10 + protected function newHTTPParameterType() { 11 + return null; 12 + } 13 + 14 + protected function newConduitParameterType() { 15 + return null; 16 + } 17 + 18 + }
+19
src/applications/transactions/editfield/PhabricatorSubmitEditField.php
··· 1 + <?php 2 + 3 + final class PhabricatorSubmitEditField 4 + extends PhabricatorEditField { 5 + 6 + protected function renderControl() { 7 + return id(new AphrontFormSubmitControl()) 8 + ->setValue($this->getValue()); 9 + } 10 + 11 + protected function newHTTPParameterType() { 12 + return null; 13 + } 14 + 15 + protected function newConduitParameterType() { 16 + return null; 17 + } 18 + 19 + }