2013-06-21 21:54:29 +02:00
|
|
|
<?php
|
|
|
|
|
2016-12-13 22:03:32 +01:00
|
|
|
final class DifferentialTransaction
|
|
|
|
extends PhabricatorModularTransaction {
|
2013-06-21 21:54:29 +02:00
|
|
|
|
2014-03-12 14:04:30 +01:00
|
|
|
private $isCommandeerSideEffect;
|
|
|
|
|
2015-06-08 01:54:53 +02:00
|
|
|
const TYPE_INLINE = 'differential:inline';
|
|
|
|
const TYPE_ACTION = 'differential:action';
|
2015-06-09 15:06:52 +02:00
|
|
|
|
2015-06-08 01:54:53 +02:00
|
|
|
const MAILTAG_REVIEWERS = 'differential-reviewers';
|
|
|
|
const MAILTAG_CLOSED = 'differential-committed';
|
|
|
|
const MAILTAG_CC = 'differential-cc';
|
|
|
|
const MAILTAG_COMMENT = 'differential-comment';
|
|
|
|
const MAILTAG_UPDATED = 'differential-updated';
|
|
|
|
const MAILTAG_REVIEW_REQUEST = 'differential-review-request';
|
|
|
|
const MAILTAG_OTHER = 'differential-other';
|
|
|
|
|
2016-12-13 22:03:32 +01:00
|
|
|
public function getBaseTransactionClass() {
|
|
|
|
return 'DifferentialRevisionTransactionType';
|
|
|
|
}
|
2014-03-12 14:04:30 +01:00
|
|
|
|
2016-12-16 18:23:07 +01:00
|
|
|
protected function newFallbackModularTransactionType() {
|
|
|
|
// TODO: This allows us to render modern strings for older transactions
|
|
|
|
// without doing a migration. At some point, we should do a migration and
|
|
|
|
// throw this away.
|
|
|
|
|
2016-12-16 18:48:40 +01:00
|
|
|
// NOTE: Old reviewer edits are raw edge transactions. They could be
|
|
|
|
// migrated to modular transactions when the rest of this migrates.
|
|
|
|
|
2016-12-16 18:23:07 +01:00
|
|
|
$xaction_type = $this->getTransactionType();
|
|
|
|
if ($xaction_type == PhabricatorTransactions::TYPE_CUSTOMFIELD) {
|
|
|
|
switch ($this->getMetadataValue('customfield:key')) {
|
|
|
|
case 'differential:title':
|
|
|
|
return new DifferentialRevisionTitleTransaction();
|
2016-12-16 18:38:58 +01:00
|
|
|
case 'differential:test-plan':
|
|
|
|
return new DifferentialRevisionTestPlanTransaction();
|
2016-12-16 18:50:54 +01:00
|
|
|
case 'differential:repository':
|
|
|
|
return new DifferentialRevisionRepositoryTransaction();
|
2016-12-16 18:23:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent::newFallbackModularTransactionType();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-03-12 14:04:30 +01:00
|
|
|
public function setIsCommandeerSideEffect($is_side_effect) {
|
|
|
|
$this->isCommandeerSideEffect = $is_side_effect;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getIsCommandeerSideEffect() {
|
|
|
|
return $this->isCommandeerSideEffect;
|
|
|
|
}
|
|
|
|
|
2013-06-21 21:54:29 +02:00
|
|
|
public function getApplicationName() {
|
|
|
|
return 'differential';
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getApplicationTransactionType() {
|
2014-07-24 00:05:46 +02:00
|
|
|
return DifferentialRevisionPHIDType::TYPECONST;
|
2013-06-21 21:54:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getApplicationTransactionCommentObject() {
|
|
|
|
return new DifferentialTransactionComment();
|
|
|
|
}
|
|
|
|
|
Transactions - deploy buildTransactionTimeline to remaining applications
Summary:
Ref T4712. Specifically...
- Differential
- needed getApplicationTransactionViewObject() implemented
- Audit
- needed getApplicationTransactionViewObject() implemented
- Repository
- one object needed PhabricatorApplicationTransactionInterface implemented
- setShouldTerminate(true)
- Ponder
- BONUS BUG FIX - leaving a comment on an answer had a bad redirect URI
- both PonderQuestion and PonderAnswer needed PhabricatorApplicationTransactionInterface implemented
- setShouldTerminate(true) on both "history" controllers
- left a "TODO" on buildAnswers on the question view controller, which is non-standard and should be re-written eventually
- Phortune
- BONUS BUG FIX - fix new user "createNewAccount" code to not fatal
- PhortuneAccount, PhortuneMerchant, and PhortuneCart needed PhabricatorApplicationTransactionInterface implemented
- setShouldTerminate(true) on Account view, merchant view, and cart view controller
- Fund
- Legalpad
- Nuance
- NuanceSource needed PhabricatorApplicationTransactionInterface implemented
- Releeph (this product is kind of a mess...)
- HACKQUEST - had to manually create an arcanist project to even be able to make a "product" and get started...!
- BONUS BUG FIX - make sure to "setName" on product edit
- ReleephProject (should be ReleepProduct...?), ReleephBranch, and ReleepRequest needed PhabricatorApplicationTransactionInterface implemented
- Harbormaster
- HarbormasterBuildable, HarbormasterBuild, HarbormasterBuildPlan, and HarbormasterBuildStep all needed PhabricatorApplicationTransactionInterface implemented
- setShouldTerminate(true) all over the place
Test Plan: foreach application, viewed the timeline(s) and made sure they still rendered
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin, epriestley
Maniphest Tasks: T4712
Differential Revision: https://secure.phabricator.com/D10925
2014-12-04 00:35:47 +01:00
|
|
|
public function getApplicationTransactionViewObject() {
|
|
|
|
return new DifferentialTransactionView();
|
|
|
|
}
|
|
|
|
|
Update overall revision status after reviewers change
Summary:
Ref T2222. This doesn't feel super clean, but doesn't feel too bad either.
Basically, Differential transactions can have secondary state-based effects (changing the overall revision status) when reviewers resign, are removed, accept, or reject revisions.
To deal with this in ApplicationTransactions, I did this:
- `applyFinalEffects()` can now alter the transaction set (notably, add new ones). This mostly matters for email, notifications and feed.
- In Differential, check for an overall revision state transition in `applyFinalEffects()` (e.g., your reject moving the revision to a rejected state).
- I'm only writing the transaction if the transition is implied and indirect.
- For example, if you "Plan Changes", that action changes the state on its own so there's no implicit state change transaction added.
The transactions themselves are kind of fluff, but it seems useful to keep a record of when state changes occurred in the transaction log. If people complain we can hide/remove them.
Test Plan: {F118143}
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T2222
Differential Revision: https://secure.phabricator.com/D8339
2014-02-25 21:36:49 +01:00
|
|
|
public function shouldHide() {
|
2014-03-08 20:21:38 +01:00
|
|
|
$old = $this->getOldValue();
|
|
|
|
$new = $this->getNewValue();
|
|
|
|
|
Update overall revision status after reviewers change
Summary:
Ref T2222. This doesn't feel super clean, but doesn't feel too bad either.
Basically, Differential transactions can have secondary state-based effects (changing the overall revision status) when reviewers resign, are removed, accept, or reject revisions.
To deal with this in ApplicationTransactions, I did this:
- `applyFinalEffects()` can now alter the transaction set (notably, add new ones). This mostly matters for email, notifications and feed.
- In Differential, check for an overall revision state transition in `applyFinalEffects()` (e.g., your reject moving the revision to a rejected state).
- I'm only writing the transaction if the transition is implied and indirect.
- For example, if you "Plan Changes", that action changes the state on its own so there's no implicit state change transaction added.
The transactions themselves are kind of fluff, but it seems useful to keep a record of when state changes occurred in the transaction log. If people complain we can hide/remove them.
Test Plan: {F118143}
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T2222
Differential Revision: https://secure.phabricator.com/D8339
2014-02-25 21:36:49 +01:00
|
|
|
switch ($this->getTransactionType()) {
|
2018-01-19 23:23:53 +01:00
|
|
|
case DifferentialRevisionRequestReviewTransaction::TRANSACTIONTYPE:
|
|
|
|
// Don't hide the initial "X requested review: ..." transaction from
|
|
|
|
// mail or feed even when it occurs during creation. We need this
|
|
|
|
// transaction to survive so we'll generate mail and feed stories when
|
|
|
|
// revisions immediately leave the draft state. See T13035 for
|
|
|
|
// discussion.
|
|
|
|
return false;
|
Update overall revision status after reviewers change
Summary:
Ref T2222. This doesn't feel super clean, but doesn't feel too bad either.
Basically, Differential transactions can have secondary state-based effects (changing the overall revision status) when reviewers resign, are removed, accept, or reject revisions.
To deal with this in ApplicationTransactions, I did this:
- `applyFinalEffects()` can now alter the transaction set (notably, add new ones). This mostly matters for email, notifications and feed.
- In Differential, check for an overall revision state transition in `applyFinalEffects()` (e.g., your reject moving the revision to a rejected state).
- I'm only writing the transaction if the transition is implied and indirect.
- For example, if you "Plan Changes", that action changes the state on its own so there's no implicit state change transaction added.
The transactions themselves are kind of fluff, but it seems useful to keep a record of when state changes occurred in the transaction log. If people complain we can hide/remove them.
Test Plan: {F118143}
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T2222
Differential Revision: https://secure.phabricator.com/D8339
2014-02-25 21:36:49 +01:00
|
|
|
}
|
|
|
|
|
2014-03-08 20:21:38 +01:00
|
|
|
return parent::shouldHide();
|
Update overall revision status after reviewers change
Summary:
Ref T2222. This doesn't feel super clean, but doesn't feel too bad either.
Basically, Differential transactions can have secondary state-based effects (changing the overall revision status) when reviewers resign, are removed, accept, or reject revisions.
To deal with this in ApplicationTransactions, I did this:
- `applyFinalEffects()` can now alter the transaction set (notably, add new ones). This mostly matters for email, notifications and feed.
- In Differential, check for an overall revision state transition in `applyFinalEffects()` (e.g., your reject moving the revision to a rejected state).
- I'm only writing the transaction if the transition is implied and indirect.
- For example, if you "Plan Changes", that action changes the state on its own so there's no implicit state change transaction added.
The transactions themselves are kind of fluff, but it seems useful to keep a record of when state changes occurred in the transaction log. If people complain we can hide/remove them.
Test Plan: {F118143}
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T2222
Differential Revision: https://secure.phabricator.com/D8339
2014-02-25 21:36:49 +01:00
|
|
|
}
|
|
|
|
|
2017-09-06 18:25:31 +02:00
|
|
|
public function shouldHideForMail(array $xactions) {
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case DifferentialRevisionReviewersTransaction::TRANSACTIONTYPE:
|
|
|
|
// Don't hide the initial "X added reviewers: ..." transaction during
|
|
|
|
// object creation from mail. See T12118 and PHI54.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent::shouldHideForMail($xactions);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-22 14:37:34 +01:00
|
|
|
public function isInlineCommentTransaction() {
|
2014-02-26 00:29:10 +01:00
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case self::TYPE_INLINE:
|
2015-03-22 14:37:34 +01:00
|
|
|
return true;
|
2014-02-26 00:29:10 +01:00
|
|
|
}
|
|
|
|
|
2015-03-22 14:37:34 +01:00
|
|
|
return parent::isInlineCommentTransaction();
|
2014-02-26 00:29:10 +01:00
|
|
|
}
|
|
|
|
|
2014-03-01 01:49:22 +01:00
|
|
|
public function getRequiredHandlePHIDs() {
|
|
|
|
$phids = parent::getRequiredHandlePHIDs();
|
|
|
|
|
|
|
|
$old = $this->getOldValue();
|
|
|
|
$new = $this->getNewValue();
|
|
|
|
|
|
|
|
switch ($this->getTransactionType()) {
|
2014-09-12 19:12:52 +02:00
|
|
|
case self::TYPE_ACTION:
|
|
|
|
if ($new == DifferentialAction::ACTION_CLOSE &&
|
|
|
|
$this->getMetadataValue('isCommitClose')) {
|
|
|
|
$phids[] = $this->getMetadataValue('commitPHID');
|
|
|
|
if ($this->getMetadataValue('committerPHID')) {
|
|
|
|
$phids[] = $this->getMetadataValue('committerPHID');
|
|
|
|
}
|
|
|
|
if ($this->getMetadataValue('authorPHID')) {
|
|
|
|
$phids[] = $this->getMetadataValue('authorPHID');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2014-03-01 01:49:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return $phids;
|
|
|
|
}
|
2014-02-26 00:29:10 +01:00
|
|
|
|
2014-04-26 21:44:05 +02:00
|
|
|
public function getActionStrength() {
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case self::TYPE_ACTION:
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent::getActionStrength();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-03-03 17:36:40 +01:00
|
|
|
public function getActionName() {
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case self::TYPE_INLINE:
|
|
|
|
return pht('Commented On');
|
|
|
|
case self::TYPE_ACTION:
|
|
|
|
$map = array(
|
|
|
|
DifferentialAction::ACTION_ACCEPT => pht('Accepted'),
|
|
|
|
DifferentialAction::ACTION_REJECT => pht('Requested Changes To'),
|
|
|
|
DifferentialAction::ACTION_RETHINK => pht('Planned Changes To'),
|
|
|
|
DifferentialAction::ACTION_ABANDON => pht('Abandoned'),
|
|
|
|
DifferentialAction::ACTION_CLOSE => pht('Closed'),
|
|
|
|
DifferentialAction::ACTION_REQUEST => pht('Requested A Review Of'),
|
|
|
|
DifferentialAction::ACTION_RESIGN => pht('Resigned From'),
|
|
|
|
DifferentialAction::ACTION_ADDREVIEWERS => pht('Added Reviewers'),
|
|
|
|
DifferentialAction::ACTION_CLAIM => pht('Commandeered'),
|
|
|
|
DifferentialAction::ACTION_REOPEN => pht('Reopened'),
|
|
|
|
);
|
|
|
|
$name = idx($map, $this->getNewValue());
|
|
|
|
if ($name !== null) {
|
|
|
|
return $name;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent::getActionName();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getMailTags() {
|
|
|
|
$tags = array();
|
|
|
|
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_SUBSCRIBERS;
|
2015-06-08 01:54:53 +02:00
|
|
|
$tags[] = self::MAILTAG_CC;
|
2014-03-03 17:36:40 +01:00
|
|
|
break;
|
|
|
|
case self::TYPE_ACTION:
|
|
|
|
switch ($this->getNewValue()) {
|
|
|
|
case DifferentialAction::ACTION_CLOSE:
|
2015-06-08 01:54:53 +02:00
|
|
|
$tags[] = self::MAILTAG_CLOSED;
|
2014-03-03 17:36:40 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2018-03-06 17:12:04 +01:00
|
|
|
case DifferentialRevisionUpdateTransaction::TRANSACTIONTYPE:
|
2014-03-08 23:43:34 +01:00
|
|
|
$old = $this->getOldValue();
|
|
|
|
if ($old === null) {
|
2015-06-08 01:54:53 +02:00
|
|
|
$tags[] = self::MAILTAG_REVIEW_REQUEST;
|
2014-03-08 23:43:34 +01:00
|
|
|
} else {
|
2015-06-08 01:54:53 +02:00
|
|
|
$tags[] = self::MAILTAG_UPDATED;
|
2014-03-08 23:43:34 +01:00
|
|
|
}
|
|
|
|
break;
|
2014-03-03 17:36:40 +01:00
|
|
|
case PhabricatorTransactions::TYPE_COMMENT:
|
|
|
|
case self::TYPE_INLINE:
|
2015-06-08 01:54:53 +02:00
|
|
|
$tags[] = self::MAILTAG_COMMENT;
|
2014-03-03 17:36:40 +01:00
|
|
|
break;
|
2016-12-31 18:31:39 +01:00
|
|
|
case DifferentialRevisionReviewersTransaction::TRANSACTIONTYPE:
|
|
|
|
$tags[] = self::MAILTAG_REVIEWERS;
|
|
|
|
break;
|
|
|
|
case DifferentialRevisionCloseTransaction::TRANSACTIONTYPE:
|
2017-01-01 18:20:08 +01:00
|
|
|
$tags[] = self::MAILTAG_CLOSED;
|
2016-12-31 18:31:39 +01:00
|
|
|
break;
|
2014-03-03 17:36:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!$tags) {
|
2015-06-08 01:54:53 +02:00
|
|
|
$tags[] = self::MAILTAG_OTHER;
|
2014-03-03 17:36:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return $tags;
|
|
|
|
}
|
|
|
|
|
2014-02-12 23:05:40 +01:00
|
|
|
public function getTitle() {
|
|
|
|
$author_phid = $this->getAuthorPHID();
|
2014-02-14 00:35:44 +01:00
|
|
|
$author_handle = $this->renderHandleLink($author_phid);
|
2014-02-12 23:05:40 +01:00
|
|
|
|
|
|
|
$old = $this->getOldValue();
|
|
|
|
$new = $this->getNewValue();
|
|
|
|
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case self::TYPE_INLINE:
|
|
|
|
return pht(
|
|
|
|
'%s added inline comments.',
|
2014-02-14 00:35:44 +01:00
|
|
|
$author_handle);
|
|
|
|
case self::TYPE_ACTION:
|
2014-09-12 19:12:52 +02:00
|
|
|
switch ($new) {
|
|
|
|
case DifferentialAction::ACTION_CLOSE:
|
|
|
|
if (!$this->getMetadataValue('isCommitClose')) {
|
|
|
|
return DifferentialAction::getBasicStoryText(
|
|
|
|
$new,
|
|
|
|
$author_handle);
|
|
|
|
}
|
|
|
|
$commit_name = $this->renderHandleLink(
|
|
|
|
$this->getMetadataValue('commitPHID'));
|
|
|
|
$committer_phid = $this->getMetadataValue('committerPHID');
|
|
|
|
$author_phid = $this->getMetadataValue('authorPHID');
|
|
|
|
if ($this->getHandleIfExists($committer_phid)) {
|
|
|
|
$committer_name = $this->renderHandleLink($committer_phid);
|
|
|
|
} else {
|
|
|
|
$committer_name = $this->getMetadataValue('committerName');
|
|
|
|
}
|
|
|
|
if ($this->getHandleIfExists($author_phid)) {
|
|
|
|
$author_name = $this->renderHandleLink($author_phid);
|
|
|
|
} else {
|
|
|
|
$author_name = $this->getMetadataValue('authorName');
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($committer_name && ($committer_name != $author_name)) {
|
|
|
|
return pht(
|
|
|
|
'Closed by commit %s (authored by %s, committed by %s).',
|
|
|
|
$commit_name,
|
|
|
|
$author_name,
|
|
|
|
$committer_name);
|
|
|
|
} else {
|
|
|
|
return pht(
|
|
|
|
'Closed by commit %s (authored by %s).',
|
|
|
|
$commit_name,
|
|
|
|
$author_name);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return DifferentialAction::getBasicStoryText($new, $author_handle);
|
|
|
|
}
|
|
|
|
break;
|
2015-06-08 01:54:53 +02:00
|
|
|
}
|
2014-02-12 23:05:40 +01:00
|
|
|
|
|
|
|
return parent::getTitle();
|
|
|
|
}
|
|
|
|
|
2014-10-14 01:55:26 +02:00
|
|
|
public function renderExtraInformationLink() {
|
|
|
|
if ($this->getMetadataValue('revisionMatchData')) {
|
|
|
|
$details_href =
|
|
|
|
'/differential/revision/closedetails/'.$this->getPHID().'/';
|
|
|
|
$details_link = javelin_tag(
|
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => $details_href,
|
|
|
|
'sigil' => 'workflow',
|
|
|
|
),
|
|
|
|
pht('Explain Why'));
|
|
|
|
return $details_link;
|
|
|
|
}
|
|
|
|
return parent::renderExtraInformationLink();
|
|
|
|
}
|
|
|
|
|
2015-01-02 17:45:43 +01:00
|
|
|
public function getTitleForFeed() {
|
2014-02-28 00:16:32 +01:00
|
|
|
$author_phid = $this->getAuthorPHID();
|
|
|
|
$object_phid = $this->getObjectPHID();
|
|
|
|
|
|
|
|
$old = $this->getOldValue();
|
|
|
|
$new = $this->getNewValue();
|
|
|
|
|
|
|
|
$author_link = $this->renderHandleLink($author_phid);
|
|
|
|
$object_link = $this->renderHandleLink($object_phid);
|
|
|
|
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case self::TYPE_INLINE:
|
|
|
|
return pht(
|
|
|
|
'%s added inline comments to %s.',
|
|
|
|
$author_link,
|
|
|
|
$object_link);
|
|
|
|
case self::TYPE_ACTION:
|
|
|
|
switch ($new) {
|
|
|
|
case DifferentialAction::ACTION_ACCEPT:
|
|
|
|
return pht(
|
|
|
|
'%s accepted %s.',
|
|
|
|
$author_link,
|
|
|
|
$object_link);
|
|
|
|
case DifferentialAction::ACTION_REJECT:
|
|
|
|
return pht(
|
|
|
|
'%s requested changes to %s.',
|
|
|
|
$author_link,
|
|
|
|
$object_link);
|
|
|
|
case DifferentialAction::ACTION_RETHINK:
|
|
|
|
return pht(
|
|
|
|
'%s planned changes to %s.',
|
|
|
|
$author_link,
|
|
|
|
$object_link);
|
|
|
|
case DifferentialAction::ACTION_ABANDON:
|
|
|
|
return pht(
|
|
|
|
'%s abandoned %s.',
|
|
|
|
$author_link,
|
|
|
|
$object_link);
|
|
|
|
case DifferentialAction::ACTION_CLOSE:
|
2014-09-12 19:12:52 +02:00
|
|
|
if (!$this->getMetadataValue('isCommitClose')) {
|
|
|
|
return pht(
|
|
|
|
'%s closed %s.',
|
|
|
|
$author_link,
|
|
|
|
$object_link);
|
|
|
|
} else {
|
|
|
|
$commit_name = $this->renderHandleLink(
|
|
|
|
$this->getMetadataValue('commitPHID'));
|
|
|
|
$committer_phid = $this->getMetadataValue('committerPHID');
|
|
|
|
$author_phid = $this->getMetadataValue('authorPHID');
|
2015-02-02 23:59:32 +01:00
|
|
|
|
2014-09-12 19:12:52 +02:00
|
|
|
if ($this->getHandleIfExists($committer_phid)) {
|
|
|
|
$committer_name = $this->renderHandleLink($committer_phid);
|
|
|
|
} else {
|
|
|
|
$committer_name = $this->getMetadataValue('committerName');
|
|
|
|
}
|
2015-02-02 23:59:32 +01:00
|
|
|
|
2014-09-12 19:12:52 +02:00
|
|
|
if ($this->getHandleIfExists($author_phid)) {
|
|
|
|
$author_name = $this->renderHandleLink($author_phid);
|
|
|
|
} else {
|
|
|
|
$author_name = $this->getMetadataValue('authorName');
|
|
|
|
}
|
|
|
|
|
2015-02-02 23:59:32 +01:00
|
|
|
// Check if the committer and author are the same. They're the
|
|
|
|
// same if both resolved and are the same user, or if neither
|
|
|
|
// resolved and the text is identical.
|
|
|
|
if ($committer_phid && $author_phid) {
|
|
|
|
$same_author = ($committer_phid == $author_phid);
|
|
|
|
} else if (!$committer_phid && !$author_phid) {
|
|
|
|
$same_author = ($committer_name == $author_name);
|
|
|
|
} else {
|
|
|
|
$same_author = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($committer_name && !$same_author) {
|
2014-09-12 19:12:52 +02:00
|
|
|
return pht(
|
2015-01-28 21:52:58 +01:00
|
|
|
'%s closed %s by committing %s (authored by %s).',
|
2014-09-12 19:12:52 +02:00
|
|
|
$author_link,
|
|
|
|
$object_link,
|
|
|
|
$commit_name,
|
|
|
|
$author_name);
|
|
|
|
} else {
|
|
|
|
return pht(
|
2015-01-28 21:52:58 +01:00
|
|
|
'%s closed %s by committing %s.',
|
2014-09-12 19:12:52 +02:00
|
|
|
$author_link,
|
|
|
|
$object_link,
|
|
|
|
$commit_name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2014-02-28 00:16:32 +01:00
|
|
|
case DifferentialAction::ACTION_REQUEST:
|
|
|
|
return pht(
|
|
|
|
'%s requested review of %s.',
|
|
|
|
$author_link,
|
|
|
|
$object_link);
|
|
|
|
case DifferentialAction::ACTION_RECLAIM:
|
|
|
|
return pht(
|
|
|
|
'%s reclaimed %s.',
|
|
|
|
$author_link,
|
|
|
|
$object_link);
|
|
|
|
case DifferentialAction::ACTION_RESIGN:
|
|
|
|
return pht(
|
|
|
|
'%s resigned from %s.',
|
|
|
|
$author_link,
|
|
|
|
$object_link);
|
|
|
|
case DifferentialAction::ACTION_CLAIM:
|
|
|
|
return pht(
|
|
|
|
'%s commandeered %s.',
|
|
|
|
$author_link,
|
|
|
|
$object_link);
|
|
|
|
case DifferentialAction::ACTION_REOPEN:
|
|
|
|
return pht(
|
|
|
|
'%s reopened %s.',
|
|
|
|
$author_link,
|
|
|
|
$object_link);
|
|
|
|
}
|
|
|
|
break;
|
2015-06-08 01:54:53 +02:00
|
|
|
}
|
2014-02-28 00:16:32 +01:00
|
|
|
|
2015-01-02 17:45:43 +01:00
|
|
|
return parent::getTitleForFeed();
|
2014-02-28 00:16:32 +01:00
|
|
|
}
|
|
|
|
|
2014-02-14 00:35:44 +01:00
|
|
|
public function getIcon() {
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case self::TYPE_INLINE:
|
2014-04-22 17:25:54 +02:00
|
|
|
return 'fa-comment';
|
2014-02-14 00:35:44 +01:00
|
|
|
case self::TYPE_ACTION:
|
|
|
|
switch ($this->getNewValue()) {
|
|
|
|
case DifferentialAction::ACTION_CLOSE:
|
2014-04-22 17:25:54 +02:00
|
|
|
return 'fa-check';
|
2014-04-22 23:24:36 +02:00
|
|
|
case DifferentialAction::ACTION_ACCEPT:
|
2014-04-22 23:55:45 +02:00
|
|
|
return 'fa-check-circle-o';
|
2014-02-14 00:35:44 +01:00
|
|
|
case DifferentialAction::ACTION_REJECT:
|
2014-04-22 23:55:45 +02:00
|
|
|
return 'fa-times-circle-o';
|
2014-02-14 00:35:44 +01:00
|
|
|
case DifferentialAction::ACTION_ABANDON:
|
2014-04-22 17:25:54 +02:00
|
|
|
return 'fa-plane';
|
2014-02-14 00:35:44 +01:00
|
|
|
case DifferentialAction::ACTION_RETHINK:
|
2014-04-22 17:25:54 +02:00
|
|
|
return 'fa-headphones';
|
2014-02-14 00:35:44 +01:00
|
|
|
case DifferentialAction::ACTION_REQUEST:
|
2014-04-22 17:25:54 +02:00
|
|
|
return 'fa-refresh';
|
2014-02-14 00:35:44 +01:00
|
|
|
case DifferentialAction::ACTION_RECLAIM:
|
|
|
|
case DifferentialAction::ACTION_REOPEN:
|
2014-04-22 17:25:54 +02:00
|
|
|
return 'fa-bullhorn';
|
2014-02-14 00:35:44 +01:00
|
|
|
case DifferentialAction::ACTION_RESIGN:
|
2014-04-22 17:25:54 +02:00
|
|
|
return 'fa-flag';
|
2014-02-14 00:35:44 +01:00
|
|
|
case DifferentialAction::ACTION_CLAIM:
|
2014-04-22 17:25:54 +02:00
|
|
|
return 'fa-flag';
|
2014-02-14 00:35:44 +01:00
|
|
|
}
|
2014-04-22 23:32:45 +02:00
|
|
|
case PhabricatorTransactions::TYPE_EDGE:
|
|
|
|
switch ($this->getMetadataValue('edge:type')) {
|
2015-01-01 04:43:26 +01:00
|
|
|
case DifferentialRevisionHasReviewerEdgeType::EDGECONST:
|
2014-04-22 23:32:45 +02:00
|
|
|
return 'fa-user';
|
|
|
|
}
|
2014-02-14 00:35:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return parent::getIcon();
|
|
|
|
}
|
|
|
|
|
Update overall revision status after reviewers change
Summary:
Ref T2222. This doesn't feel super clean, but doesn't feel too bad either.
Basically, Differential transactions can have secondary state-based effects (changing the overall revision status) when reviewers resign, are removed, accept, or reject revisions.
To deal with this in ApplicationTransactions, I did this:
- `applyFinalEffects()` can now alter the transaction set (notably, add new ones). This mostly matters for email, notifications and feed.
- In Differential, check for an overall revision state transition in `applyFinalEffects()` (e.g., your reject moving the revision to a rejected state).
- I'm only writing the transaction if the transition is implied and indirect.
- For example, if you "Plan Changes", that action changes the state on its own so there's no implicit state change transaction added.
The transactions themselves are kind of fluff, but it seems useful to keep a record of when state changes occurred in the transaction log. If people complain we can hide/remove them.
Test Plan: {F118143}
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T2222
Differential Revision: https://secure.phabricator.com/D8339
2014-02-25 21:36:49 +01:00
|
|
|
public function shouldDisplayGroupWith(array $group) {
|
|
|
|
|
|
|
|
// Never group status changes with other types of actions, they're indirect
|
|
|
|
// and don't make sense when combined with direct actions.
|
|
|
|
|
2017-08-11 23:13:25 +02:00
|
|
|
if ($this->isStatusTransaction($this)) {
|
Update overall revision status after reviewers change
Summary:
Ref T2222. This doesn't feel super clean, but doesn't feel too bad either.
Basically, Differential transactions can have secondary state-based effects (changing the overall revision status) when reviewers resign, are removed, accept, or reject revisions.
To deal with this in ApplicationTransactions, I did this:
- `applyFinalEffects()` can now alter the transaction set (notably, add new ones). This mostly matters for email, notifications and feed.
- In Differential, check for an overall revision state transition in `applyFinalEffects()` (e.g., your reject moving the revision to a rejected state).
- I'm only writing the transaction if the transition is implied and indirect.
- For example, if you "Plan Changes", that action changes the state on its own so there's no implicit state change transaction added.
The transactions themselves are kind of fluff, but it seems useful to keep a record of when state changes occurred in the transaction log. If people complain we can hide/remove them.
Test Plan: {F118143}
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T2222
Differential Revision: https://secure.phabricator.com/D8339
2014-02-25 21:36:49 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($group as $xaction) {
|
2017-08-11 23:13:25 +02:00
|
|
|
if ($this->isStatusTransaction($xaction)) {
|
Update overall revision status after reviewers change
Summary:
Ref T2222. This doesn't feel super clean, but doesn't feel too bad either.
Basically, Differential transactions can have secondary state-based effects (changing the overall revision status) when reviewers resign, are removed, accept, or reject revisions.
To deal with this in ApplicationTransactions, I did this:
- `applyFinalEffects()` can now alter the transaction set (notably, add new ones). This mostly matters for email, notifications and feed.
- In Differential, check for an overall revision state transition in `applyFinalEffects()` (e.g., your reject moving the revision to a rejected state).
- I'm only writing the transaction if the transition is implied and indirect.
- For example, if you "Plan Changes", that action changes the state on its own so there's no implicit state change transaction added.
The transactions themselves are kind of fluff, but it seems useful to keep a record of when state changes occurred in the transaction log. If people complain we can hide/remove them.
Test Plan: {F118143}
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T2222
Differential Revision: https://secure.phabricator.com/D8339
2014-02-25 21:36:49 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent::shouldDisplayGroupWith($group);
|
|
|
|
}
|
|
|
|
|
2017-08-11 23:13:25 +02:00
|
|
|
private function isStatusTransaction($xaction) {
|
2017-08-12 01:57:44 +02:00
|
|
|
$status_type = DifferentialRevisionStatusTransaction::TRANSACTIONTYPE;
|
|
|
|
if ($xaction->getTransactionType() == $status_type) {
|
2017-08-11 23:13:25 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
Update overall revision status after reviewers change
Summary:
Ref T2222. This doesn't feel super clean, but doesn't feel too bad either.
Basically, Differential transactions can have secondary state-based effects (changing the overall revision status) when reviewers resign, are removed, accept, or reject revisions.
To deal with this in ApplicationTransactions, I did this:
- `applyFinalEffects()` can now alter the transaction set (notably, add new ones). This mostly matters for email, notifications and feed.
- In Differential, check for an overall revision state transition in `applyFinalEffects()` (e.g., your reject moving the revision to a rejected state).
- I'm only writing the transaction if the transition is implied and indirect.
- For example, if you "Plan Changes", that action changes the state on its own so there's no implicit state change transaction added.
The transactions themselves are kind of fluff, but it seems useful to keep a record of when state changes occurred in the transaction log. If people complain we can hide/remove them.
Test Plan: {F118143}
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T2222
Differential Revision: https://secure.phabricator.com/D8339
2014-02-25 21:36:49 +01:00
|
|
|
|
2014-02-14 00:35:44 +01:00
|
|
|
public function getColor() {
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case self::TYPE_ACTION:
|
|
|
|
switch ($this->getNewValue()) {
|
|
|
|
case DifferentialAction::ACTION_CLOSE:
|
2015-01-05 20:19:01 +01:00
|
|
|
return PhabricatorTransactions::COLOR_INDIGO;
|
2014-02-14 00:35:44 +01:00
|
|
|
case DifferentialAction::ACTION_ACCEPT:
|
|
|
|
return PhabricatorTransactions::COLOR_GREEN;
|
|
|
|
case DifferentialAction::ACTION_REJECT:
|
|
|
|
return PhabricatorTransactions::COLOR_RED;
|
|
|
|
case DifferentialAction::ACTION_ABANDON:
|
2015-01-05 20:19:01 +01:00
|
|
|
return PhabricatorTransactions::COLOR_INDIGO;
|
2014-02-14 00:35:44 +01:00
|
|
|
case DifferentialAction::ACTION_RETHINK:
|
|
|
|
return PhabricatorTransactions::COLOR_RED;
|
|
|
|
case DifferentialAction::ACTION_REQUEST:
|
|
|
|
return PhabricatorTransactions::COLOR_SKY;
|
|
|
|
case DifferentialAction::ACTION_RECLAIM:
|
|
|
|
return PhabricatorTransactions::COLOR_SKY;
|
|
|
|
case DifferentialAction::ACTION_REOPEN:
|
|
|
|
return PhabricatorTransactions::COLOR_SKY;
|
|
|
|
case DifferentialAction::ACTION_RESIGN:
|
|
|
|
return PhabricatorTransactions::COLOR_ORANGE;
|
|
|
|
case DifferentialAction::ACTION_CLAIM:
|
|
|
|
return PhabricatorTransactions::COLOR_YELLOW;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return parent::getColor();
|
|
|
|
}
|
|
|
|
|
2014-02-25 00:57:26 +01:00
|
|
|
public function getNoEffectDescription() {
|
|
|
|
switch ($this->getTransactionType()) {
|
2015-05-13 22:50:28 +02:00
|
|
|
case self::TYPE_ACTION:
|
2014-02-25 00:57:49 +01:00
|
|
|
switch ($this->getNewValue()) {
|
|
|
|
case DifferentialAction::ACTION_CLOSE:
|
|
|
|
return pht('This revision is already closed.');
|
|
|
|
case DifferentialAction::ACTION_ABANDON:
|
|
|
|
return pht('This revision has already been abandoned.');
|
|
|
|
case DifferentialAction::ACTION_RECLAIM:
|
|
|
|
return pht(
|
|
|
|
'You can not reclaim this revision because his revision is '.
|
|
|
|
'not abandoned.');
|
|
|
|
case DifferentialAction::ACTION_REOPEN:
|
|
|
|
return pht(
|
|
|
|
'You can not reopen this revision because this revision is '.
|
|
|
|
'not closed.');
|
|
|
|
case DifferentialAction::ACTION_RETHINK:
|
|
|
|
return pht('This revision already requires changes.');
|
2014-02-25 21:36:24 +01:00
|
|
|
case DifferentialAction::ACTION_CLAIM:
|
|
|
|
return pht(
|
|
|
|
'You can not commandeer this revision because you already own '.
|
|
|
|
'it.');
|
2014-02-25 00:57:49 +01:00
|
|
|
}
|
|
|
|
break;
|
2014-02-25 00:57:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return parent::getNoEffectDescription();
|
|
|
|
}
|
|
|
|
|
2014-10-01 16:09:34 +02:00
|
|
|
public function renderAsTextForDoorkeeper(
|
|
|
|
DoorkeeperFeedStoryPublisher $publisher,
|
|
|
|
PhabricatorFeedStory $story,
|
|
|
|
array $xactions) {
|
|
|
|
|
|
|
|
$body = parent::renderAsTextForDoorkeeper($publisher, $story, $xactions);
|
|
|
|
|
|
|
|
$inlines = array();
|
|
|
|
foreach ($xactions as $xaction) {
|
|
|
|
if ($xaction->getTransactionType() == self::TYPE_INLINE) {
|
|
|
|
$inlines[] = $xaction;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: This is a bit gross, but far less bad than it used to be. It
|
|
|
|
// could be further cleaned up at some point.
|
|
|
|
|
|
|
|
if ($inlines) {
|
|
|
|
$engine = PhabricatorMarkupEngine::newMarkupEngine(array())
|
|
|
|
->setConfig('viewer', new PhabricatorUser())
|
|
|
|
->setMode(PhutilRemarkupEngine::MODE_TEXT);
|
|
|
|
|
|
|
|
$body .= "\n\n";
|
|
|
|
$body .= pht('Inline Comments');
|
|
|
|
$body .= "\n";
|
|
|
|
|
|
|
|
$changeset_ids = array();
|
|
|
|
foreach ($inlines as $inline) {
|
|
|
|
$changeset_ids[] = $inline->getComment()->getChangesetID();
|
|
|
|
}
|
|
|
|
|
|
|
|
$changesets = id(new DifferentialChangeset())->loadAllWhere(
|
|
|
|
'id IN (%Ld)',
|
|
|
|
$changeset_ids);
|
|
|
|
|
|
|
|
foreach ($inlines as $inline) {
|
|
|
|
$comment = $inline->getComment();
|
|
|
|
$changeset = idx($changesets, $comment->getChangesetID());
|
|
|
|
if (!$changeset) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$filename = $changeset->getDisplayFilename();
|
|
|
|
$linenumber = $comment->getLineNumber();
|
|
|
|
$inline_text = $engine->markupText($comment->getContent());
|
|
|
|
$inline_text = rtrim($inline_text);
|
|
|
|
|
|
|
|
$body .= "{$filename}:{$linenumber} {$inline_text}\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $body;
|
|
|
|
}
|
|
|
|
|
2014-02-25 00:57:26 +01:00
|
|
|
|
2013-06-21 21:54:29 +02:00
|
|
|
}
|