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

Remove DifferentialCommentEditor and DifferentialCommentMail

Summary: Ref T2222. These no longer have any callsites. Also got rid of a little bit of other code which also no longer has callsites.

Test Plan: `grep`

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2222

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

+1 -1097
+1 -7
src/__phutil_library_map__.php
··· 317 317 'DatabaseConfigurationProvider' => 'infrastructure/storage/configuration/DatabaseConfigurationProvider.php', 318 318 'DefaultDatabaseConfigurationProvider' => 'infrastructure/storage/configuration/DefaultDatabaseConfigurationProvider.php', 319 319 'DifferentialAction' => 'applications/differential/constants/DifferentialAction.php', 320 - 'DifferentialActionHasNoEffectException' => 'applications/differential/exception/DifferentialActionHasNoEffectException.php', 321 320 'DifferentialActionMenuEventListener' => 'applications/differential/event/DifferentialActionMenuEventListener.php', 322 321 'DifferentialAddCommentView' => 'applications/differential/view/DifferentialAddCommentView.php', 323 322 'DifferentialAffectedPath' => 'applications/differential/storage/DifferentialAffectedPath.php', ··· 354 353 'DifferentialChangesetTwoUpTestRenderer' => 'applications/differential/render/DifferentialChangesetTwoUpTestRenderer.php', 355 354 'DifferentialChangesetViewController' => 'applications/differential/controller/DifferentialChangesetViewController.php', 356 355 'DifferentialComment' => 'applications/differential/storage/DifferentialComment.php', 357 - 'DifferentialCommentEditor' => 'applications/differential/editor/DifferentialCommentEditor.php', 358 - 'DifferentialCommentMail' => 'applications/differential/mail/DifferentialCommentMail.php', 359 356 'DifferentialCommentPreviewController' => 'applications/differential/controller/DifferentialCommentPreviewController.php', 360 357 'DifferentialCommentQuery' => 'applications/differential/query/DifferentialCommentQuery.php', 361 358 'DifferentialCommentSaveController' => 'applications/differential/controller/DifferentialCommentSaveController.php', ··· 2708 2705 'ConduitAPI_conpherence_querytransaction_Method' => 'ConduitAPI_conpherence_Method', 2709 2706 'ConduitAPI_conpherence_updatethread_Method' => 'ConduitAPI_conpherence_Method', 2710 2707 'ConduitAPI_differential_Method' => 'ConduitAPIMethod', 2711 - 'ConduitAPI_differential_close_Method' => 'ConduitAPIMethod', 2708 + 'ConduitAPI_differential_close_Method' => 'ConduitAPI_differential_Method', 2712 2709 'ConduitAPI_differential_createcomment_Method' => 'ConduitAPIMethod', 2713 2710 'ConduitAPI_differential_creatediff_Method' => 'ConduitAPIMethod', 2714 2711 'ConduitAPI_differential_createinline_Method' => 'ConduitAPI_differential_Method', ··· 2888 2885 'DarkConsoleServicesPlugin' => 'DarkConsolePlugin', 2889 2886 'DarkConsoleXHProfPlugin' => 'DarkConsolePlugin', 2890 2887 'DefaultDatabaseConfigurationProvider' => 'DatabaseConfigurationProvider', 2891 - 'DifferentialActionHasNoEffectException' => 'DifferentialException', 2892 2888 'DifferentialActionMenuEventListener' => 'PhabricatorEventListener', 2893 2889 'DifferentialAddCommentView' => 'AphrontView', 2894 2890 'DifferentialAffectedPath' => 'DifferentialDAO', ··· 2920 2916 'DifferentialChangesetTwoUpTestRenderer' => 'DifferentialChangesetTestRenderer', 2921 2917 'DifferentialChangesetViewController' => 'DifferentialController', 2922 2918 'DifferentialComment' => 'PhabricatorMarkupInterface', 2923 - 'DifferentialCommentEditor' => 'PhabricatorEditor', 2924 - 'DifferentialCommentMail' => 'DifferentialMail', 2925 2919 'DifferentialCommentPreviewController' => 'DifferentialController', 2926 2920 'DifferentialCommentQuery' => 'PhabricatorOffsetPagedQuery', 2927 2921 'DifferentialCommentSaveController' => 'DifferentialController',
-800
src/applications/differential/editor/DifferentialCommentEditor.php
··· 1 - <?php 2 - 3 - final class DifferentialCommentEditor extends PhabricatorEditor { 4 - 5 - protected $revision; 6 - protected $action; 7 - 8 - protected $attachInlineComments; 9 - protected $message; 10 - protected $changedByCommit; 11 - protected $addedReviewers = array(); 12 - protected $removedReviewers = array(); 13 - private $addedCCs = array(); 14 - 15 - private $parentMessageID; 16 - private $contentSource; 17 - private $noEmail; 18 - 19 - private $isDaemonWorkflow; 20 - 21 - public function __construct( 22 - DifferentialRevision $revision, 23 - $action) { 24 - 25 - $this->revision = $revision; 26 - $this->action = $action; 27 - } 28 - 29 - public function setParentMessageID($parent_message_id) { 30 - $this->parentMessageID = $parent_message_id; 31 - return $this; 32 - } 33 - 34 - public function setMessage($message) { 35 - $this->message = $message; 36 - return $this; 37 - } 38 - 39 - public function setAttachInlineComments($attach) { 40 - $this->attachInlineComments = $attach; 41 - return $this; 42 - } 43 - 44 - public function setChangedByCommit($changed_by_commit) { 45 - $this->changedByCommit = $changed_by_commit; 46 - return $this; 47 - } 48 - 49 - public function getChangedByCommit() { 50 - return $this->changedByCommit; 51 - } 52 - 53 - public function setAddedReviewers(array $added_reviewers) { 54 - $this->addedReviewers = $added_reviewers; 55 - return $this; 56 - } 57 - 58 - public function getAddedReviewers() { 59 - return $this->addedReviewers; 60 - } 61 - 62 - public function setRemovedReviewers(array $removeded_reviewers) { 63 - $this->removedReviewers = $removeded_reviewers; 64 - return $this; 65 - } 66 - 67 - public function getRemovedReviewers() { 68 - return $this->removedReviewers; 69 - } 70 - 71 - public function setAddedCCs($added_ccs) { 72 - $this->addedCCs = $added_ccs; 73 - return $this; 74 - } 75 - 76 - public function getAddedCCs() { 77 - return $this->addedCCs; 78 - } 79 - 80 - public function setContentSource(PhabricatorContentSource $content_source) { 81 - $this->contentSource = $content_source; 82 - return $this; 83 - } 84 - 85 - public function setIsDaemonWorkflow($is_daemon) { 86 - $this->isDaemonWorkflow = $is_daemon; 87 - return $this; 88 - } 89 - 90 - public function setNoEmail($no_email) { 91 - $this->noEmail = $no_email; 92 - return $this; 93 - } 94 - 95 - public function save() { 96 - $actor = $this->requireActor(); 97 - 98 - // Reload the revision to pick up reviewer status, until we can lift this 99 - // out of here. 100 - $this->revision = id(new DifferentialRevisionQuery()) 101 - ->setViewer($actor) 102 - ->withIDs(array($this->revision->getID())) 103 - ->needRelationships(true) 104 - ->needReviewerStatus(true) 105 - ->needReviewerAuthority(true) 106 - ->executeOne(); 107 - 108 - $revision = $this->revision; 109 - $action = $this->action; 110 - $actor_phid = $actor->getPHID(); 111 - $actor_is_author = ($actor_phid == $revision->getAuthorPHID()); 112 - $allow_self_accept = PhabricatorEnv::getEnvConfig( 113 - 'differential.allow-self-accept'); 114 - $always_allow_close = PhabricatorEnv::getEnvConfig( 115 - 'differential.always-allow-close'); 116 - $allow_reopen = PhabricatorEnv::getEnvConfig( 117 - 'differential.allow-reopen'); 118 - $revision_status = $revision->getStatus(); 119 - $update_accepted_status = false; 120 - 121 - $reviewer_phids = $revision->getReviewers(); 122 - if ($reviewer_phids) { 123 - $reviewer_phids = array_fuse($reviewer_phids); 124 - } 125 - 126 - $metadata = array(); 127 - 128 - $inline_comments = array(); 129 - if ($this->attachInlineComments) { 130 - $inline_comments = id(new DifferentialInlineCommentQuery()) 131 - ->withDraftComments($actor_phid, $revision->getID()) 132 - ->execute(); 133 - } 134 - 135 - switch ($action) { 136 - case DifferentialAction::ACTION_COMMENT: 137 - if (!$this->message && !$inline_comments) { 138 - throw new DifferentialActionHasNoEffectException( 139 - "You are submitting an empty comment with no action: ". 140 - "you must act on the revision or post a comment."); 141 - } 142 - 143 - // If the actor is a reviewer, and their status is "added" (that is, 144 - // they haven't accepted or requested changes to the revision), 145 - // upgrade their status to "commented". If they have a stronger status 146 - // already, don't overwrite it. 147 - if (isset($reviewer_phids[$actor_phid])) { 148 - $status_added = DifferentialReviewerStatus::STATUS_ADDED; 149 - $reviewer_status = $revision->getReviewerStatus(); 150 - foreach ($reviewer_status as $reviewer) { 151 - if ($reviewer->getReviewerPHID() == $actor_phid) { 152 - if ($reviewer->getStatus() == $status_added) { 153 - DifferentialRevisionEditor::updateReviewerStatus( 154 - $revision, 155 - $actor, 156 - $actor_phid, 157 - DifferentialReviewerStatus::STATUS_COMMENTED); 158 - } 159 - } 160 - } 161 - } 162 - 163 - break; 164 - 165 - case DifferentialAction::ACTION_RESIGN: 166 - if ($actor_is_author) { 167 - throw new Exception('You can not resign from your own revision!'); 168 - } 169 - if (empty($reviewer_phids[$actor_phid])) { 170 - throw new DifferentialActionHasNoEffectException( 171 - "You can not resign from this revision because you are not ". 172 - "a reviewer."); 173 - } 174 - 175 - list($added_reviewers, $ignored) = $this->alterReviewers(); 176 - if ($added_reviewers) { 177 - $key = DifferentialComment::METADATA_ADDED_REVIEWERS; 178 - $metadata[$key] = $added_reviewers; 179 - } 180 - 181 - DifferentialRevisionEditor::updateReviewers( 182 - $revision, 183 - $actor, 184 - array(), 185 - array($actor_phid)); 186 - 187 - // If you are a blocking reviewer, your presence as a reviewer may be 188 - // the only thing keeping a revision from transitioning to "accepted". 189 - // Recalculate state after removing the resigning reviewer. 190 - switch ($revision_status) { 191 - case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: 192 - case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: 193 - $update_accepted_status = true; 194 - break; 195 - } 196 - 197 - break; 198 - 199 - case DifferentialAction::ACTION_ABANDON: 200 - if (!$actor_is_author) { 201 - throw new Exception('You can only abandon your own revisions.'); 202 - } 203 - 204 - if ($revision_status == ArcanistDifferentialRevisionStatus::CLOSED) { 205 - throw new DifferentialActionHasNoEffectException( 206 - "You can not abandon this revision because it has already ". 207 - "been closed."); 208 - } 209 - 210 - if ($revision_status == ArcanistDifferentialRevisionStatus::ABANDONED) { 211 - throw new DifferentialActionHasNoEffectException( 212 - "You can not abandon this revision because it has already ". 213 - "been abandoned."); 214 - } 215 - 216 - $revision->setStatus(ArcanistDifferentialRevisionStatus::ABANDONED); 217 - break; 218 - 219 - case DifferentialAction::ACTION_ACCEPT: 220 - if ($actor_is_author && !$allow_self_accept) { 221 - throw new Exception('You can not accept your own revision.'); 222 - } 223 - 224 - switch ($revision_status) { 225 - case ArcanistDifferentialRevisionStatus::ABANDONED: 226 - throw new DifferentialActionHasNoEffectException( 227 - "You can not accept this revision because it has been ". 228 - "abandoned."); 229 - case ArcanistDifferentialRevisionStatus::CLOSED: 230 - throw new DifferentialActionHasNoEffectException( 231 - "You can not accept this revision because it has already ". 232 - "been closed."); 233 - case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: 234 - case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: 235 - case ArcanistDifferentialRevisionStatus::ACCEPTED: 236 - // We expect "Accept" from these states. 237 - break; 238 - default: 239 - throw new Exception( 240 - "Unexpected revision state '{$revision_status}'!"); 241 - } 242 - 243 - $was_reviewer_already = false; 244 - foreach ($revision->getReviewerStatus() as $reviewer) { 245 - if ($reviewer->hasAuthority($actor)) { 246 - DifferentialRevisionEditor::updateReviewerStatus( 247 - $revision, 248 - $actor, 249 - $reviewer->getReviewerPHID(), 250 - DifferentialReviewerStatus::STATUS_ACCEPTED); 251 - if ($reviewer->getReviewerPHID() == $actor_phid) { 252 - $was_reviewer_already = true; 253 - } 254 - } 255 - } 256 - 257 - if (!$was_reviewer_already) { 258 - DifferentialRevisionEditor::updateReviewerStatus( 259 - $revision, 260 - $actor, 261 - $actor_phid, 262 - DifferentialReviewerStatus::STATUS_ACCEPTED); 263 - } 264 - 265 - $update_accepted_status = true; 266 - break; 267 - 268 - case DifferentialAction::ACTION_REQUEST: 269 - if (!$actor_is_author) { 270 - throw new Exception('You must own a revision to request review.'); 271 - } 272 - 273 - switch ($revision_status) { 274 - case ArcanistDifferentialRevisionStatus::ACCEPTED: 275 - case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: 276 - $revision->setStatus( 277 - ArcanistDifferentialRevisionStatus::NEEDS_REVIEW); 278 - break; 279 - case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: 280 - throw new DifferentialActionHasNoEffectException( 281 - "You can not request review of this revision because it has ". 282 - "been abandoned."); 283 - case ArcanistDifferentialRevisionStatus::ABANDONED: 284 - throw new DifferentialActionHasNoEffectException( 285 - "You can not request review of this revision because it has ". 286 - "been abandoned."); 287 - case ArcanistDifferentialRevisionStatus::CLOSED: 288 - throw new DifferentialActionHasNoEffectException( 289 - "You can not request review of this revision because it has ". 290 - "already been closed."); 291 - default: 292 - throw new Exception( 293 - "Unexpected revision state '{$revision_status}'!"); 294 - } 295 - 296 - list($added_reviewers, $ignored) = $this->alterReviewers(); 297 - if ($added_reviewers) { 298 - $key = DifferentialComment::METADATA_ADDED_REVIEWERS; 299 - $metadata[$key] = $added_reviewers; 300 - } 301 - 302 - break; 303 - 304 - case DifferentialAction::ACTION_REJECT: 305 - if ($actor_is_author) { 306 - throw new Exception( 307 - 'You can not request changes to your own revision.'); 308 - } 309 - 310 - switch ($revision_status) { 311 - case ArcanistDifferentialRevisionStatus::ACCEPTED: 312 - case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: 313 - case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: 314 - // We expect rejects from these states. 315 - break; 316 - case ArcanistDifferentialRevisionStatus::ABANDONED: 317 - throw new DifferentialActionHasNoEffectException( 318 - "You can not request changes to this revision because it has ". 319 - "been abandoned."); 320 - case ArcanistDifferentialRevisionStatus::CLOSED: 321 - throw new DifferentialActionHasNoEffectException( 322 - "You can not request changes to this revision because it has ". 323 - "already been closed."); 324 - default: 325 - throw new Exception( 326 - "Unexpected revision state '{$revision_status}'!"); 327 - } 328 - 329 - DifferentialRevisionEditor::updateReviewerStatus( 330 - $revision, 331 - $actor, 332 - $actor_phid, 333 - DifferentialReviewerStatus::STATUS_REJECTED); 334 - 335 - $revision 336 - ->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVISION); 337 - break; 338 - 339 - case DifferentialAction::ACTION_RETHINK: 340 - if (!$actor_is_author) { 341 - throw new Exception( 342 - "You can not plan changes to somebody else's revision"); 343 - } 344 - 345 - switch ($revision_status) { 346 - case ArcanistDifferentialRevisionStatus::ACCEPTED: 347 - case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: 348 - case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: 349 - // We expect accepts from these states. 350 - break; 351 - case ArcanistDifferentialRevisionStatus::ABANDONED: 352 - throw new DifferentialActionHasNoEffectException( 353 - "You can not plan changes to this revision because it has ". 354 - "been abandoned."); 355 - case ArcanistDifferentialRevisionStatus::CLOSED: 356 - throw new DifferentialActionHasNoEffectException( 357 - "You can not plan changes to this revision because it has ". 358 - "already been closed."); 359 - default: 360 - throw new Exception( 361 - "Unexpected revision state '{$revision_status}'!"); 362 - } 363 - 364 - $revision 365 - ->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVISION); 366 - break; 367 - 368 - case DifferentialAction::ACTION_RECLAIM: 369 - if (!$actor_is_author) { 370 - throw new Exception('You can not reclaim a revision you do not own.'); 371 - } 372 - 373 - 374 - if ($revision_status != ArcanistDifferentialRevisionStatus::ABANDONED) { 375 - throw new DifferentialActionHasNoEffectException( 376 - "You can not reclaim this revision because it is not abandoned."); 377 - } 378 - 379 - $revision 380 - ->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVIEW); 381 - 382 - $update_accepted_status = true; 383 - break; 384 - 385 - case DifferentialAction::ACTION_CLOSE: 386 - 387 - // NOTE: The daemons can mark things closed from any state. We treat 388 - // them as completely authoritative. 389 - 390 - if (!$this->isDaemonWorkflow) { 391 - if (!$actor_is_author && !$always_allow_close) { 392 - throw new Exception( 393 - "You can not mark a revision you don't own as closed."); 394 - } 395 - 396 - $status_closed = ArcanistDifferentialRevisionStatus::CLOSED; 397 - $status_accepted = ArcanistDifferentialRevisionStatus::ACCEPTED; 398 - 399 - if ($revision_status == $status_closed) { 400 - throw new DifferentialActionHasNoEffectException( 401 - "You can not mark this revision as closed because it has ". 402 - "already been marked as closed."); 403 - } 404 - 405 - if ($revision_status != $status_accepted) { 406 - throw new DifferentialActionHasNoEffectException( 407 - "You can not mark this revision as closed because it is ". 408 - "has not been accepted."); 409 - } 410 - } 411 - 412 - $revision->setStatus(ArcanistDifferentialRevisionStatus::CLOSED); 413 - break; 414 - 415 - case DifferentialAction::ACTION_REOPEN: 416 - if (!$allow_reopen) { 417 - throw new Exception( 418 - "You cannot reopen a revision when this action is disabled."); 419 - } 420 - 421 - if ($revision_status != ArcanistDifferentialRevisionStatus::CLOSED) { 422 - throw new Exception( 423 - "You cannot reopen a revision that is not currently closed."); 424 - } 425 - 426 - $revision->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVIEW); 427 - 428 - break; 429 - 430 - case DifferentialAction::ACTION_ADDREVIEWERS: 431 - list($added_reviewers, $ignored) = $this->alterReviewers(); 432 - 433 - if ($added_reviewers) { 434 - $key = DifferentialComment::METADATA_ADDED_REVIEWERS; 435 - $metadata[$key] = $added_reviewers; 436 - } else { 437 - $user_tried_to_add = count($this->getAddedReviewers()); 438 - if ($user_tried_to_add == 0) { 439 - throw new DifferentialActionHasNoEffectException( 440 - "You can not add reviewers, because you did not specify any ". 441 - "reviewers."); 442 - } else if ($user_tried_to_add == 1) { 443 - throw new DifferentialActionHasNoEffectException( 444 - "You can not add that reviewer, because they are already an ". 445 - "author or reviewer."); 446 - } else { 447 - throw new DifferentialActionHasNoEffectException( 448 - "You can not add those reviewers, because they are all already ". 449 - "authors or reviewers."); 450 - } 451 - } 452 - 453 - break; 454 - case DifferentialAction::ACTION_ADDCCS: 455 - $added_ccs = $this->getAddedCCs(); 456 - $user_tried_to_add = count($added_ccs); 457 - 458 - $added_ccs = $this->filterAddedCCs($added_ccs); 459 - 460 - if ($added_ccs) { 461 - $key = DifferentialComment::METADATA_ADDED_CCS; 462 - $metadata[$key] = $added_ccs; 463 - } else { 464 - if ($user_tried_to_add == 0) { 465 - throw new DifferentialActionHasNoEffectException( 466 - "You can not add CCs, because you did not specify any ". 467 - "CCs."); 468 - } else if ($user_tried_to_add == 1) { 469 - throw new DifferentialActionHasNoEffectException( 470 - "You can not add that CC, because they are already an ". 471 - "author, reviewer or CC."); 472 - } else { 473 - throw new DifferentialActionHasNoEffectException( 474 - "You can not add those CCs, because they are all already ". 475 - "authors, reviewers or CCs."); 476 - } 477 - } 478 - break; 479 - case DifferentialAction::ACTION_CLAIM: 480 - if ($actor_is_author) { 481 - throw new Exception("You can not commandeer your own revision."); 482 - } 483 - 484 - switch ($revision_status) { 485 - case ArcanistDifferentialRevisionStatus::CLOSED: 486 - throw new DifferentialActionHasNoEffectException( 487 - "You can not commandeer this revision because it has ". 488 - "already been closed."); 489 - break; 490 - } 491 - 492 - $this->setAddedReviewers(array($revision->getAuthorPHID())); 493 - $this->setRemovedReviewers(array($actor_phid)); 494 - 495 - // NOTE: Set the new author PHID before calling addReviewers(), since it 496 - // doesn't permit the author to become a reviewer. 497 - $revision->setAuthorPHID($actor_phid); 498 - 499 - list($added_reviewers, $removed_reviewers) = $this->alterReviewers(); 500 - if ($added_reviewers) { 501 - $key = DifferentialComment::METADATA_ADDED_REVIEWERS; 502 - $metadata[$key] = $added_reviewers; 503 - } 504 - 505 - if ($removed_reviewers) { 506 - $key = DifferentialComment::METADATA_REMOVED_REVIEWERS; 507 - $metadata[$key] = $removed_reviewers; 508 - } 509 - 510 - break; 511 - default: 512 - throw new Exception('Unsupported action.'); 513 - } 514 - 515 - // Update information about reviewer in charge. 516 - if ($action == DifferentialAction::ACTION_ACCEPT || 517 - $action == DifferentialAction::ACTION_REJECT) { 518 - $revision->setLastReviewerPHID($actor_phid); 519 - } 520 - 521 - // TODO: Call beginReadLocking() prior to loading the revision. 522 - $revision->openTransaction(); 523 - 524 - // Always save the revision (even if we didn't actually change any of its 525 - // properties) so that it jumps to the top of the revision list when sorted 526 - // by "updated". Notably, this allows "ping" comments to push it to the 527 - // top of the action list. 528 - $revision->save(); 529 - 530 - if ($update_accepted_status) { 531 - $revision = DifferentialRevisionEditor::updateAcceptedStatus( 532 - $actor, 533 - $revision); 534 - } 535 - 536 - if ($action != DifferentialAction::ACTION_RESIGN) { 537 - DifferentialRevisionEditor::addCC( 538 - $revision, 539 - $actor_phid, 540 - $actor_phid); 541 - } 542 - 543 - $is_new = !$revision->getID(); 544 - 545 - $event = new PhabricatorEvent( 546 - PhabricatorEventType::TYPE_DIFFERENTIAL_WILLEDITREVISION, 547 - array( 548 - 'revision' => $revision, 549 - 'new' => $is_new, 550 - )); 551 - 552 - $event->setUser($actor); 553 - PhutilEventEngine::dispatchEvent($event); 554 - 555 - $template = id(new DifferentialComment()) 556 - ->setAuthorPHID($actor_phid) 557 - ->setRevision($revision); 558 - 559 - if ($this->contentSource) { 560 - $content_source = $this->contentSource; 561 - } else { 562 - $content_source = PhabricatorContentSource::newForSource( 563 - PhabricatorContentSource::SOURCE_LEGACY, 564 - array()); 565 - } 566 - 567 - $template->setContentSource($content_source); 568 - 569 - $comments = array(); 570 - 571 - // If this edit performs a meaningful action, save a transaction for the 572 - // action. Do this first, since the mail currently assumes the first 573 - // transaction is the strongest. 574 - if ($action != DifferentialAction::ACTION_COMMENT && 575 - $action != DifferentialAction::ACTION_ADDREVIEWERS && 576 - $action != DifferentialAction::ACTION_ADDCCS) { 577 - $comments[] = id(clone $template) 578 - ->setAction($action); 579 - } 580 - 581 - // If this edit adds reviewers, save a transaction for those changes. 582 - $rev_add = DifferentialComment::METADATA_ADDED_REVIEWERS; 583 - $rev_rem = DifferentialComment::METADATA_REMOVED_REVIEWERS; 584 - if (idx($metadata, $rev_add) || idx($metadata, $rev_rem)) { 585 - $reviewer_meta = array_select_keys($metadata, array($rev_add, $rev_rem)); 586 - 587 - $comments[] = id(clone $template) 588 - ->setAction(DifferentialAction::ACTION_ADDREVIEWERS) 589 - ->setMetadata($reviewer_meta); 590 - } 591 - 592 - // If this edit adds CCs, save a transaction for the new CCs. We build this 593 - // for either explicit CCs, or for @mentions. First, find any "@mentions" in 594 - // the comment blocks. 595 - $content_blocks = array($this->message); 596 - foreach ($inline_comments as $inline) { 597 - $content_blocks[] = $inline->getContent(); 598 - } 599 - $mention_ccs = PhabricatorMarkupEngine::extractPHIDsFromMentions( 600 - $content_blocks); 601 - 602 - // Now, build a comment if we have explicit action CCs or mention CCs. 603 - $cc_add = DifferentialComment::METADATA_ADDED_CCS; 604 - if (idx($metadata, $cc_add) || $mention_ccs) { 605 - $all_adds = array_merge( 606 - idx($metadata, $cc_add, array()), 607 - $mention_ccs); 608 - $all_adds = $this->filterAddedCCs($all_adds); 609 - if ($all_adds) { 610 - $cc_meta = array( 611 - DifferentialComment::METADATA_ADDED_CCS => $all_adds, 612 - ); 613 - 614 - foreach ($all_adds as $cc_phid) { 615 - DifferentialRevisionEditor::addCC( 616 - $revision, 617 - $cc_phid, 618 - $actor_phid); 619 - } 620 - 621 - $comments[] = id(clone $template) 622 - ->setAction(DifferentialAction::ACTION_ADDCCS) 623 - ->setMetadata($cc_meta); 624 - } 625 - } 626 - 627 - // If this edit has comments or inline comments, save a transaction for 628 - // the comment content. 629 - if (strlen($this->message)) { 630 - $comments[] = id(clone $template) 631 - ->setAction(DifferentialAction::ACTION_COMMENT) 632 - ->setContent((string)$this->message); 633 - } 634 - 635 - foreach ($comments as $comment) { 636 - $comment->save(); 637 - } 638 - 639 - $changesets = array(); 640 - $mail_inlines = array(); 641 - if ($inline_comments) { 642 - $load_ids = mpull($inline_comments, 'getChangesetID'); 643 - if ($load_ids) { 644 - $load_ids = array_unique($load_ids); 645 - $changesets = id(new DifferentialChangeset())->loadAllWhere( 646 - 'id in (%Ld)', 647 - $load_ids); 648 - } 649 - foreach ($inline_comments as $inline) { 650 - $inline_xaction_comment = $inline->getTransactionCommentForSave(); 651 - $inline_xaction_comment->setRevisionPHID($revision->getPHID()); 652 - 653 - $inline_xaction = id(clone $template) 654 - ->setAction(DifferentialTransaction::TYPE_INLINE) 655 - ->setProxyComment($inline_xaction_comment) 656 - ->save(); 657 - 658 - $comments[] = $inline_xaction; 659 - $mail_inlines[] = $inline_xaction->getProxyTransaction(); 660 - } 661 - } 662 - 663 - $revision->saveTransaction(); 664 - 665 - $phids = array($actor_phid); 666 - $handles = id(new PhabricatorHandleQuery()) 667 - ->setViewer($actor) 668 - ->withPHIDs($phids) 669 - ->execute(); 670 - $actor_handle = $handles[$actor_phid]; 671 - 672 - $xherald_header = HeraldTranscript::loadXHeraldRulesHeader( 673 - $revision->getPHID()); 674 - 675 - $mailed_phids = array(); 676 - if (!$this->noEmail) { 677 - $mail = id(new DifferentialCommentMail( 678 - $revision, 679 - $actor_handle, 680 - $comments, 681 - $changesets, 682 - $mail_inlines)) 683 - ->setActor($actor) 684 - ->setExcludeMailRecipientPHIDs($this->getExcludeMailRecipientPHIDs()) 685 - ->setToPHIDs( 686 - array_merge( 687 - $revision->getReviewers(), 688 - array($revision->getAuthorPHID()))) 689 - ->setCCPHIDs($revision->getCCPHIDs()) 690 - ->setChangedByCommit($this->getChangedByCommit()) 691 - ->setXHeraldRulesHeader($xherald_header) 692 - ->setParentMessageID($this->parentMessageID) 693 - ->send(); 694 - 695 - $mailed_phids = $mail->getRawMail()->buildRecipientList(); 696 - } 697 - 698 - 699 - $event_data = array( 700 - 'revision_id' => $revision->getID(), 701 - 'revision_phid' => $revision->getPHID(), 702 - 'revision_name' => $revision->getTitle(), 703 - 'revision_author_phid' => $revision->getAuthorPHID(), 704 - 'action' => head($comments)->getAction(), 705 - 'feedback_content' => $this->message, 706 - 'actor_phid' => $actor_phid, 707 - 708 - // NOTE: Don't use this, it will be removed after ApplicationTransactions. 709 - // For now, it powers inline comment rendering over the Asana brdige. 710 - 'temporaryTransactionPHIDs' => mpull($comments, 'getPHID'), 711 - ); 712 - 713 - id(new PhabricatorFeedStoryPublisher()) 714 - ->setStoryType('PhabricatorFeedStoryDifferential') 715 - ->setStoryData($event_data) 716 - ->setStoryTime(time()) 717 - ->setStoryAuthorPHID($actor_phid) 718 - ->setRelatedPHIDs( 719 - array( 720 - $revision->getPHID(), 721 - $actor_phid, 722 - $revision->getAuthorPHID(), 723 - )) 724 - ->setPrimaryObjectPHID($revision->getPHID()) 725 - ->setSubscribedPHIDs( 726 - array_merge( 727 - array($revision->getAuthorPHID()), 728 - $revision->getReviewers(), 729 - $revision->getCCPHIDs())) 730 - ->setMailRecipientPHIDs($mailed_phids) 731 - ->publish(); 732 - 733 - id(new PhabricatorSearchIndexer()) 734 - ->queueDocumentForIndexing($revision->getPHID()); 735 - } 736 - 737 - private function filterAddedCCs(array $ccs) { 738 - $revision = $this->revision; 739 - 740 - $current_ccs = $revision->getCCPHIDs(); 741 - $current_ccs = array_fill_keys($current_ccs, true); 742 - 743 - $reviewer_phids = $revision->getReviewers(); 744 - $reviewer_phids = array_fill_keys($reviewer_phids, true); 745 - 746 - foreach ($ccs as $key => $cc) { 747 - if (isset($current_ccs[$cc])) { 748 - unset($ccs[$key]); 749 - } 750 - if (isset($reviewer_phids[$cc])) { 751 - unset($ccs[$key]); 752 - } 753 - if ($cc == $revision->getAuthorPHID()) { 754 - unset($ccs[$key]); 755 - } 756 - } 757 - 758 - return $ccs; 759 - } 760 - 761 - private function alterReviewers() { 762 - $actor_phid = $this->getActor()->getPHID(); 763 - $revision = $this->revision; 764 - $added_reviewers = $this->getAddedReviewers(); 765 - $removed_reviewers = $this->getRemovedReviewers(); 766 - $reviewer_phids = $revision->getReviewers(); 767 - $allow_self_accept = PhabricatorEnv::getEnvConfig( 768 - 'differential.allow-self-accept'); 769 - 770 - $reviewer_phids_map = array_fill_keys($reviewer_phids, true); 771 - foreach ($added_reviewers as $k => $user_phid) { 772 - if (!$allow_self_accept && $user_phid == $revision->getAuthorPHID()) { 773 - unset($added_reviewers[$k]); 774 - } 775 - if (isset($reviewer_phids_map[$user_phid])) { 776 - unset($added_reviewers[$k]); 777 - } 778 - } 779 - 780 - foreach ($removed_reviewers as $k => $user_phid) { 781 - if (!isset($reviewer_phids_map[$user_phid])) { 782 - unset($removed_reviewers[$k]); 783 - } 784 - } 785 - 786 - $added_reviewers = array_unique($added_reviewers); 787 - $removed_reviewers = array_unique($removed_reviewers); 788 - 789 - if ($added_reviewers) { 790 - DifferentialRevisionEditor::updateReviewers( 791 - $revision, 792 - $this->getActor(), 793 - $added_reviewers, 794 - $removed_reviewers); 795 - } 796 - 797 - return array($added_reviewers, $removed_reviewers); 798 - } 799 - 800 - }
-47
src/applications/differential/editor/DifferentialRevisionEditor.php
··· 153 153 return !$this->getRevision()->getID(); 154 154 } 155 155 156 - /** 157 - * A silent update does not trigger Herald rules or send emails. This is used 158 - * for auto-amends at commit time. 159 - */ 160 - public function setSilentUpdate($silent) { 161 - $this->silentUpdate = $silent; 162 - return $this; 163 - } 164 156 165 157 public function save() { 166 158 $revision = $this->getRevision(); ··· 540 532 ->queueDocumentForIndexing($revision->getPHID()); 541 533 } 542 534 543 - public static function addCC( 544 - DifferentialRevision $revision, 545 - $phid, 546 - $reason) { 547 - return self::alterCCs( 548 - $revision, 549 - $revision->getCCPHIDs(), 550 - $rem = array(), 551 - $add = array($phid), 552 - $reason); 553 - } 554 - 555 535 protected static function alterCCs( 556 536 DifferentialRevision $revision, 557 537 array $stable_phids, ··· 629 609 } 630 610 631 611 $editor->save(); 632 - } 633 - 634 - public static function updateReviewerStatus( 635 - DifferentialRevision $revision, 636 - PhabricatorUser $actor, 637 - $reviewer_phid, 638 - $status) { 639 - 640 - $options = array( 641 - 'data' => array( 642 - 'status' => $status 643 - ) 644 - ); 645 - 646 - $active_diff = $revision->loadActiveDiff(); 647 - if ($active_diff) { 648 - $options['data']['diff'] = $active_diff->getID(); 649 - } 650 - 651 - id(new PhabricatorEdgeEditor()) 652 - ->setActor($actor) 653 - ->addEdge( 654 - $revision->getPHID(), 655 - PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER, 656 - $reviewer_phid, 657 - $options) 658 - ->save(); 659 612 } 660 613 661 614 private function createComment() {
-8
src/applications/differential/exception/DifferentialActionHasNoEffectException.php
··· 1 - <?php 2 - 3 - final class DifferentialActionHasNoEffectException 4 - extends DifferentialException { 5 - 6 - 7 - 8 - }
-235
src/applications/differential/mail/DifferentialCommentMail.php
··· 1 - <?php 2 - 3 - final class DifferentialCommentMail extends DifferentialMail { 4 - 5 - protected $changedByCommit; 6 - 7 - private $addedReviewers; 8 - private $addedCCs; 9 - 10 - public function setChangedByCommit($changed_by_commit) { 11 - $this->changedByCommit = $changed_by_commit; 12 - return $this; 13 - } 14 - 15 - public function getChangedByCommit() { 16 - return $this->changedByCommit; 17 - } 18 - 19 - public function __construct( 20 - DifferentialRevision $revision, 21 - PhabricatorObjectHandle $actor, 22 - array $comments, 23 - array $changesets, 24 - array $inline_comments) { 25 - 26 - assert_instances_of($comments, 'DifferentialComment'); 27 - assert_instances_of($changesets, 'DifferentialChangeset'); 28 - assert_instances_of($inline_comments, 'DifferentialTransaction'); 29 - 30 - $this->setRevision($revision); 31 - $this->setActorHandle($actor); 32 - $this->setComments($comments); 33 - $this->setChangesets($changesets); 34 - $this->setInlineComments($inline_comments); 35 - 36 - } 37 - 38 - protected function getMailTags() { 39 - $tags = array(); 40 - 41 - foreach ($this->getComments() as $comment) { 42 - $action = $comment->getAction(); 43 - 44 - switch ($action) { 45 - case DifferentialAction::ACTION_ADDCCS: 46 - $tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_CC; 47 - break; 48 - case DifferentialAction::ACTION_CLOSE: 49 - $tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_CLOSED; 50 - break; 51 - case DifferentialAction::ACTION_ADDREVIEWERS: 52 - $tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_REVIEWERS; 53 - break; 54 - case DifferentialAction::ACTION_COMMENT: 55 - // this is a comment which we will check separately below for content 56 - break; 57 - default: 58 - $tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_OTHER; 59 - break; 60 - } 61 - 62 - $has_comment = strlen(trim($comment->getContent())); 63 - $has_inlines = (bool)$this->getInlineComments(); 64 - 65 - if ($has_comment || $has_inlines) { 66 - switch ($action) { 67 - case DifferentialAction::ACTION_CLOSE: 68 - // Commit comments are auto-generated and not especially 69 - // interesting, so don't tag them as having a comment. 70 - break; 71 - default: 72 - $tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_COMMENT; 73 - break; 74 - } 75 - } 76 - } 77 - 78 - if (!$tags) { 79 - $tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_OTHER; 80 - } 81 - 82 - return $tags; 83 - } 84 - 85 - protected function renderVaryPrefix() { 86 - $verb = ucwords($this->getVerb()); 87 - return "[{$verb}]"; 88 - } 89 - 90 - protected function getVerb() { 91 - // NOTE: Eventually, this will use getStrongestAction() transaction logic. 92 - // For now, pick the first comment. 93 - $comment = head($this->getComments()); 94 - $action = $comment->getAction(); 95 - $verb = DifferentialAction::getActionPastTenseVerb($action); 96 - return $verb; 97 - } 98 - 99 - protected function prepareBody() { 100 - parent::prepareBody(); 101 - 102 - // If the commented added reviewers or CCs, list them explicitly. 103 - $load = array(); 104 - foreach ($this->comments as $comment) { 105 - $meta = $comment->getMetadata(); 106 - $m_reviewers = idx( 107 - $meta, 108 - DifferentialComment::METADATA_ADDED_REVIEWERS, 109 - array()); 110 - $m_cc = idx( 111 - $meta, 112 - DifferentialComment::METADATA_ADDED_CCS, 113 - array()); 114 - $load[] = $m_reviewers; 115 - $load[] = $m_cc; 116 - } 117 - 118 - $load = array_mergev($load); 119 - if ($load) { 120 - $handles = id(new PhabricatorHandleQuery()) 121 - ->setViewer($this->getActor()) 122 - ->withPHIDs($load) 123 - ->execute(); 124 - if ($m_reviewers) { 125 - $this->addedReviewers = $this->renderHandleList($handles, $m_reviewers); 126 - } 127 - if ($m_cc) { 128 - $this->addedCCs = $this->renderHandleList($handles, $m_cc); 129 - } 130 - } 131 - } 132 - 133 - protected function renderBody() { 134 - // TODO: This will be ApplicationTransactions eventually, but split the 135 - // difference for now. 136 - 137 - $comment = head($this->getComments()); 138 - 139 - $actor = $this->getActorName(); 140 - $name = $this->getRevision()->getTitle(); 141 - $verb = $this->getVerb(); 142 - 143 - $body = array(); 144 - 145 - $body[] = "{$actor} has {$verb} the revision \"{$name}\"."; 146 - 147 - if ($this->addedReviewers) { 148 - $body[] = 'Added Reviewers: '.$this->addedReviewers; 149 - } 150 - if ($this->addedCCs) { 151 - $body[] = 'Added CCs: '.$this->addedCCs; 152 - } 153 - 154 - $body[] = null; 155 - 156 - foreach ($this->getComments() as $dcomment) { 157 - if ($dcomment->getAction() == DifferentialTransaction::TYPE_INLINE) { 158 - // These have comment content now, but are rendered below. 159 - continue; 160 - } 161 - $content = $dcomment->getContent(); 162 - if (strlen($content)) { 163 - $body[] = $this->formatText($content); 164 - $body[] = null; 165 - } 166 - } 167 - 168 - if ($this->getChangedByCommit()) { 169 - $body[] = 'CHANGED PRIOR TO COMMIT'; 170 - $body[] = ' '.$this->getChangedByCommit(); 171 - $body[] = null; 172 - } 173 - 174 - $context_key = 'metamta.differential.unified-comment-context'; 175 - $show_context = PhabricatorEnv::getEnvConfig($context_key); 176 - 177 - $inlines = $this->getInlineComments(); 178 - if ($inlines) { 179 - $body[] = 'INLINE COMMENTS'; 180 - $changesets = $this->getChangesets(); 181 - $hunk_parser = new DifferentialHunkParser(); 182 - 183 - if ($show_context) { 184 - foreach ($changesets as $changeset) { 185 - $changeset->attachHunks($changeset->loadHunks()); 186 - } 187 - } 188 - 189 - $inline_groups = DifferentialTransactionComment::sortAndGroupInlines( 190 - $inlines, 191 - $changesets); 192 - foreach ($inline_groups as $changeset_id => $group) { 193 - $changeset = $changesets[$changeset_id]; 194 - if (!$changeset) { 195 - continue; 196 - } 197 - foreach ($group as $inline) { 198 - $comment = $inline->getComment(); 199 - $file = $changeset->getFilename(); 200 - $start = $comment->getLineNumber(); 201 - $len = $comment->getLineLength(); 202 - if ($len) { 203 - $range = $start.'-'.($start + $len); 204 - } else { 205 - $range = $start; 206 - } 207 - 208 - $inline_content = $comment->getContent(); 209 - 210 - if (!$show_context) { 211 - $body[] = $this->formatText("{$file}:{$range} {$inline_content}"); 212 - } else { 213 - $body[] = "================"; 214 - $body[] = "Comment at: " . $file . ":" . $range; 215 - $body[] = $hunk_parser->makeContextDiff( 216 - $changeset->getHunks(), 217 - $comment->getIsNewFile(), 218 - $comment->getLineNumber(), 219 - $comment->getLineLength(), 220 - 1); 221 - $body[] = "----------------"; 222 - 223 - $body[] = $inline_content; 224 - $body[] = null; 225 - } 226 - } 227 - } 228 - $body[] = null; 229 - } 230 - 231 - $body[] = $this->renderAuxFields(DifferentialMailPhase::COMMENT); 232 - 233 - return implode("\n", $body); 234 - } 235 - }