[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class DifferentialGetCommitMessageConduitAPIMethod 4 extends DifferentialConduitAPIMethod { 5 6 public function getAPIMethodName() { 7 return 'differential.getcommitmessage'; 8 } 9 10 public function getMethodDescription() { 11 return 'Retrieve Differential commit messages or message templates.'; 12 } 13 14 public function defineParamTypes() { 15 $edit_types = array('edit', 'create'); 16 17 return array( 18 'revision_id' => 'optional revision_id', 19 'fields' => 'optional dict<string, wild>', 20 'edit' => 'optional '.$this->formatStringConstants($edit_types), 21 ); 22 } 23 24 public function defineReturnType() { 25 return 'nonempty string'; 26 } 27 28 public function defineErrorTypes() { 29 return array( 30 'ERR_NOT_FOUND' => 'Revision was not found.', 31 ); 32 } 33 34 protected function execute(ConduitAPIRequest $request) { 35 $id = $request->getValue('revision_id'); 36 $viewer = $request->getUser(); 37 38 if ($id) { 39 $revision = id(new DifferentialRevisionQuery()) 40 ->withIDs(array($id)) 41 ->setViewer($viewer) 42 ->needReviewerStatus(true) 43 ->needActiveDiffs(true) 44 ->executeOne(); 45 if (!$revision) { 46 throw new ConduitException('ERR_NOT_FOUND'); 47 } 48 } else { 49 $revision = DifferentialRevision::initializeNewRevision($viewer); 50 $revision->attachReviewerStatus(array()); 51 $revision->attachActiveDiff(null); 52 } 53 54 $is_edit = $request->getValue('edit'); 55 $is_create = ($is_edit == 'create'); 56 57 $field_list = PhabricatorCustomField::getObjectFields( 58 $revision, 59 ($is_edit 60 ? DifferentialCustomField::ROLE_COMMITMESSAGEEDIT 61 : DifferentialCustomField::ROLE_COMMITMESSAGE)); 62 63 $field_list 64 ->setViewer($viewer) 65 ->readFieldsFromStorage($revision); 66 67 $field_map = mpull($field_list->getFields(), null, 'getFieldKeyForConduit'); 68 69 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); 81 } 82 } 83 } 84 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))); 96 } 97 $phids[$key] = $field_phids; 98 } 99 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(); 108 } 109 110 $key_title = id(new DifferentialTitleField())->getFieldKey(); 111 $default_title = DifferentialTitleField::getDefaultTitle(); 112 113 $commit_message = array(); 114 foreach ($field_list->getFields() as $key => $field) { 115 $handles = array_select_keys($all_handles, $phids[$key]); 116 117 $label = $field->renderCommitMessageLabel(); 118 $value = $field->renderCommitMessageValue($handles); 119 120 if (!is_string($value) && !is_null($value)) { 121 throw new Exception( 122 pht( 123 'Custom field "%s" was expected to render a string or null value, '. 124 'but rendered a "%s" instead.', 125 $field->getFieldKey(), 126 gettype($value))); 127 } 128 129 $is_title = ($key == $key_title); 130 131 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 } 138 } 139 } else { 140 if ($is_title) { 141 $commit_message[] = $value; 142 } else { 143 $value = str_replace( 144 array("\r\n", "\r"), 145 array("\n", "\n"), 146 $value); 147 if (strpos($value, "\n") !== false || substr($value, 0, 2) === ' ') { 148 $commit_message[] = "{$label}:\n{$value}"; 149 } else { 150 $commit_message[] = "{$label}: {$value}"; 151 } 152 } 153 } 154 } 155 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; 166 } 167 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); 189 190 $lines = explode("\n", $tip); 191 foreach ($lines as $key => $line) { 192 $lines[$key] = '# '.$line; 193 } 194 195 return implode("\n", $lines); 196 } 197 198 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |