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

Implement a "Reviewers" CustomField

Summary:
Ref T3886:

- Adds a "Reviewers" field as a modern CustomField.

Ref T418:

- Allows CustomFields to emit transaction metadata.

Test Plan: {F116254}

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T418, T3886

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

+165 -18
+2
src/__phutil_library_map__.php
··· 441 441 'DifferentialReviewedByFieldSpecification' => 'applications/differential/field/specification/DifferentialReviewedByFieldSpecification.php', 442 442 'DifferentialReviewer' => 'applications/differential/storage/DifferentialReviewer.php', 443 443 'DifferentialReviewerStatus' => 'applications/differential/constants/DifferentialReviewerStatus.php', 444 + 'DifferentialReviewersField' => 'applications/differential/customfield/DifferentialReviewersField.php', 444 445 'DifferentialReviewersFieldSpecification' => 'applications/differential/field/specification/DifferentialReviewersFieldSpecification.php', 445 446 'DifferentialReviewersView' => 'applications/differential/view/DifferentialReviewersView.php', 446 447 'DifferentialRevision' => 'applications/differential/storage/DifferentialRevision.php', ··· 2979 2980 'DifferentialRevertPlanFieldSpecification' => 'DifferentialFieldSpecification', 2980 2981 'DifferentialReviewRequestMail' => 'DifferentialMail', 2981 2982 'DifferentialReviewedByFieldSpecification' => 'DifferentialFieldSpecification', 2983 + 'DifferentialReviewersField' => 'DifferentialCoreCustomField', 2982 2984 'DifferentialReviewersFieldSpecification' => 'DifferentialFieldSpecification', 2983 2985 'DifferentialReviewersView' => 'AphrontView', 2984 2986 'DifferentialRevision' =>
+84
src/applications/differential/customfield/DifferentialReviewersField.php
··· 1 + <?php 2 + 3 + final class DifferentialReviewersField 4 + extends DifferentialCoreCustomField { 5 + 6 + public function getFieldKey() { 7 + return 'differential:reviewers'; 8 + } 9 + 10 + public function getFieldName() { 11 + return pht('Reviewers'); 12 + } 13 + 14 + public function getFieldDescription() { 15 + return pht('Manage reviewers.'); 16 + } 17 + 18 + protected function readValueFromRevision( 19 + DifferentialRevision $revision) { 20 + return $revision->getReviewerStatus(); 21 + } 22 + 23 + public function getNewValueForApplicationTransactions() { 24 + $specs = array(); 25 + foreach ($this->getValue() as $reviewer) { 26 + $specs[$reviewer->getReviewerPHID()] = array( 27 + 'data' => $reviewer->getEdgeData(), 28 + ); 29 + } 30 + 31 + return array('=' => $specs); 32 + } 33 + 34 + public function readValueFromRequest(AphrontRequest $request) { 35 + // Compute a new set of reviewer objects. For reviewers who haven't been 36 + // added or removed, retain their existing status. Also, respect the new 37 + // order. 38 + 39 + $old_status = $this->getValue(); 40 + $old_status = mpull($old_status, null, 'getReviewerPHID'); 41 + 42 + $new_phids = $request->getArr($this->getFieldKey()); 43 + $new_phids = array_fuse($new_phids); 44 + 45 + $new_status = array(); 46 + foreach ($new_phids as $new_phid) { 47 + if (empty($old_status[$new_phid])) { 48 + $new_status[$new_phid] = new DifferentialReviewer( 49 + $new_phid, 50 + array( 51 + 'status' => DifferentialReviewerStatus::STATUS_ADDED, 52 + )); 53 + } else { 54 + $new_status[$new_phid] = $old_status[$new_phid]; 55 + } 56 + } 57 + 58 + $this->setValue($new_status); 59 + } 60 + 61 + public function getRequiredHandlePHIDsForEdit() { 62 + return mpull($this->getValue(), 'getReviewerPHID'); 63 + } 64 + 65 + public function renderEditControl(array $handles) { 66 + return id(new AphrontFormTokenizerControl()) 67 + ->setName($this->getFieldKey()) 68 + ->setDatasource('/typeahead/common/usersorprojects/') 69 + ->setValue($handles) 70 + ->setError($this->getFieldError()) 71 + ->setLabel($this->getFieldName()); 72 + } 73 + 74 + public function getApplicationTransactionType() { 75 + return PhabricatorTransactions::TYPE_EDGE; 76 + } 77 + 78 + public function getApplicationTransactionMetadata() { 79 + return array( 80 + 'edge:type' => PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER, 81 + ); 82 + } 83 + 84 + }
+5 -2
src/applications/differential/editor/DifferentialTransactionEditor.php
··· 6 6 public function getTransactionTypes() { 7 7 $types = parent::getTransactionTypes(); 8 8 9 + $types[] = PhabricatorTransactions::TYPE_EDGE; 9 10 $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; 10 11 $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; 11 12 12 13 /* 13 - $types[] = PhabricatorTransactions::TYPE_EDGE; 14 14 15 15 $types[] = DifferentialTransaction::TYPE_INLINE; 16 16 $types[] = DifferentialTransaction::TYPE_UPDATE; ··· 59 59 $object->setEditPolicy($xaction->getNewValue()); 60 60 return; 61 61 case PhabricatorTransactions::TYPE_SUBSCRIBERS: 62 + case PhabricatorTransactions::TYPE_EDGE: 63 + // TODO: When removing reviewers, we may be able to move the revision 64 + // to "Accepted". 62 65 return; 63 66 } 64 67 ··· 74 77 case PhabricatorTransactions::TYPE_EDIT_POLICY: 75 78 return; 76 79 case PhabricatorTransactions::TYPE_SUBSCRIBERS: 80 + case PhabricatorTransactions::TYPE_EDGE: 77 81 return; 78 82 } 79 83 ··· 92 96 93 97 return $errors; 94 98 } 95 - 96 99 97 100 protected function requireCapabilities( 98 101 PhabricatorLiskDAO $object,
+7
src/applications/differential/storage/DifferentialReviewer.php
··· 46 46 return $this->authority[$viewer_phid]; 47 47 } 48 48 49 + public function getEdgeData() { 50 + return array( 51 + 'status' => $this->status, 52 + 'diffID' => $this->diffID, 53 + ); 54 + } 55 + 49 56 }
+1
src/applications/differential/storage/DifferentialRevision.php
··· 469 469 new DifferentialTitleField(), 470 470 new DifferentialSummaryField(), 471 471 new DifferentialTestPlanField(), 472 + new DifferentialReviewersField(), 472 473 new DifferentialSubscribersField(), 473 474 new DifferentialRepositoryField(), 474 475 new DifferentialViewPolicyField(),
+38 -9
src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
··· 990 990 } 991 991 $result[$dst_phid] = $this->normalizeEdgeTransactionValue( 992 992 $xaction, 993 - $edge); 993 + $edge, 994 + $dst_phid); 994 995 } 995 996 996 997 if ($new_set !== null) { 997 998 foreach ($new_set as $dst_phid => $edge) { 998 999 $result[$dst_phid] = $this->normalizeEdgeTransactionValue( 999 1000 $xaction, 1000 - $edge); 1001 + $edge, 1002 + $dst_phid); 1001 1003 } 1002 1004 } 1003 1005 1004 1006 foreach ($new_add as $dst_phid => $edge) { 1005 1007 $result[$dst_phid] = $this->normalizeEdgeTransactionValue( 1006 1008 $xaction, 1007 - $edge); 1009 + $edge, 1010 + $dst_phid); 1008 1011 } 1009 1012 1010 1013 foreach ($new_rem as $dst_phid => $edge) { ··· 1032 1035 } 1033 1036 } 1034 1037 1035 - protected function normalizeEdgeTransactionValue( 1038 + private function normalizeEdgeTransactionValue( 1036 1039 PhabricatorApplicationTransaction $xaction, 1037 - $edge) { 1040 + $edge, 1041 + $dst_phid) { 1038 1042 1039 1043 if (!is_array($edge)) { 1040 - $edge = array( 1041 - 'dst' => $edge, 1042 - ); 1044 + if ($edge != $dst_phid) { 1045 + throw new Exception( 1046 + pht( 1047 + 'Transaction edge data must either be the edge PHID or an edge '. 1048 + 'specification dictionary.')); 1049 + } 1050 + $edge = array(); 1051 + } else { 1052 + foreach ($edge as $key => $value) { 1053 + switch ($key) { 1054 + case 'src': 1055 + case 'dst': 1056 + case 'type': 1057 + case 'data': 1058 + case 'dateCreated': 1059 + case 'dateModified': 1060 + case 'seq': 1061 + case 'dataID': 1062 + break; 1063 + default: 1064 + throw new Exception( 1065 + pht( 1066 + 'Transaction edge specification contains unexpected key '. 1067 + '"%s".', 1068 + $key)); 1069 + } 1070 + } 1043 1071 } 1044 1072 1045 - $edge_type = $xaction->getMetadataValue('edge:type'); 1073 + $edge['dst'] = $dst_phid; 1046 1074 1075 + $edge_type = $xaction->getMetadataValue('edge:type'); 1047 1076 if (empty($edge['type'])) { 1048 1077 $edge['type'] = $edge_type; 1049 1078 } else {
+11
src/infrastructure/customfield/field/PhabricatorCustomField.php
··· 747 747 /** 748 748 * @task appxaction 749 749 */ 750 + public function getApplicationTransactionMetadata() { 751 + if ($this->proxy) { 752 + return $this->proxy->getApplicationTransactionMetadata(); 753 + } 754 + return array(); 755 + } 756 + 757 + 758 + /** 759 + * @task appxaction 760 + */ 750 761 public function getOldValueForApplicationTransactions() { 751 762 if ($this->proxy) { 752 763 return $this->proxy->getOldValueForApplicationTransactions();
+17 -7
src/infrastructure/customfield/field/PhabricatorCustomFieldList.php
··· 199 199 continue; 200 200 } 201 201 202 - $old_value = $field->getOldValueForApplicationTransactions(); 203 - 204 - $field->readValueFromRequest($request); 205 202 $transaction_type = $field->getApplicationTransactionType(); 206 - 207 203 $xaction = id(clone $template) 208 - ->setTransactionType($transaction_type) 209 - ->setMetadataValue('customfield:key', $field->getFieldKey()) 210 - ->setNewValue($field->getNewValueForApplicationTransactions()); 204 + ->setTransactionType($transaction_type); 211 205 212 206 if ($transaction_type == PhabricatorTransactions::TYPE_CUSTOMFIELD) { 213 207 // For TYPE_CUSTOMFIELD transactions only, we provide the old value 214 208 // as an input. 209 + $old_value = $field->getOldValueForApplicationTransactions(); 215 210 $xaction->setOldValue($old_value); 211 + } 212 + 213 + $field->readValueFromRequest($request); 214 + 215 + $xaction 216 + ->setNewValue($field->getNewValueForApplicationTransactions()); 217 + 218 + if ($transaction_type == PhabricatorTransactions::TYPE_CUSTOMFIELD) { 219 + // For TYPE_CUSTOMFIELD transactions, add the field key in metadata. 220 + $xaction->setMetadataValue('customfield:key', $field->getFieldKey()); 221 + } 222 + 223 + $metadata = $field->getApplicationTransactionMetadata(); 224 + foreach ($metadata as $key => $value) { 225 + $xaction->setMetadataValue($key, $value); 216 226 } 217 227 218 228 $xactions[] = $xaction;