[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class HeraldDifferentialRevisionAdapter 4 extends HeraldDifferentialAdapter { 5 6 protected $revision; 7 8 protected $explicitCCs; 9 protected $explicitReviewers; 10 protected $forbiddenCCs; 11 12 protected $newCCs = array(); 13 protected $remCCs = array(); 14 protected $emailPHIDs = array(); 15 protected $addReviewerPHIDs = array(); 16 protected $blockingReviewerPHIDs = array(); 17 protected $buildPlans = array(); 18 protected $requiredSignatureDocumentPHIDs = array(); 19 20 protected $affectedPackages; 21 protected $changesets; 22 private $haveHunks; 23 24 public function getAdapterApplicationClass() { 25 return 'PhabricatorDifferentialApplication'; 26 } 27 28 public function getObject() { 29 return $this->revision; 30 } 31 32 public function getDiff() { 33 return $this->diff; 34 } 35 36 public function getAdapterContentType() { 37 return 'differential'; 38 } 39 40 public function getAdapterContentName() { 41 return pht('Differential Revisions'); 42 } 43 44 public function getAdapterContentDescription() { 45 return pht( 46 "React to revisions being created or updated.\n". 47 "Revision rules can send email, flag revisions, add reviewers, ". 48 "and run build plans."); 49 } 50 51 public function supportsRuleType($rule_type) { 52 switch ($rule_type) { 53 case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL: 54 case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL: 55 return true; 56 case HeraldRuleTypeConfig::RULE_TYPE_OBJECT: 57 default: 58 return false; 59 } 60 } 61 62 public function getFields() { 63 return array_merge( 64 array( 65 self::FIELD_TITLE, 66 self::FIELD_BODY, 67 self::FIELD_AUTHOR, 68 self::FIELD_AUTHOR_PROJECTS, 69 self::FIELD_REVIEWERS, 70 self::FIELD_CC, 71 self::FIELD_REPOSITORY, 72 self::FIELD_REPOSITORY_PROJECTS, 73 self::FIELD_DIFF_FILE, 74 self::FIELD_DIFF_CONTENT, 75 self::FIELD_DIFF_ADDED_CONTENT, 76 self::FIELD_DIFF_REMOVED_CONTENT, 77 self::FIELD_AFFECTED_PACKAGE, 78 self::FIELD_AFFECTED_PACKAGE_OWNER, 79 self::FIELD_IS_NEW_OBJECT, 80 self::FIELD_ARCANIST_PROJECT, 81 ), 82 parent::getFields()); 83 } 84 85 public function getRepetitionOptions() { 86 return array( 87 HeraldRepetitionPolicyConfig::EVERY, 88 HeraldRepetitionPolicyConfig::FIRST, 89 ); 90 } 91 92 public static function newLegacyAdapter( 93 DifferentialRevision $revision, 94 DifferentialDiff $diff) { 95 $object = new HeraldDifferentialRevisionAdapter(); 96 97 // Reload the revision to pick up relationship information. 98 $revision = id(new DifferentialRevisionQuery()) 99 ->withIDs(array($revision->getID())) 100 ->setViewer(PhabricatorUser::getOmnipotentUser()) 101 ->needRelationships(true) 102 ->needReviewerStatus(true) 103 ->executeOne(); 104 105 $object->revision = $revision; 106 $object->diff = $diff; 107 108 return $object; 109 } 110 111 public function setExplicitCCs($explicit_ccs) { 112 $this->explicitCCs = $explicit_ccs; 113 return $this; 114 } 115 116 public function setExplicitReviewers($explicit_reviewers) { 117 $this->explicitReviewers = $explicit_reviewers; 118 return $this; 119 } 120 121 public function setForbiddenCCs($forbidden_ccs) { 122 $this->forbiddenCCs = $forbidden_ccs; 123 return $this; 124 } 125 126 public function getCCsAddedByHerald() { 127 return array_diff_key($this->newCCs, $this->remCCs); 128 } 129 130 public function getCCsRemovedByHerald() { 131 return $this->remCCs; 132 } 133 134 public function getEmailPHIDsAddedByHerald() { 135 return $this->emailPHIDs; 136 } 137 138 public function getReviewersAddedByHerald() { 139 return $this->addReviewerPHIDs; 140 } 141 142 public function getBlockingReviewersAddedByHerald() { 143 return $this->blockingReviewerPHIDs; 144 } 145 146 public function getRequiredSignatureDocumentPHIDs() { 147 return $this->requiredSignatureDocumentPHIDs; 148 } 149 150 public function getBuildPlans() { 151 return $this->buildPlans; 152 } 153 154 public function getPHID() { 155 return $this->revision->getPHID(); 156 } 157 158 public function getHeraldName() { 159 return $this->revision->getTitle(); 160 } 161 162 protected function loadChangesets() { 163 if ($this->changesets === null) { 164 $this->changesets = $this->diff->loadChangesets(); 165 } 166 return $this->changesets; 167 } 168 169 protected function loadChangesetsWithHunks() { 170 $changesets = $this->loadChangesets(); 171 172 if ($changesets && !$this->haveHunks) { 173 $this->haveHunks = true; 174 175 id(new DifferentialHunkQuery()) 176 ->setViewer(PhabricatorUser::getOmnipotentUser()) 177 ->withChangesets($changesets) 178 ->needAttachToChangesets(true) 179 ->execute(); 180 } 181 182 return $changesets; 183 } 184 185 public function loadAffectedPackages() { 186 if ($this->affectedPackages === null) { 187 $this->affectedPackages = array(); 188 189 $repository = $this->loadRepository(); 190 if ($repository) { 191 $packages = PhabricatorOwnersPackage::loadAffectedPackages( 192 $repository, 193 $this->loadAffectedPaths()); 194 $this->affectedPackages = $packages; 195 } 196 } 197 return $this->affectedPackages; 198 } 199 200 public function getHeraldField($field) { 201 switch ($field) { 202 case self::FIELD_TITLE: 203 return $this->revision->getTitle(); 204 break; 205 case self::FIELD_BODY: 206 return $this->revision->getSummary()."\n". 207 $this->revision->getTestPlan(); 208 break; 209 case self::FIELD_AUTHOR: 210 return $this->revision->getAuthorPHID(); 211 break; 212 case self::FIELD_AUTHOR_PROJECTS: 213 $author_phid = $this->revision->getAuthorPHID(); 214 if (!$author_phid) { 215 return array(); 216 } 217 218 $projects = id(new PhabricatorProjectQuery()) 219 ->setViewer(PhabricatorUser::getOmnipotentUser()) 220 ->withMemberPHIDs(array($author_phid)) 221 ->execute(); 222 223 return mpull($projects, 'getPHID'); 224 case self::FIELD_DIFF_FILE: 225 return $this->loadAffectedPaths(); 226 case self::FIELD_CC: 227 if (isset($this->explicitCCs)) { 228 return array_keys($this->explicitCCs); 229 } else { 230 return $this->revision->getCCPHIDs(); 231 } 232 case self::FIELD_REVIEWERS: 233 if (isset($this->explicitReviewers)) { 234 return array_keys($this->explicitReviewers); 235 } else { 236 return $this->revision->getReviewers(); 237 } 238 case self::FIELD_REPOSITORY: 239 $repository = $this->loadRepository(); 240 if (!$repository) { 241 return null; 242 } 243 return $repository->getPHID(); 244 case self::FIELD_REPOSITORY_PROJECTS: 245 $repository = $this->loadRepository(); 246 if (!$repository) { 247 return array(); 248 } 249 return $repository->getProjectPHIDs(); 250 case self::FIELD_DIFF_CONTENT: 251 return $this->loadContentDictionary(); 252 case self::FIELD_DIFF_ADDED_CONTENT: 253 return $this->loadAddedContentDictionary(); 254 case self::FIELD_DIFF_REMOVED_CONTENT: 255 return $this->loadRemovedContentDictionary(); 256 case self::FIELD_AFFECTED_PACKAGE: 257 $packages = $this->loadAffectedPackages(); 258 return mpull($packages, 'getPHID'); 259 case self::FIELD_AFFECTED_PACKAGE_OWNER: 260 $packages = $this->loadAffectedPackages(); 261 return PhabricatorOwnersOwner::loadAffiliatedUserPHIDs( 262 mpull($packages, 'getID')); 263 case self::FIELD_ARCANIST_PROJECT: 264 return $this->revision->getArcanistProjectPHID(); 265 } 266 267 return parent::getHeraldField($field); 268 } 269 270 public function getActions($rule_type) { 271 switch ($rule_type) { 272 case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL: 273 return array_merge( 274 array( 275 self::ACTION_ADD_CC, 276 self::ACTION_REMOVE_CC, 277 self::ACTION_EMAIL, 278 self::ACTION_ADD_REVIEWERS, 279 self::ACTION_ADD_BLOCKING_REVIEWERS, 280 self::ACTION_APPLY_BUILD_PLANS, 281 self::ACTION_REQUIRE_SIGNATURE, 282 self::ACTION_NOTHING, 283 ), 284 parent::getActions($rule_type)); 285 case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL: 286 return array_merge( 287 array( 288 self::ACTION_ADD_CC, 289 self::ACTION_REMOVE_CC, 290 self::ACTION_EMAIL, 291 self::ACTION_FLAG, 292 self::ACTION_ADD_REVIEWERS, 293 self::ACTION_ADD_BLOCKING_REVIEWERS, 294 self::ACTION_NOTHING, 295 ), 296 parent::getActions($rule_type)); 297 } 298 } 299 300 public function applyHeraldEffects(array $effects) { 301 assert_instances_of($effects, 'HeraldEffect'); 302 303 $result = array(); 304 if ($this->explicitCCs) { 305 $effect = new HeraldEffect(); 306 $effect->setAction(self::ACTION_ADD_CC); 307 $effect->setTarget(array_keys($this->explicitCCs)); 308 $effect->setReason( 309 pht('CCs provided explicitly by revision author or carried over '. 310 'from a previous version of the revision.')); 311 $result[] = new HeraldApplyTranscript( 312 $effect, 313 true, 314 pht('Added addresses to CC list.')); 315 } 316 317 $forbidden_ccs = array_fill_keys( 318 nonempty($this->forbiddenCCs, array()), 319 true); 320 321 foreach ($effects as $effect) { 322 $action = $effect->getAction(); 323 switch ($action) { 324 case self::ACTION_NOTHING: 325 $result[] = new HeraldApplyTranscript( 326 $effect, 327 true, 328 pht('OK, did nothing.')); 329 break; 330 case self::ACTION_FLAG: 331 $result[] = parent::applyFlagEffect( 332 $effect, 333 $this->revision->getPHID()); 334 break; 335 case self::ACTION_EMAIL: 336 case self::ACTION_ADD_CC: 337 $op = ($action == self::ACTION_EMAIL) ? 'email' : 'CC'; 338 $base_target = $effect->getTarget(); 339 $forbidden = array(); 340 foreach ($base_target as $key => $fbid) { 341 if (isset($forbidden_ccs[$fbid])) { 342 $forbidden[] = $fbid; 343 unset($base_target[$key]); 344 } else { 345 if ($action == self::ACTION_EMAIL) { 346 $this->emailPHIDs[$fbid] = true; 347 } else { 348 $this->newCCs[$fbid] = true; 349 } 350 } 351 } 352 353 if ($forbidden) { 354 $failed = clone $effect; 355 $failed->setTarget($forbidden); 356 if ($base_target) { 357 $effect->setTarget($base_target); 358 $result[] = new HeraldApplyTranscript( 359 $effect, 360 true, 361 pht('Added these addresses to %s list. '. 362 'Others could not be added.', $op)); 363 } 364 $result[] = new HeraldApplyTranscript( 365 $failed, 366 false, 367 pht('%s forbidden, these addresses have unsubscribed.', $op)); 368 } else { 369 $result[] = new HeraldApplyTranscript( 370 $effect, 371 true, 372 pht('Added addresses to %s list.', $op)); 373 } 374 break; 375 case self::ACTION_REMOVE_CC: 376 foreach ($effect->getTarget() as $fbid) { 377 $this->remCCs[$fbid] = true; 378 } 379 $result[] = new HeraldApplyTranscript( 380 $effect, 381 true, 382 pht('Removed addresses from CC list.')); 383 break; 384 case self::ACTION_ADD_REVIEWERS: 385 foreach ($effect->getTarget() as $phid) { 386 $this->addReviewerPHIDs[$phid] = true; 387 } 388 $result[] = new HeraldApplyTranscript( 389 $effect, 390 true, 391 pht('Added reviewers.')); 392 break; 393 case self::ACTION_ADD_BLOCKING_REVIEWERS: 394 // This adds reviewers normally, it just also marks them blocking. 395 foreach ($effect->getTarget() as $phid) { 396 $this->addReviewerPHIDs[$phid] = true; 397 $this->blockingReviewerPHIDs[$phid] = true; 398 } 399 $result[] = new HeraldApplyTranscript( 400 $effect, 401 true, 402 pht('Added blocking reviewers.')); 403 break; 404 case self::ACTION_APPLY_BUILD_PLANS: 405 foreach ($effect->getTarget() as $phid) { 406 $this->buildPlans[] = $phid; 407 } 408 $result[] = new HeraldApplyTranscript( 409 $effect, 410 true, 411 pht('Applied build plans.')); 412 break; 413 case self::ACTION_REQUIRE_SIGNATURE: 414 foreach ($effect->getTarget() as $phid) { 415 $this->requiredSignatureDocumentPHIDs[] = $phid; 416 } 417 $result[] = new HeraldApplyTranscript( 418 $effect, 419 true, 420 pht('Required signatures.')); 421 break; 422 default: 423 $custom_result = parent::handleCustomHeraldEffect($effect); 424 if ($custom_result === null) { 425 throw new Exception(pht( 426 "No rules to handle action '%s'.", 427 $action)); 428 } 429 430 $result[] = $custom_result; 431 break; 432 } 433 } 434 return $result; 435 } 436 437 }
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 |