[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class DifferentialJIRAIssuesField 4 extends DifferentialStoredCustomField { 5 6 private $error; 7 8 public function getFieldKey() { 9 return 'phabricator:jira-issues'; 10 } 11 12 public function getFieldKeyForConduit() { 13 return 'jira.issues'; 14 } 15 16 public function isFieldEnabled() { 17 return (bool)PhabricatorJIRAAuthProvider::getJIRAProvider(); 18 } 19 20 public function canDisableField() { 21 return false; 22 } 23 24 public function getValueForStorage() { 25 return json_encode($this->getValue()); 26 } 27 28 public function setValueFromStorage($value) { 29 try { 30 $this->setValue(phutil_json_decode($value)); 31 } catch (PhutilJSONParserException $ex) { 32 $this->setValue(array()); 33 } 34 return $this; 35 } 36 37 public function getFieldName() { 38 return pht('JIRA Issues'); 39 } 40 41 public function getFieldDescription() { 42 return pht('Lists associated JIRA issues.'); 43 } 44 45 public function shouldAppearInPropertyView() { 46 return true; 47 } 48 49 public function renderPropertyViewLabel() { 50 return $this->getFieldName(); 51 } 52 53 public function renderPropertyViewValue(array $handles) { 54 $xobjs = $this->loadDoorkeeperExternalObjects($this->getValue()); 55 if (!$xobjs) { 56 return null; 57 } 58 59 $links = array(); 60 foreach ($xobjs as $xobj) { 61 $links[] = id(new DoorkeeperTagView()) 62 ->setExternalObject($xobj); 63 } 64 65 return phutil_implode_html(phutil_tag('br'), $links); 66 } 67 68 private function buildDoorkeeperRefs($value) { 69 $provider = PhabricatorJIRAAuthProvider::getJIRAProvider(); 70 71 $refs = array(); 72 if ($value) { 73 foreach ($value as $jira_key) { 74 $refs[] = id(new DoorkeeperObjectRef()) 75 ->setApplicationType(DoorkeeperBridgeJIRA::APPTYPE_JIRA) 76 ->setApplicationDomain($provider->getProviderDomain()) 77 ->setObjectType(DoorkeeperBridgeJIRA::OBJTYPE_ISSUE) 78 ->setObjectID($jira_key); 79 } 80 } 81 82 return $refs; 83 } 84 85 private function loadDoorkeeperExternalObjects($value) { 86 $refs = $this->buildDoorkeeperRefs($value); 87 if (!$refs) { 88 return array(); 89 } 90 91 $xobjs = id(new DoorkeeperExternalObjectQuery()) 92 ->setViewer($this->getViewer()) 93 ->withObjectKeys(mpull($refs, 'getObjectKey')) 94 ->execute(); 95 96 return $xobjs; 97 } 98 99 public function shouldAppearInEditView() { 100 return PhabricatorJIRAAuthProvider::getJIRAProvider(); 101 } 102 103 public function shouldAppearInApplicationTransactions() { 104 return PhabricatorJIRAAuthProvider::getJIRAProvider(); 105 } 106 107 public function readValueFromRequest(AphrontRequest $request) { 108 $this->setValue($request->getStrList($this->getFieldKey())); 109 return $this; 110 } 111 112 public function renderEditControl(array $handles) { 113 return id(new AphrontFormTextControl()) 114 ->setLabel(pht('JIRA Issues')) 115 ->setCaption( 116 pht('Example: %s', phutil_tag('tt', array(), 'JIS-3, JIS-9'))) 117 ->setName($this->getFieldKey()) 118 ->setValue(implode(', ', nonempty($this->getValue(), array()))) 119 ->setError($this->error); 120 } 121 122 public function getOldValueForApplicationTransactions() { 123 return array_unique(nonempty($this->getValue(), array())); 124 } 125 126 public function getNewValueForApplicationTransactions() { 127 return array_unique(nonempty($this->getValue(), array())); 128 } 129 130 public function validateApplicationTransactions( 131 PhabricatorApplicationTransactionEditor $editor, 132 $type, 133 array $xactions) { 134 135 $this->error = null; 136 137 $errors = parent::validateApplicationTransactions( 138 $editor, 139 $type, 140 $xactions); 141 142 $transaction = null; 143 foreach ($xactions as $xaction) { 144 $old = $xaction->getOldValue(); 145 $new = $xaction->getNewValue(); 146 147 $add = array_diff($new, $old); 148 if (!$add) { 149 continue; 150 } 151 152 // Only check that the actor can see newly added JIRA refs. You're 153 // allowed to remove refs or make no-op changes even if you aren't 154 // linked to JIRA. 155 156 try { 157 $refs = id(new DoorkeeperImportEngine()) 158 ->setViewer($this->getViewer()) 159 ->setRefs($this->buildDoorkeeperRefs($add)) 160 ->setThrowOnMissingLink(true) 161 ->execute(); 162 } catch (DoorkeeperMissingLinkException $ex) { 163 $this->error = pht('Not Linked'); 164 $errors[] = new PhabricatorApplicationTransactionValidationError( 165 $type, 166 pht('Not Linked'), 167 pht( 168 'You can not add JIRA issues (%s) to this revision because your '. 169 'Phabricator account is not linked to a JIRA account.', 170 implode(', ', $add)), 171 $xaction); 172 continue; 173 } 174 175 $bad = array(); 176 foreach ($refs as $ref) { 177 if (!$ref->getIsVisible()) { 178 $bad[] = $ref->getObjectID(); 179 } 180 } 181 182 if ($bad) { 183 $bad = implode(', ', $bad); 184 $this->error = pht('Invalid'); 185 186 $errors[] = new PhabricatorApplicationTransactionValidationError( 187 $type, 188 pht('Invalid'), 189 pht( 190 'Some JIRA issues could not be loaded. They may not exist, or '. 191 'you may not have permission to view them: %s', 192 $bad), 193 $xaction); 194 } 195 } 196 197 return $errors; 198 } 199 200 public function getApplicationTransactionTitle( 201 PhabricatorApplicationTransaction $xaction) { 202 203 $old = $xaction->getOldValue(); 204 if (!is_array($old)) { 205 $old = array(); 206 } 207 208 $new = $xaction->getNewValue(); 209 if (!is_array($new)) { 210 $new = array(); 211 } 212 213 $add = array_diff($new, $old); 214 $rem = array_diff($old, $new); 215 216 $author_phid = $xaction->getAuthorPHID(); 217 if ($add && $rem) { 218 return pht( 219 '%s updated JIRA issue(s): added %d %s; removed %d %s.', 220 $xaction->renderHandleLink($author_phid), 221 new PhutilNumber(count($add)), 222 implode(', ', $add), 223 new PhutilNumber(count($rem)), 224 implode(', ', $rem)); 225 } else if ($add) { 226 return pht( 227 '%s added %d JIRA issue(s): %s.', 228 $xaction->renderHandleLink($author_phid), 229 new PhutilNumber(count($add)), 230 implode(', ', $add)); 231 } else if ($rem) { 232 return pht( 233 '%s removed %d JIRA issue(s): %s.', 234 $xaction->renderHandleLink($author_phid), 235 new PhutilNumber(count($rem)), 236 implode(', ', $rem)); 237 } 238 239 return parent::getApplicationTransactionTitle($xaction); 240 } 241 242 public function applyApplicationTransactionExternalEffects( 243 PhabricatorApplicationTransaction $xaction) { 244 245 // Update the CustomField storage. 246 parent::applyApplicationTransactionExternalEffects($xaction); 247 248 // Now, synchronize the Doorkeeper edges. 249 $revision = $this->getObject(); 250 $revision_phid = $revision->getPHID(); 251 252 $edge_type = PhabricatorEdgeConfig::TYPE_PHOB_HAS_JIRAISSUE; 253 $xobjs = $this->loadDoorkeeperExternalObjects($xaction->getNewValue()); 254 $edge_dsts = mpull($xobjs, 'getPHID'); 255 256 $edges = PhabricatorEdgeQuery::loadDestinationPHIDs( 257 $revision_phid, 258 $edge_type); 259 260 $editor = new PhabricatorEdgeEditor(); 261 262 foreach (array_diff($edges, $edge_dsts) as $rem_edge) { 263 $editor->removeEdge($revision_phid, $edge_type, $rem_edge); 264 } 265 266 foreach (array_diff($edge_dsts, $edges) as $add_edge) { 267 $editor->addEdge($revision_phid, $edge_type, $add_edge); 268 } 269 270 $editor->save(); 271 } 272 273 public function shouldAppearInCommitMessage() { 274 return true; 275 } 276 277 public function shouldAppearInCommitMessageTemplate() { 278 return true; 279 } 280 281 public function getCommitMessageLabels() { 282 return array( 283 'JIRA', 284 'JIRA Issues', 285 'JIRA Issue', 286 ); 287 } 288 289 public function parseValueFromCommitMessage($value) { 290 return preg_split('/[\s,]+/', $value, $limit = -1, PREG_SPLIT_NO_EMPTY); 291 } 292 293 public function readValueFromCommitMessage($value) { 294 $this->setValue($value); 295 return $this; 296 } 297 298 299 300 public function renderCommitMessageValue(array $handles) { 301 $value = $this->getValue(); 302 if (!$value) { 303 return null; 304 } 305 return implode(', ', $value); 306 } 307 308 public function shouldAppearInConduitDictionary() { 309 return true; 310 } 311 312 313 }
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 |