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

Use CustomFields in `differential.createrevision`

Summary:
Ref T2222. Ref T3886. Medium term goal is to remove `DifferentialRevisionEditor`.

This temporarily reduces a couple of pieces of functionality unique to the RevisionEditor, but I'm going to go clean those up in the next couple diffs.

Test Plan: Used `arc diff --create` to create several revisions with different data.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T3886, T2222

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

+166 -107
+104
src/applications/differential/conduit/ConduitAPI_differential_Method.php
··· 43 43 ); 44 44 } 45 45 46 + protected function applyFieldEdit( 47 + ConduitAPIRequest $request, 48 + DifferentialRevision $revision, 49 + DifferentialDiff $diff, 50 + array $fields, 51 + $message) { 52 + 53 + $viewer = $request->getUser(); 54 + 55 + $field_list = PhabricatorCustomField::getObjectFields( 56 + $revision, 57 + DifferentialCustomField::ROLE_COMMITMESSAGEEDIT); 58 + 59 + $field_list 60 + ->setViewer($viewer) 61 + ->readFieldsFromStorage($revision); 62 + $field_map = mpull($field_list->getFields(), null, 'getFieldKeyForConduit'); 63 + 64 + $xactions = array(); 65 + 66 + $xactions[] = id(new DifferentialTransaction()) 67 + ->setTransactionType(DifferentialTransaction::TYPE_UPDATE) 68 + ->setNewValue($diff->getPHID()); 69 + 70 + $values = $request->getValue('fields', array()); 71 + foreach ($values as $key => $value) { 72 + $field = idx($field_map, $key); 73 + if (!$field) { 74 + // NOTE: We're just ignoring fields we don't know about. This isn't 75 + // ideal, but the way the workflow currently works involves us getting 76 + // several read-only fields, like the revision ID field, which we should 77 + // just skip. 78 + continue; 79 + } 80 + 81 + $role = PhabricatorCustomField::ROLE_APPLICATIONTRANSACTIONS; 82 + if (!$field->shouldEnableForRole($role)) { 83 + throw new Exception( 84 + pht( 85 + 'Request attempts to update field "%s", but that field can not '. 86 + 'perform transactional updates.', 87 + $key)); 88 + } 89 + 90 + // TODO: This is fairly similar to PhabricatorCustomField's 91 + // buildFieldTransactionsFromRequest() method, but that's currently not 92 + // easy to reuse. 93 + 94 + $transaction_type = $field->getApplicationTransactionType(); 95 + $xaction = id(new DifferentialTransaction()) 96 + ->setTransactionType($transaction_type); 97 + 98 + if ($transaction_type == PhabricatorTransactions::TYPE_CUSTOMFIELD) { 99 + // For TYPE_CUSTOMFIELD transactions only, we provide the old value 100 + // as an input. 101 + $old_value = $field->getOldValueForApplicationTransactions(); 102 + $xaction->setOldValue($old_value); 103 + } 104 + 105 + // The transaction itself will be validated so this is somewhat 106 + // redundant, but this validator will sometimes give us a better error 107 + // message or a better reaction to a bad value type. 108 + $field->validateCommitMessageValue($value); 109 + $field->readValueFromCommitMessage($value); 110 + 111 + $xaction 112 + ->setNewValue($field->getNewValueForApplicationTransactions()); 113 + 114 + if ($transaction_type == PhabricatorTransactions::TYPE_CUSTOMFIELD) { 115 + // For TYPE_CUSTOMFIELD transactions, add the field key in metadata. 116 + $xaction->setMetadataValue('customfield:key', $field->getFieldKey()); 117 + } 118 + 119 + $metadata = $field->getApplicationTransactionMetadata(); 120 + foreach ($metadata as $meta_key => $meta_value) { 121 + $xaction->setMetadataValue($meta_key, $meta_value); 122 + } 123 + 124 + $xactions[] = $xaction; 125 + } 126 + 127 + $message = $request->getValue('message'); 128 + if (strlen($message)) { 129 + // This is a little awkward, and should maybe move inside the transaction 130 + // editor. It largely exists for legacy reasons. 131 + $first_line = head(phutil_split_lines($message, false)); 132 + $diff->setDescription($first_line); 133 + $diff->save(); 134 + 135 + $xactions[] = id(new DifferentialTransaction()) 136 + ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) 137 + ->attachComment( 138 + id(new DifferentialTransactionComment()) 139 + ->setContent($message)); 140 + } 141 + 142 + $editor = id(new DifferentialTransactionEditor()) 143 + ->setActor($viewer) 144 + ->setContentSourceFromConduitRequest($request) 145 + ->setContinueOnNoEffect(true) 146 + ->setContinueOnMissingFields(true); 147 + 148 + $editor->applyTransactions($revision, $xactions); 149 + } 46 150 47 151 }
+12 -10
src/applications/differential/conduit/ConduitAPI_differential_createrevision_Method.php
··· 1 1 <?php 2 2 3 - /** 4 - * @group conduit 5 - */ 6 3 final class ConduitAPI_differential_createrevision_Method 7 - extends ConduitAPIMethod { 4 + extends ConduitAPI_differential_Method { 8 5 9 6 public function getMethodDescription() { 10 - return "Create a new Differential revision."; 7 + return pht("Create a new Differential revision."); 11 8 } 12 9 13 10 public function defineParamTypes() { ··· 31 28 } 32 29 33 30 protected function execute(ConduitAPIRequest $request) { 34 - $fields = $request->getValue('fields'); 31 + $viewer = $request->getUser(); 35 32 36 33 $diff = id(new DifferentialDiffQuery()) 37 - ->setViewer($request->getUser()) 34 + ->setViewer($viewer) 38 35 ->withIDs(array($request->getValue('diffid'))) 39 36 ->executeOne(); 40 37 if (!$diff) { 41 38 throw new ConduitException('ERR_BAD_DIFF'); 42 39 } 43 40 44 - $revision = DifferentialRevisionEditor::newRevisionFromConduitWithDiff( 45 - $fields, 41 + $revision = DifferentialRevision::initializeNewRevision($viewer); 42 + $revision->attachReviewerStatus(array()); 43 + 44 + $this->applyFieldEdit( 45 + $request, 46 + $revision, 46 47 $diff, 47 - $request->getUser()); 48 + $request->getValue('fields', array()), 49 + $message = null); 48 50 49 51 return array( 50 52 'revisionid' => $revision->getID(),
+6 -94
src/applications/differential/conduit/ConduitAPI_differential_updaterevision_Method.php
··· 1 1 <?php 2 2 3 3 final class ConduitAPI_differential_updaterevision_Method 4 - extends ConduitAPIMethod { 4 + extends ConduitAPI_differential_Method { 5 5 6 6 public function getMethodDescription() { 7 7 return pht("Update a Differential revision."); ··· 59 59 throw new ConduitException('ERR_CLOSED'); 60 60 } 61 61 62 - $field_list = PhabricatorCustomField::getObjectFields( 62 + $this->applyFieldEdit( 63 + $request, 63 64 $revision, 64 - DifferentialCustomField::ROLE_COMMITMESSAGEEDIT); 65 - 66 - $field_list 67 - ->setViewer($viewer) 68 - ->readFieldsFromStorage($revision); 69 - $field_map = mpull($field_list->getFields(), null, 'getFieldKeyForConduit'); 70 - 71 - $xactions = array(); 72 - 73 - $xactions[] = id(new DifferentialTransaction()) 74 - ->setTransactionType(DifferentialTransaction::TYPE_UPDATE) 75 - ->setNewValue($diff->getPHID()); 76 - 77 - $values = $request->getValue('fields', array()); 78 - foreach ($values as $key => $value) { 79 - $field = idx($field_map, $key); 80 - if (!$field) { 81 - // NOTE: We're just ignoring fields we don't know about. This isn't 82 - // ideal, but the way the workflow currently works involves us getting 83 - // several read-only fields, like the revision ID field, which we should 84 - // just skip. 85 - continue; 86 - } 87 - 88 - $role = PhabricatorCustomField::ROLE_APPLICATIONTRANSACTIONS; 89 - if (!$field->shouldEnableForRole($role)) { 90 - throw new Exception( 91 - pht( 92 - 'Request attempts to update field "%s", but that field can not '. 93 - 'perform transactional updates.', 94 - $key)); 95 - } 96 - 97 - // TODO: This is fairly similar to PhabricatorCustomField's 98 - // buildFieldTransactionsFromRequest() method, but that's currently not 99 - // easy to reuse. 100 - 101 - $transaction_type = $field->getApplicationTransactionType(); 102 - $xaction = id(new DifferentialTransaction()) 103 - ->setTransactionType($transaction_type); 104 - 105 - if ($transaction_type == PhabricatorTransactions::TYPE_CUSTOMFIELD) { 106 - // For TYPE_CUSTOMFIELD transactions only, we provide the old value 107 - // as an input. 108 - $old_value = $field->getOldValueForApplicationTransactions(); 109 - $xaction->setOldValue($old_value); 110 - } 111 - 112 - // The transaction itself will be validated so this is somewhat 113 - // redundant, but this validator will sometimes give us a better error 114 - // message or a better reaction to a bad value type. 115 - $field->validateCommitMessageValue($value); 116 - $field->readValueFromCommitMessage($value); 117 - 118 - $xaction 119 - ->setNewValue($field->getNewValueForApplicationTransactions()); 120 - 121 - if ($transaction_type == PhabricatorTransactions::TYPE_CUSTOMFIELD) { 122 - // For TYPE_CUSTOMFIELD transactions, add the field key in metadata. 123 - $xaction->setMetadataValue('customfield:key', $field->getFieldKey()); 124 - } 125 - 126 - $metadata = $field->getApplicationTransactionMetadata(); 127 - foreach ($metadata as $meta_key => $meta_value) { 128 - $xaction->setMetadataValue($meta_key, $meta_value); 129 - } 130 - 131 - $xactions[] = $xaction; 132 - } 133 - 134 - $message = $request->getValue('message'); 135 - if (strlen($message)) { 136 - // This is a little awkward, and should maybe move inside the transaction 137 - // editor. It largely exists for legacy reasons. 138 - $first_line = head(phutil_split_lines($message, false)); 139 - $diff->setDescription($first_line); 140 - $diff->save(); 141 - 142 - $xactions[] = id(new DifferentialTransaction()) 143 - ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) 144 - ->attachComment( 145 - id(new DifferentialTransactionComment()) 146 - ->setContent($message)); 147 - } 148 - 149 - $editor = id(new DifferentialTransactionEditor()) 150 - ->setActor($viewer) 151 - ->setContentSourceFromConduitRequest($request) 152 - ->setContinueOnNoEffect(true) 153 - ->setContinueOnMissingFields(true); 154 - 155 - $editor->applyTransactions($revision, $xactions); 65 + $diff, 66 + $request->getValue('fields', array()), 67 + $request->getValue('message')); 156 68 157 69 return array( 158 70 'revisionid' => $revision->getID(),
+8
src/applications/differential/customfield/DifferentialSummaryField.php
··· 21 21 22 22 protected function readValueFromRevision( 23 23 DifferentialRevision $revision) { 24 + if (!$revision->getID()) { 25 + return null; 26 + } 24 27 return $revision->getSummary(); 25 28 } 26 29 ··· 80 83 $viewer, 81 84 $xaction->getOldValue(), 82 85 $xaction->getNewValue()); 86 + } 87 + 88 + public function shouldHideInApplicationTransactions( 89 + PhabricatorApplicationTransaction $xaction) { 90 + return ($xaction->getOldValue() === null); 83 91 } 84 92 85 93 public function shouldAppearInGlobalSearch() {
+7
src/applications/differential/customfield/DifferentialTestPlanField.php
··· 21 21 22 22 protected function readValueFromRevision( 23 23 DifferentialRevision $revision) { 24 + if (!$revision->getID()) { 25 + return null; 26 + } 24 27 return $revision->getTestPlan(); 25 28 } 26 29 ··· 96 99 $xaction->getNewValue()); 97 100 } 98 101 102 + public function shouldHideInApplicationTransactions( 103 + PhabricatorApplicationTransaction $xaction) { 104 + return ($xaction->getOldValue() === null); 105 + } 99 106 100 107 public function shouldAppearInGlobalSearch() { 101 108 return true;
+16 -3
src/applications/differential/storage/DifferentialTransaction.php
··· 20 20 } 21 21 22 22 public function shouldHide() { 23 + $old = $this->getOldValue(); 24 + $new = $this->getNewValue(); 25 + 23 26 switch ($this->getTransactionType()) { 27 + case self::TYPE_UPDATE: 28 + // Older versions of this transaction have an ID for the new value, 29 + // and/or do not record the old value. Only hide the transaction if 30 + // the new value is a PHID, indicating that this is a newer style 31 + // transaction. 32 + if ($old === null) { 33 + if (phid_get_type($new) == DifferentialPHIDTypeDiff::TYPECONST) { 34 + return true; 35 + } 36 + } 37 + break; 38 + 24 39 case PhabricatorTransactions::TYPE_EDGE: 25 - $old = $this->getOldValue(); 26 - $new = $this->getNewValue(); 27 40 $add = array_diff_key($new, $old); 28 41 $rem = array_diff_key($old, $new); 29 42 ··· 38 51 break; 39 52 } 40 53 41 - return false; 54 + return parent::shouldHide(); 42 55 } 43 56 44 57 public function shouldHideForMail(array $xactions) {
+5
src/applications/transactions/storage/PhabricatorApplicationTransaction.php
··· 356 356 return false; 357 357 } 358 358 break; 359 + case PhabricatorTransactions::TYPE_CUSTOMFIELD: 360 + $field = $this->getTransactionCustomField(); 361 + if ($field) { 362 + return $field->shouldHideInApplicationTransactions($this); 363 + } 359 364 } 360 365 361 366 return false;
+8
src/infrastructure/customfield/field/PhabricatorCustomField.php
··· 991 991 return array(); 992 992 } 993 993 994 + public function shouldHideInApplicationTransactions( 995 + PhabricatorApplicationTransaction $xaction) { 996 + if ($this->proxy) { 997 + return $this->proxy->shouldHideInApplicationTransactions($xaction); 998 + } 999 + return false; 1000 + } 1001 + 994 1002 995 1003 /* -( Edit View )---------------------------------------------------------- */ 996 1004