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

Move Differential commit message rendering to dedicated classes

Summary:
Ref T11114. This probably still has some bugs, but survives basic sanity checks.

Continue pulling commit message logic out of CustomField so we can reduce the amount of responsibility/bloat in the classtree and send more code through EditEngine.

Test Plan:
- Called `differential.getcommitmessage` via API console for various revisions/parameters (edit and create mode, with and without fields, with and without revisions).
- Used `--create`, `--edit` and `--update` modes of `arc diff` from the CLI.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T11114

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

+497 -110
+6 -4
src/__phutil_library_map__.php
··· 385 385 'DifferentialCloseConduitAPIMethod' => 'applications/differential/conduit/DifferentialCloseConduitAPIMethod.php', 386 386 'DifferentialCommentPreviewController' => 'applications/differential/controller/DifferentialCommentPreviewController.php', 387 387 'DifferentialCommentSaveController' => 'applications/differential/controller/DifferentialCommentSaveController.php', 388 + 'DifferentialCommitMessageCustomField' => 'applications/differential/field/DifferentialCommitMessageCustomField.php', 388 389 'DifferentialCommitMessageField' => 'applications/differential/field/DifferentialCommitMessageField.php', 389 390 'DifferentialCommitMessageParser' => 'applications/differential/parser/DifferentialCommitMessageParser.php', 390 391 'DifferentialCommitMessageParserTestCase' => 'applications/differential/parser/__tests__/DifferentialCommitMessageParserTestCase.php', ··· 4996 4997 'DifferentialAffectedPath' => 'DifferentialDAO', 4997 4998 'DifferentialApplyPatchField' => 'DifferentialCustomField', 4998 4999 'DifferentialAsanaRepresentationField' => 'DifferentialCustomField', 4999 - 'DifferentialAuditorsCommitMessageField' => 'DifferentialCommitMessageField', 5000 + 'DifferentialAuditorsCommitMessageField' => 'DifferentialCommitMessageCustomField', 5000 5001 'DifferentialAuditorsField' => 'DifferentialStoredCustomField', 5001 5002 'DifferentialAuthorField' => 'DifferentialCustomField', 5002 - 'DifferentialBlameRevisionCommitMessageField' => 'DifferentialCommitMessageField', 5003 + 'DifferentialBlameRevisionCommitMessageField' => 'DifferentialCommitMessageCustomField', 5003 5004 'DifferentialBlameRevisionField' => 'DifferentialStoredCustomField', 5004 5005 'DifferentialBlockHeraldAction' => 'HeraldAction', 5005 5006 'DifferentialBlockingReviewerDatasource' => 'PhabricatorTypeaheadCompositeDatasource', ··· 5031 5032 'DifferentialCloseConduitAPIMethod' => 'DifferentialConduitAPIMethod', 5032 5033 'DifferentialCommentPreviewController' => 'DifferentialController', 5033 5034 'DifferentialCommentSaveController' => 'DifferentialController', 5035 + 'DifferentialCommitMessageCustomField' => 'DifferentialCommitMessageField', 5034 5036 'DifferentialCommitMessageField' => 'Phobject', 5035 5037 'DifferentialCommitMessageParser' => 'Phobject', 5036 5038 'DifferentialCommitMessageParserTestCase' => 'PhabricatorTestCase', ··· 5125 5127 'DifferentialInlineCommentMailView' => 'DifferentialMailView', 5126 5128 'DifferentialInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController', 5127 5129 'DifferentialInlineCommentQuery' => 'PhabricatorOffsetPagedQuery', 5128 - 'DifferentialJIRAIssuesCommitMessageField' => 'DifferentialCommitMessageField', 5130 + 'DifferentialJIRAIssuesCommitMessageField' => 'DifferentialCommitMessageCustomField', 5129 5131 'DifferentialJIRAIssuesField' => 'DifferentialStoredCustomField', 5130 5132 'DifferentialLandingActionMenuEventListener' => 'PhabricatorEventListener', 5131 5133 'DifferentialLandingStrategy' => 'Phobject', ··· 5158 5160 'DifferentialResponsibleDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 5159 5161 'DifferentialResponsibleUserDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 5160 5162 'DifferentialResponsibleViewerFunctionDatasource' => 'PhabricatorTypeaheadDatasource', 5161 - 'DifferentialRevertPlanCommitMessageField' => 'DifferentialCommitMessageField', 5163 + 'DifferentialRevertPlanCommitMessageField' => 'DifferentialCommitMessageCustomField', 5162 5164 'DifferentialRevertPlanField' => 'DifferentialStoredCustomField', 5163 5165 'DifferentialReviewedByCommitMessageField' => 'DifferentialCommitMessageField', 5164 5166 'DifferentialReviewedByField' => 'DifferentialCoreCustomField',
+58 -96
src/applications/differential/conduit/DifferentialGetCommitMessageConduitAPIMethod.php
··· 47 47 } 48 48 } else { 49 49 $revision = DifferentialRevision::initializeNewRevision($viewer); 50 - $revision->attachReviewerStatus(array()); 51 - $revision->attachActiveDiff(null); 52 50 } 53 51 54 - $is_edit = $request->getValue('edit'); 55 - $is_create = ($is_edit == 'create'); 52 + $edit_mode = $request->getValue('edit'); 53 + $is_create = ($edit_mode == 'create'); 54 + $is_edit = ($edit_mode && !$is_create); 56 55 57 - $field_list = PhabricatorCustomField::getObjectFields( 58 - $revision, 59 - ($is_edit 60 - ? DifferentialCustomField::ROLE_COMMITMESSAGEEDIT 61 - : DifferentialCustomField::ROLE_COMMITMESSAGE)); 56 + $field_list = DifferentialCommitMessageField::newEnabledFields($viewer); 62 57 63 - $field_list 64 - ->setViewer($viewer) 65 - ->readFieldsFromStorage($revision); 58 + $custom_storage = $this->loadCustomFieldStorage($viewer, $revision); 59 + foreach ($field_list as $field) { 60 + $field->setCustomFieldStorage($custom_storage); 61 + } 66 62 67 - $field_map = mpull($field_list->getFields(), null, 'getFieldKeyForConduit'); 68 - 63 + // If we're editing the message, remove fields like "Conflicts" and 64 + // "git-svn-id" which should not be presented to the user for editing. 69 65 if ($is_edit) { 70 - $fields = $request->getValue('fields', array()); 71 - foreach ($fields as $field => $value) { 72 - $custom_field = idx($field_map, $field); 73 - if (!$custom_field) { 74 - // Just ignore this, these workflows don't make strong distictions 75 - // about field editability on the client side. 76 - continue; 77 - } 78 - if ($is_create || 79 - $custom_field->shouldOverwriteWhenCommitMessageIsEdited()) { 80 - $custom_field->readValueFromCommitMessage($value); 66 + foreach ($field_list as $field_key => $field) { 67 + if (!$field->isFieldEditable()) { 68 + unset($field_list[$field_key]); 81 69 } 82 70 } 83 71 } 84 72 85 - $phids = array(); 86 - foreach ($field_list->getFields() as $key => $field) { 87 - $field_phids = $field->getRequiredHandlePHIDsForCommitMessage(); 88 - if (!is_array($field_phids)) { 89 - throw new Exception( 90 - pht( 91 - 'Custom field "%s" was expected to return an array of handle '. 92 - 'PHIDs required for commit message rendering, but returned "%s" '. 93 - 'instead.', 94 - $field->getFieldKey(), 95 - gettype($field_phids))); 73 + $overrides = $request->getValue('fields', array()); 74 + 75 + $value_map = array(); 76 + foreach ($field_list as $field_key => $field) { 77 + if (array_key_exists($field_key, $overrides)) { 78 + $field_value = $overrides[$field_key]; 79 + } else { 80 + $field_value = $field->readFieldValueFromObject($revision); 96 81 } 97 - $phids[$key] = $field_phids; 98 - } 99 82 100 - $all_phids = array_mergev($phids); 101 - if ($all_phids) { 102 - $all_handles = id(new PhabricatorHandleQuery()) 103 - ->setViewer($viewer) 104 - ->withPHIDs($all_phids) 105 - ->execute(); 106 - } else { 107 - $all_handles = array(); 83 + // We're calling this method on the value no matter where we got it 84 + // from, so we hit the same validation logic for values which came over 85 + // the wire and which we generated. 86 + $field_value = $field->readFieldValueFromConduit($field_value); 87 + 88 + $value_map[$field_key] = $field_value; 108 89 } 109 90 110 - $key_title = id(new DifferentialTitleField())->getFieldKey(); 111 - $default_title = DifferentialTitleField::getDefaultTitle(); 91 + $key_title = DifferentialTitleCommitMessageField::FIELDKEY; 112 92 113 93 $commit_message = array(); 114 - foreach ($field_list->getFields() as $key => $field) { 115 - $handles = array_select_keys($all_handles, $phids[$key]); 94 + foreach ($field_list as $field_key => $field) { 95 + $label = $field->getFieldName(); 96 + $wire_value = $value_map[$field_key]; 97 + $value = $field->renderFieldValue($wire_value); 116 98 117 - $label = $field->renderCommitMessageLabel(); 118 - $value = $field->renderCommitMessageValue($handles); 99 + $is_template = ($is_edit && $field->isTemplateField()); 119 100 120 101 if (!is_string($value) && !is_null($value)) { 121 102 throw new Exception( 122 103 pht( 123 - 'Custom field "%s" was expected to render a string or null value, '. 124 - 'but rendered a "%s" instead.', 104 + 'Commit message field "%s" was expected to render a string or '. 105 + 'null value, but rendered a "%s" instead.', 125 106 $field->getFieldKey(), 126 107 gettype($value))); 127 108 } 128 109 129 - $is_title = ($key == $key_title); 110 + $is_title = ($field_key == $key_title); 130 111 131 112 if (!strlen($value)) { 132 - if ($is_title) { 133 - $commit_message[] = $default_title; 134 - } else { 135 - if ($is_edit && $field->shouldAppearInCommitMessageTemplate()) { 136 - $commit_message[] = $label.': '; 137 - } 113 + if ($is_template) { 114 + $commit_message[] = $label.': '; 138 115 } 139 116 } else { 140 117 if ($is_title) { ··· 153 130 } 154 131 } 155 132 156 - if ($is_edit) { 157 - $tip = $this->getProTip($field_list); 158 - if ($tip !== null) { 159 - $commit_message[] = "\n".$tip; 160 - } 161 - } 162 - 163 - $commit_message = implode("\n\n", $commit_message); 164 - 165 - return $commit_message; 133 + return implode("\n\n", $commit_message); 166 134 } 167 135 168 - private function getProTip() { 169 - // Any field can provide tips, whether it normally appears on commit 170 - // messages or not. 171 - $field_list = PhabricatorCustomField::getObjectFields( 172 - new DifferentialRevision(), 173 - PhabricatorCustomField::ROLE_DEFAULT); 174 - 175 - $tips = array(); 176 - foreach ($field_list->getFields() as $key => $field) { 177 - $tips[] = $field->getProTips(); 178 - } 179 - $tips = array_mergev($tips); 180 - 181 - if (!$tips) { 182 - return null; 183 - } 184 - 185 - shuffle($tips); 186 - 187 - $tip = pht('Tip: %s', head($tips)); 188 - $tip = wordwrap($tip, 78, "\n", true); 136 + private function loadCustomFieldStorage( 137 + PhabricatorUser $viewer, 138 + DifferentialRevision $revision) { 139 + $custom_field_list = PhabricatorCustomField::getObjectFields( 140 + $revision, 141 + DifferentialCustomField::ROLE_COMMITMESSAGE); 142 + $custom_field_list 143 + ->setViewer($viewer) 144 + ->readFieldsFromStorage($revision); 189 145 190 - $lines = explode("\n", $tip); 191 - foreach ($lines as $key => $line) { 192 - $lines[$key] = '# '.$line; 146 + $custom_field_map = array(); 147 + foreach ($custom_field_list->getFields() as $custom_field) { 148 + if (!$custom_field->shouldUseStorage()) { 149 + continue; 150 + } 151 + $custom_field_key = $custom_field->getFieldKey(); 152 + $custom_field_value = $custom_field->getValueForStorage(); 153 + $custom_field_map[$custom_field_key] = $custom_field_value; 193 154 } 194 155 195 - return implode("\n", $lines); 156 + return $custom_field_map; 196 157 } 158 + 197 159 198 160 }
+17 -1
src/applications/differential/field/DifferentialAuditorsCommitMessageField.php
··· 1 1 <?php 2 2 3 3 final class DifferentialAuditorsCommitMessageField 4 - extends DifferentialCommitMessageField { 4 + extends DifferentialCommitMessageCustomField { 5 5 6 6 const FIELDKEY = 'phabricator:auditors'; 7 7 ··· 16 16 PhabricatorPeopleUserPHIDType::TYPECONST, 17 17 PhabricatorProjectProjectPHIDType::TYPECONST, 18 18 )); 19 + } 20 + 21 + public function getCustomFieldKey() { 22 + return 'phabricator:auditors'; 23 + } 24 + 25 + public function readFieldValueFromConduit($value) { 26 + return $this->readStringListFieldValueFromConduit($value); 27 + } 28 + 29 + public function renderFieldValue($value) { 30 + return $this->renderHandleList($value); 31 + } 32 + 33 + protected function readFieldValueFromCustomFieldStorage($value) { 34 + return $this->readJSONFieldValueFromCustomFieldStorage($value, array()); 19 35 } 20 36 21 37 }
+3 -3
src/applications/differential/field/DifferentialBlameRevisionCommitMessageField.php
··· 1 1 <?php 2 2 3 3 final class DifferentialBlameRevisionCommitMessageField 4 - extends DifferentialCommitMessageField { 4 + extends DifferentialCommitMessageCustomField { 5 5 6 6 const FIELDKEY = 'blameRevision'; 7 7 ··· 15 15 ); 16 16 } 17 17 18 - public function isFieldEnabled() { 19 - return $this->isCustomFieldEnabled('phabricator:blame-revision'); 18 + public function getCustomFieldKey() { 19 + return 'phabricator:blame-revision'; 20 20 } 21 21 22 22 }
+63
src/applications/differential/field/DifferentialCommitMessageCustomField.php
··· 1 + <?php 2 + 3 + abstract class DifferentialCommitMessageCustomField 4 + extends DifferentialCommitMessageField { 5 + 6 + abstract public function getCustomFieldKey(); 7 + 8 + public function getFieldOrder() { 9 + $custom_key = $this->getCustomFieldKey(); 10 + return 100000 + $this->getCustomFieldOrder($custom_key); 11 + } 12 + 13 + public function isFieldEnabled() { 14 + $custom_key = $this->getCustomFieldKey(); 15 + return $this->isCustomFieldEnabled($custom_key); 16 + } 17 + 18 + public function readFieldValueFromObject(DifferentialRevision $revision) { 19 + $custom_key = $this->getCustomFieldKey(); 20 + $value = $this->readCustomFieldValue($revision, $custom_key); 21 + return $value; 22 + } 23 + 24 + protected function readFieldValueFromCustomFieldStorage($value) { 25 + return $value; 26 + } 27 + 28 + protected function readJSONFieldValueFromCustomFieldStorage( 29 + $value, 30 + $default) { 31 + try { 32 + return phutil_json_decode($value); 33 + } catch (PhutilJSONParserException $ex) { 34 + return $default; 35 + } 36 + } 37 + 38 + protected function readCustomFieldValue( 39 + DifferentialRevision $revision, 40 + $key) { 41 + $value = idx($this->getCustomFieldStorage(), $key); 42 + return $this->readFieldValueFromCustomFieldStorage($value); 43 + } 44 + 45 + protected function getCustomFieldOrder($key) { 46 + $field_list = PhabricatorCustomField::getObjectFields( 47 + new DifferentialRevision(), 48 + DifferentialCustomField::ROLE_COMMITMESSAGE); 49 + 50 + $fields = $field_list->getFields(); 51 + 52 + $idx = 0; 53 + foreach ($fields as $field_key => $value) { 54 + if ($key === $field_key) { 55 + return $idx; 56 + } 57 + $idx++; 58 + } 59 + 60 + return $idx; 61 + } 62 + 63 + }
+92
src/applications/differential/field/DifferentialCommitMessageField.php
··· 4 4 extends Phobject { 5 5 6 6 private $viewer; 7 + private $customFieldStorage; 7 8 8 9 final public function setViewer(PhabricatorUser $viewer) { 9 10 $this->viewer = $viewer; ··· 14 15 return $this->viewer; 15 16 } 16 17 18 + final public function setCustomFieldStorage(array $custom_field_storage) { 19 + $this->customFieldStorage = $custom_field_storage; 20 + return $this; 21 + } 22 + 23 + final public function getCustomFieldStorage() { 24 + return $this->customFieldStorage; 25 + } 26 + 17 27 abstract public function getFieldName(); 28 + abstract public function getFieldOrder(); 18 29 19 30 public function isFieldEnabled() { 20 31 return true; ··· 32 43 return $value; 33 44 } 34 45 46 + public function isFieldEditable() { 47 + return true; 48 + } 49 + 50 + public function isTemplateField() { 51 + return true; 52 + } 53 + 54 + public function readFieldValueFromConduit($value) { 55 + return $this->readStringFieldValueFromConduit($value); 56 + } 57 + 58 + public function readFieldValueFromObject(DifferentialRevision $revision) { 59 + return null; 60 + } 61 + 62 + public function renderFieldValue($value) { 63 + if (!strlen($value)) { 64 + return null; 65 + } 66 + 67 + return $value; 68 + } 69 + 35 70 final public function getCommitMessageFieldKey() { 36 71 return $this->getPhobjectClassConstant('FIELDKEY', 64); 37 72 } ··· 55 90 return id(new PhutilClassMapQuery()) 56 91 ->setAncestorClass(__CLASS__) 57 92 ->setUniqueMethod('getCommitMessageFieldKey') 93 + ->setSortMethod('getFieldOrder') 58 94 ->execute(); 59 95 } 60 96 ··· 78 114 ->setAllowPartialResults($allow_partial) 79 115 ->setSuffixes($suffixes) 80 116 ->execute(); 117 + } 118 + 119 + protected function renderHandleList(array $phids, array $suffixes = array()) { 120 + if (!$phids) { 121 + return null; 122 + } 123 + 124 + $handles = $this->getViewer()->loadHandles($phids); 125 + 126 + $out = array(); 127 + foreach ($handles as $handle) { 128 + $phid = $handle->getPHID(); 129 + 130 + if ($handle->getPolicyFiltered()) { 131 + $token = $phid; 132 + } else if ($handle->isComplete()) { 133 + $token = $handle->getCommandLineObjectName(); 134 + } 135 + 136 + $suffix = idx($suffixes, $phid); 137 + $token = $token.$suffix; 138 + 139 + $out[] = $token; 140 + } 141 + 142 + return implode(', ', $out); 143 + } 144 + 145 + protected function readStringFieldValueFromConduit($value) { 146 + if ($value === null) { 147 + return $value; 148 + } 149 + 150 + if (!is_string($value)) { 151 + throw new Exception( 152 + pht( 153 + 'Field "%s" expects a string value, but received a value of type '. 154 + '"%s".', 155 + $this->getCommitMessageFieldKey(), 156 + gettype($value))); 157 + } 158 + 159 + return $value; 160 + } 161 + 162 + protected function readStringListFieldValueFromConduit($value) { 163 + if (!is_array($value)) { 164 + throw new Exception( 165 + pht( 166 + 'Field "%s" expects a list of strings, but received a value of type '. 167 + '"%s".', 168 + $this->getCommitMessageFieldKey(), 169 + gettype($value))); 170 + } 171 + 172 + return $value; 81 173 } 82 174 83 175 protected function isCustomFieldEnabled($key) {
+8
src/applications/differential/field/DifferentialConflictsCommitMessageField.php
··· 9 9 return pht('Conflicts'); 10 10 } 11 11 12 + public function getFieldOrder() { 13 + return 900000; 14 + } 15 + 16 + public function isFieldEditable() { 17 + return false; 18 + } 19 + 12 20 }
+8
src/applications/differential/field/DifferentialGitSVNIDCommitMessageField.php
··· 9 9 return pht('git-svn-id'); 10 10 } 11 11 12 + public function getFieldOrder() { 13 + return 900001; 14 + } 15 + 16 + public function isFieldEditable() { 17 + return false; 18 + } 19 + 12 20 }
+19 -3
src/applications/differential/field/DifferentialJIRAIssuesCommitMessageField.php
··· 1 1 <?php 2 2 3 3 final class DifferentialJIRAIssuesCommitMessageField 4 - extends DifferentialCommitMessageField { 4 + extends DifferentialCommitMessageCustomField { 5 5 6 6 const FIELDKEY = 'jira.issues'; 7 7 ··· 16 16 ); 17 17 } 18 18 19 + public function getCustomFieldKey() { 20 + return 'phabricator:jira-issues'; 21 + } 22 + 19 23 public function parseFieldValue($value) { 20 24 return preg_split('/[\s,]+/', $value, $limit = -1, PREG_SPLIT_NO_EMPTY); 21 25 } 22 26 23 - public function isFieldEnabled() { 24 - return (bool)PhabricatorJIRAAuthProvider::getJIRAProvider(); 27 + protected function readFieldValueFromCustomFieldStorage($value) { 28 + return $this->readJSONFieldValueFromCustomFieldStorage($value, array()); 29 + } 30 + 31 + public function readFieldValueFromConduit($value) { 32 + return $this->readStringListFieldValueFromConduit($value); 33 + } 34 + 35 + public function renderFieldValue($value) { 36 + if (!$value) { 37 + return null; 38 + } 39 + 40 + return implode(', ', $value); 25 41 } 26 42 27 43 }
+3 -3
src/applications/differential/field/DifferentialRevertPlanCommitMessageField.php
··· 1 1 <?php 2 2 3 3 final class DifferentialRevertPlanCommitMessageField 4 - extends DifferentialCommitMessageField { 4 + extends DifferentialCommitMessageCustomField { 5 5 6 6 const FIELDKEY = 'revertPlan'; 7 7 ··· 9 9 return pht('Revert Plan'); 10 10 } 11 11 12 - public function isFieldEnabled() { 13 - return $this->isCustomFieldEnabled('phabricator:revert-plan'); 12 + public function getCustomFieldKey() { 13 + return 'phabricator:revert-plan'; 14 14 } 15 15 16 16 }
+34
src/applications/differential/field/DifferentialReviewedByCommitMessageField.php
··· 9 9 return pht('Reviewed By'); 10 10 } 11 11 12 + public function getFieldOrder() { 13 + return 5000; 14 + } 15 + 12 16 public function parseFieldValue($value) { 13 17 return $this->parseObjectList( 14 18 $value, ··· 17 21 PhabricatorProjectProjectPHIDType::TYPECONST, 18 22 ), 19 23 $allow_partial = true); 24 + } 25 + 26 + public function isFieldEditable() { 27 + return false; 28 + } 29 + 30 + public function readFieldValueFromObject(DifferentialRevision $revision) { 31 + if (!$revision->getPHID()) { 32 + return array(); 33 + } 34 + 35 + $phids = array(); 36 + foreach ($revision->getReviewerStatus() as $reviewer) { 37 + switch ($reviewer->getStatus()) { 38 + case DifferentialReviewerStatus::STATUS_ACCEPTED: 39 + case DifferentialReviewerStatus::STATUS_ACCEPTED_OLDER: 40 + $phids[] = $reviewer->getReviewerPHID(); 41 + break; 42 + } 43 + } 44 + 45 + return $phids; 46 + } 47 + 48 + public function readFieldValueFromConduit($value) { 49 + return $this->readStringListFieldValueFromConduit($value); 50 + } 51 + 52 + public function renderFieldValue($value) { 53 + return $this->renderHandleList($value); 20 54 } 21 55 22 56 }
+48
src/applications/differential/field/DifferentialReviewersCommitMessageField.php
··· 9 9 return pht('Reviewers'); 10 10 } 11 11 12 + public function getFieldOrder() { 13 + return 4000; 14 + } 15 + 12 16 public function getFieldAliases() { 13 17 return array( 14 18 'Reviewer', ··· 27 31 array('!')); 28 32 29 33 return $this->flattenReviewers($results); 34 + } 35 + 36 + public function readFieldValueFromConduit($value) { 37 + return $this->readStringListFieldValueFromConduit($value); 38 + } 39 + 40 + public function readFieldValueFromObject(DifferentialRevision $revision) { 41 + if (!$revision->getPHID()) { 42 + return array(); 43 + } 44 + 45 + $status_blocking = DifferentialReviewerStatus::STATUS_BLOCKING; 46 + 47 + $results = array(); 48 + foreach ($revision->getReviewerStatus() as $reviewer) { 49 + if ($reviewer->getStatus() == $status_blocking) { 50 + $suffixes = array('!' => '!'); 51 + } else { 52 + $suffixes = array(); 53 + } 54 + 55 + $results[] = array( 56 + 'phid' => $reviewer->getReviewerPHID(), 57 + 'suffixes' => $suffixes, 58 + ); 59 + } 60 + 61 + return $this->flattenReviewers($results); 62 + } 63 + 64 + public function renderFieldValue($value) { 65 + $value = $this->inflateReviewers($value); 66 + 67 + $phid_list = array(); 68 + $suffix_map = array(); 69 + foreach ($value as $reviewer) { 70 + $phid = $reviewer['phid']; 71 + $phid_list[] = $phid; 72 + if (isset($reviewer['suffixes']['!'])) { 73 + $suffix_map[$phid] = '!'; 74 + } 75 + } 76 + 77 + return $this->renderHandleList($phid_list, $suffix_map); 30 78 } 31 79 32 80 private function flattenReviewers(array $values) {
+27
src/applications/differential/field/DifferentialRevisionIDCommitMessageField.php
··· 9 9 return pht('Differential Revision'); 10 10 } 11 11 12 + public function getFieldOrder() { 13 + return 200000; 14 + } 15 + 16 + public function isTemplateField() { 17 + return false; 18 + } 19 + 12 20 public function parseFieldValue($value) { 13 21 // If the value is just "D123" or similar, parse the ID from it directly. 14 22 $value = trim($value); ··· 47 55 } 48 56 49 57 return null; 58 + } 59 + 60 + public function readFieldValueFromObject(DifferentialRevision $revision) { 61 + return $revision->getID(); 62 + } 63 + 64 + public function readFieldValueFromConduit($value) { 65 + if (is_int($value)) { 66 + $value = (string)$value; 67 + } 68 + return $this->readStringFieldValueFromConduit($value); 69 + } 70 + 71 + public function renderFieldValue($value) { 72 + if (!strlen($value)) { 73 + return null; 74 + } 75 + 76 + return PhabricatorEnv::getProductionURI('/D'.$value); 50 77 } 51 78 52 79 }
+21
src/applications/differential/field/DifferentialSubscribersCommitMessageField.php
··· 9 9 return pht('Subscribers'); 10 10 } 11 11 12 + public function getFieldOrder() { 13 + return 6000; 14 + } 15 + 12 16 public function getFieldAliases() { 13 17 return array( 14 18 'CC', ··· 25 29 PhabricatorProjectProjectPHIDType::TYPECONST, 26 30 PhabricatorOwnersPackagePHIDType::TYPECONST, 27 31 )); 32 + } 33 + 34 + public function readFieldValueFromObject(DifferentialRevision $revision) { 35 + if (!$revision->getPHID()) { 36 + return array(); 37 + } 38 + 39 + return PhabricatorSubscribersQuery::loadSubscribersForPHID( 40 + $revision->getPHID()); 41 + } 42 + 43 + public function readFieldValueFromConduit($value) { 44 + return $this->readStringListFieldValueFromConduit($value); 45 + } 46 + 47 + public function renderFieldValue($value) { 48 + return $this->renderHandleList($value); 28 49 } 29 50 30 51 }
+8
src/applications/differential/field/DifferentialSummaryCommitMessageField.php
··· 9 9 return pht('Summary'); 10 10 } 11 11 12 + public function getFieldOrder() { 13 + return 2000; 14 + } 15 + 16 + public function readFieldValueFromObject(DifferentialRevision $revision) { 17 + return $revision->getSummary(); 18 + } 19 + 12 20 }
+30
src/applications/differential/field/DifferentialTagsCommitMessageField.php
··· 9 9 return pht('Tags'); 10 10 } 11 11 12 + public function getFieldOrder() { 13 + return 7000; 14 + } 15 + 12 16 public function getFieldAliases() { 13 17 return array( 14 18 'Tag', 15 19 'Project', 16 20 'Projects', 17 21 ); 22 + } 23 + 24 + public function isTemplateField() { 25 + return false; 18 26 } 19 27 20 28 public function parseFieldValue($value) { ··· 24 32 PhabricatorProjectProjectPHIDType::TYPECONST, 25 33 )); 26 34 } 35 + 36 + public function readFieldValueFromObject(DifferentialRevision $revision) { 37 + if (!$revision->getPHID()) { 38 + return array(); 39 + } 40 + 41 + $projects = PhabricatorEdgeQuery::loadDestinationPHIDs( 42 + $revision->getPHID(), 43 + PhabricatorProjectObjectHasProjectEdgeType::EDGECONST); 44 + $projects = array_reverse($projects); 45 + 46 + return $projects; 47 + } 48 + 49 + public function readFieldValueFromConduit($value) { 50 + return $this->readStringListFieldValueFromConduit($value); 51 + } 52 + 53 + public function renderFieldValue($value) { 54 + return $this->renderHandleList($value); 55 + } 56 + 27 57 28 58 }
+29
src/applications/differential/field/DifferentialTasksCommitMessageField.php
··· 9 9 return pht('Maniphest Tasks'); 10 10 } 11 11 12 + public function getFieldOrder() { 13 + return 8000; 14 + } 15 + 12 16 public function getFieldAliases() { 13 17 return array( 14 18 'Task', 15 19 'Tasks', 16 20 'Maniphest Task', 17 21 ); 22 + } 23 + 24 + public function isTemplateField() { 25 + return false; 18 26 } 19 27 20 28 public function parseFieldValue($value) { ··· 23 31 array( 24 32 ManiphestTaskPHIDType::TYPECONST, 25 33 )); 34 + } 35 + 36 + public function readFieldValueFromObject(DifferentialRevision $revision) { 37 + if (!$revision->getPHID()) { 38 + return array(); 39 + } 40 + 41 + $projects = PhabricatorEdgeQuery::loadDestinationPHIDs( 42 + $revision->getPHID(), 43 + DifferentialRevisionHasTaskEdgeType::EDGECONST); 44 + $projects = array_reverse($projects); 45 + 46 + return $projects; 47 + } 48 + 49 + public function readFieldValueFromConduit($value) { 50 + return $this->readStringListFieldValueFromConduit($value); 51 + } 52 + 53 + public function renderFieldValue($value) { 54 + return $this->renderHandleList($value); 26 55 } 27 56 28 57 }
+8
src/applications/differential/field/DifferentialTestPlanCommitMessageField.php
··· 9 9 return pht('Test Plan'); 10 10 } 11 11 12 + public function getFieldOrder() { 13 + return 3000; 14 + } 15 + 12 16 public function getFieldAliases() { 13 17 return array( 14 18 'Testplan', ··· 31 35 'You must provide a test plan. Describe the actions you performed '. 32 36 'to verify the behavior of this change.')); 33 37 } 38 + } 39 + 40 + public function readFieldValueFromObject(DifferentialRevision $revision) { 41 + return $revision->getTestPlan(); 34 42 } 35 43 36 44 }
+14
src/applications/differential/field/DifferentialTitleCommitMessageField.php
··· 9 9 return pht('Title'); 10 10 } 11 11 12 + public function getFieldOrder() { 13 + return 1000; 14 + } 15 + 12 16 public static function getDefaultTitle() { 13 17 return pht('<<Replace this line with your revision title>'); 14 18 } ··· 31 35 'You must provide a revision title in the first line '. 32 36 'of your commit message.')); 33 37 } 38 + } 39 + 40 + public function readFieldValueFromObject(DifferentialRevision $revision) { 41 + $value = $revision->getTitle(); 42 + 43 + if (!strlen($value)) { 44 + return self::getDefaultTitle(); 45 + } 46 + 47 + return $value; 34 48 } 35 49 36 50 }
+1
src/applications/differential/storage/DifferentialRevision.php
··· 70 70 ->setAuthorPHID($actor->getPHID()) 71 71 ->attachRelationships(array()) 72 72 ->attachRepository(null) 73 + ->attachActiveDiff(null) 73 74 ->attachReviewerStatus(array()) 74 75 ->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVIEW); 75 76 }