2012-12-11 13:59:20 -08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
abstract class PhabricatorApplicationTransaction
|
|
|
|
extends PhabricatorLiskDAO
|
2014-05-01 18:25:30 -07:00
|
|
|
implements
|
|
|
|
PhabricatorPolicyInterface,
|
2014-07-21 23:59:22 +10:00
|
|
|
PhabricatorDestructibleInterface {
|
2012-12-11 13:59:20 -08:00
|
|
|
|
2012-12-11 14:00:07 -08:00
|
|
|
const TARGET_TEXT = 'text';
|
|
|
|
const TARGET_HTML = 'html';
|
|
|
|
|
2012-12-11 13:59:20 -08:00
|
|
|
protected $phid;
|
|
|
|
protected $objectPHID;
|
|
|
|
protected $authorPHID;
|
|
|
|
protected $viewPolicy;
|
|
|
|
protected $editPolicy;
|
|
|
|
|
|
|
|
protected $commentPHID;
|
|
|
|
protected $commentVersion = 0;
|
|
|
|
protected $transactionType;
|
|
|
|
protected $oldValue;
|
|
|
|
protected $newValue;
|
2013-03-28 08:34:34 -07:00
|
|
|
protected $metadata = array();
|
2012-12-11 13:59:20 -08:00
|
|
|
|
|
|
|
protected $contentSource;
|
|
|
|
|
|
|
|
private $comment;
|
|
|
|
private $commentNotLoaded;
|
|
|
|
|
|
|
|
private $handles;
|
2012-12-11 14:00:07 -08:00
|
|
|
private $renderingTarget = self::TARGET_HTML;
|
2013-03-09 19:23:50 -08:00
|
|
|
private $transactionGroup = array();
|
2013-09-23 14:32:22 -07:00
|
|
|
private $viewer = self::ATTACHABLE;
|
2014-02-18 16:32:35 -08:00
|
|
|
private $object = self::ATTACHABLE;
|
2014-03-05 10:44:21 -08:00
|
|
|
private $oldValueHasBeenSet = false;
|
2012-12-11 13:59:20 -08:00
|
|
|
|
2014-02-25 12:36:02 -08:00
|
|
|
private $ignoreOnNoEffect;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Flag this transaction as a pure side-effect which should be ignored when
|
|
|
|
* applying transactions if it has no effect, even if transaction application
|
|
|
|
* would normally fail. This both provides users with better error messages
|
|
|
|
* and allows transactions to perform optional side effects.
|
|
|
|
*/
|
|
|
|
public function setIgnoreOnNoEffect($ignore) {
|
|
|
|
$this->ignoreOnNoEffect = $ignore;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getIgnoreOnNoEffect() {
|
|
|
|
return $this->ignoreOnNoEffect;
|
|
|
|
}
|
|
|
|
|
2014-03-03 15:58:00 -08:00
|
|
|
public function shouldGenerateOldValue() {
|
|
|
|
switch ($this->getTransactionType()) {
|
2014-04-17 16:04:14 -07:00
|
|
|
case PhabricatorTransactions::TYPE_BUILDABLE:
|
2014-04-21 15:33:59 -07:00
|
|
|
case PhabricatorTransactions::TYPE_TOKEN:
|
2014-03-03 15:58:00 -08:00
|
|
|
case PhabricatorTransactions::TYPE_CUSTOMFIELD:
|
2015-03-22 06:25:03 -07:00
|
|
|
case PhabricatorTransactions::TYPE_INLINESTATE:
|
2014-03-03 15:58:00 -08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-12-11 13:59:20 -08:00
|
|
|
abstract public function getApplicationTransactionType();
|
2013-08-20 10:04:33 -07:00
|
|
|
|
|
|
|
private function getApplicationObjectTypeName() {
|
|
|
|
$types = PhabricatorPHIDType::getAllTypes();
|
|
|
|
|
|
|
|
$type = idx($types, $this->getApplicationTransactionType());
|
|
|
|
if ($type) {
|
|
|
|
return $type->getTypeName();
|
|
|
|
}
|
|
|
|
|
|
|
|
return pht('Object');
|
|
|
|
}
|
2012-12-11 13:59:20 -08:00
|
|
|
|
2013-08-20 10:00:25 -07:00
|
|
|
public function getApplicationTransactionCommentObject() {
|
2014-07-22 01:47:00 +10:00
|
|
|
throw new PhutilMethodNotImplementedException();
|
2013-08-20 10:00:25 -07:00
|
|
|
}
|
|
|
|
|
2013-03-09 19:23:50 -08:00
|
|
|
public function getApplicationTransactionViewObject() {
|
|
|
|
return new PhabricatorApplicationTransactionView();
|
|
|
|
}
|
|
|
|
|
2013-03-28 08:34:34 -07:00
|
|
|
public function getMetadataValue($key, $default = null) {
|
|
|
|
return idx($this->metadata, $key, $default);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setMetadataValue($key, $value) {
|
|
|
|
$this->metadata[$key] = $value;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2012-12-11 13:59:20 -08:00
|
|
|
public function generatePHID() {
|
2014-07-24 08:05:46 +10:00
|
|
|
$type = PhabricatorApplicationTransactionTransactionPHIDType::TYPECONST;
|
2012-12-11 13:59:20 -08:00
|
|
|
$subtype = $this->getApplicationTransactionType();
|
|
|
|
|
|
|
|
return PhabricatorPHID::generateNewPHID($type, $subtype);
|
|
|
|
}
|
|
|
|
|
2015-01-14 06:47:05 +11:00
|
|
|
protected function getConfiguration() {
|
2012-12-11 13:59:20 -08:00
|
|
|
return array(
|
|
|
|
self::CONFIG_AUX_PHID => true,
|
|
|
|
self::CONFIG_SERIALIZATION => array(
|
|
|
|
'oldValue' => self::SERIALIZATION_JSON,
|
|
|
|
'newValue' => self::SERIALIZATION_JSON,
|
2013-03-28 08:34:34 -07:00
|
|
|
'metadata' => self::SERIALIZATION_JSON,
|
2012-12-11 13:59:20 -08:00
|
|
|
),
|
2014-09-18 08:32:44 -07:00
|
|
|
self::CONFIG_COLUMN_SCHEMA => array(
|
|
|
|
'commentPHID' => 'phid?',
|
|
|
|
'commentVersion' => 'uint32',
|
|
|
|
'contentSource' => 'text',
|
|
|
|
'transactionType' => 'text32',
|
|
|
|
),
|
2014-09-19 11:46:44 -07:00
|
|
|
self::CONFIG_KEY_SCHEMA => array(
|
|
|
|
'key_object' => array(
|
|
|
|
'columns' => array('objectPHID'),
|
|
|
|
),
|
|
|
|
),
|
2012-12-11 13:59:20 -08:00
|
|
|
) + parent::getConfiguration();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setContentSource(PhabricatorContentSource $content_source) {
|
|
|
|
$this->contentSource = $content_source->serialize();
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getContentSource() {
|
|
|
|
return PhabricatorContentSource::newFromSerialized($this->contentSource);
|
|
|
|
}
|
|
|
|
|
Modernize Macro application
Summary: Adds feed, email, notifications, comments, partial editing, subscriptions, enable/disable, flags and crumbs to Macro.
Test Plan:
{F26839}
{F26840}
{F26841}
{F26842}
{F26843}
{F26844}
{F26845}
Reviewers: vrana, btrahan, chad
Reviewed By: vrana
CC: aran
Maniphest Tasks: T2157, T175, T2104
Differential Revision: https://secure.phabricator.com/D4141
2012-12-11 14:01:03 -08:00
|
|
|
public function hasComment() {
|
|
|
|
return $this->getComment() && strlen($this->getComment()->getContent());
|
|
|
|
}
|
|
|
|
|
2012-12-11 13:59:20 -08:00
|
|
|
public function getComment() {
|
|
|
|
if ($this->commentNotLoaded) {
|
2015-05-22 17:27:56 +10:00
|
|
|
throw new Exception(pht('Comment for this transaction was not loaded.'));
|
2012-12-11 13:59:20 -08:00
|
|
|
}
|
|
|
|
return $this->comment;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function attachComment(
|
|
|
|
PhabricatorApplicationTransactionComment $comment) {
|
|
|
|
$this->comment = $comment;
|
|
|
|
$this->commentNotLoaded = false;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setCommentNotLoaded($not_loaded) {
|
|
|
|
$this->commentNotLoaded = $not_loaded;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2014-02-18 16:32:35 -08:00
|
|
|
public function attachObject($object) {
|
|
|
|
$this->object = $object;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getObject() {
|
|
|
|
return $this->assertAttached($this->object);
|
|
|
|
}
|
|
|
|
|
2014-02-28 15:20:45 -08:00
|
|
|
public function getRemarkupBlocks() {
|
|
|
|
$blocks = array();
|
|
|
|
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_CUSTOMFIELD:
|
|
|
|
$field = $this->getTransactionCustomField();
|
|
|
|
if ($field) {
|
|
|
|
$custom_blocks = $field->getApplicationTransactionRemarkupBlocks(
|
|
|
|
$this);
|
|
|
|
foreach ($custom_blocks as $custom_block) {
|
|
|
|
$blocks[] = $custom_block;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($this->getComment()) {
|
|
|
|
$blocks[] = $this->getComment()->getContent();
|
|
|
|
}
|
|
|
|
|
|
|
|
return $blocks;
|
|
|
|
}
|
|
|
|
|
2014-03-05 10:44:21 -08:00
|
|
|
public function setOldValue($value) {
|
|
|
|
$this->oldValueHasBeenSet = true;
|
|
|
|
$this->writeField('oldValue', $value);
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function hasOldValue() {
|
|
|
|
return $this->oldValueHasBeenSet;
|
|
|
|
}
|
|
|
|
|
2014-02-28 15:20:45 -08:00
|
|
|
|
2012-12-11 13:59:20 -08:00
|
|
|
/* -( Rendering )---------------------------------------------------------- */
|
|
|
|
|
2012-12-11 14:00:07 -08:00
|
|
|
public function setRenderingTarget($rendering_target) {
|
|
|
|
$this->renderingTarget = $rendering_target;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getRenderingTarget() {
|
|
|
|
return $this->renderingTarget;
|
|
|
|
}
|
|
|
|
|
2013-09-23 14:32:22 -07:00
|
|
|
public function attachViewer(PhabricatorUser $viewer) {
|
|
|
|
$this->viewer = $viewer;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getViewer() {
|
|
|
|
return $this->assertAttached($this->viewer);
|
|
|
|
}
|
|
|
|
|
2012-12-11 13:59:20 -08:00
|
|
|
public function getRequiredHandlePHIDs() {
|
|
|
|
$phids = array();
|
|
|
|
|
|
|
|
$old = $this->getOldValue();
|
|
|
|
$new = $this->getNewValue();
|
|
|
|
|
|
|
|
$phids[] = array($this->getAuthorPHID());
|
|
|
|
switch ($this->getTransactionType()) {
|
2014-02-21 11:53:37 -08:00
|
|
|
case PhabricatorTransactions::TYPE_CUSTOMFIELD:
|
|
|
|
$field = $this->getTransactionCustomField();
|
|
|
|
if ($field) {
|
|
|
|
$phids[] = $field->getApplicationTransactionRequiredHandlePHIDs(
|
|
|
|
$this);
|
|
|
|
}
|
|
|
|
break;
|
2012-12-11 13:59:20 -08:00
|
|
|
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
|
|
|
|
$phids[] = $old;
|
|
|
|
$phids[] = $new;
|
|
|
|
break;
|
2013-03-28 08:34:34 -07:00
|
|
|
case PhabricatorTransactions::TYPE_EDGE:
|
|
|
|
$phids[] = ipull($old, 'dst');
|
|
|
|
$phids[] = ipull($new, 'dst');
|
|
|
|
break;
|
2013-05-26 08:43:09 -07:00
|
|
|
case PhabricatorTransactions::TYPE_EDIT_POLICY:
|
|
|
|
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
2013-10-22 13:49:37 -07:00
|
|
|
case PhabricatorTransactions::TYPE_JOIN_POLICY:
|
2015-06-13 15:44:38 -07:00
|
|
|
if (!PhabricatorPolicyQuery::isSpecialPolicy($old)) {
|
2013-05-26 08:43:09 -07:00
|
|
|
$phids[] = array($old);
|
|
|
|
}
|
2015-06-13 15:44:38 -07:00
|
|
|
if (!PhabricatorPolicyQuery::isSpecialPolicy($new)) {
|
2013-05-26 08:43:09 -07:00
|
|
|
$phids[] = array($new);
|
|
|
|
}
|
|
|
|
break;
|
2015-06-05 10:42:49 -07:00
|
|
|
case PhabricatorTransactions::TYPE_SPACE:
|
|
|
|
if ($old) {
|
|
|
|
$phids[] = array($old);
|
|
|
|
}
|
|
|
|
if ($new) {
|
|
|
|
$phids[] = array($new);
|
|
|
|
}
|
|
|
|
break;
|
2014-04-21 15:33:59 -07:00
|
|
|
case PhabricatorTransactions::TYPE_TOKEN:
|
|
|
|
break;
|
2014-04-17 16:04:14 -07:00
|
|
|
case PhabricatorTransactions::TYPE_BUILDABLE:
|
|
|
|
$phid = $this->getMetadataValue('harbormaster:buildablePHID');
|
|
|
|
if ($phid) {
|
|
|
|
$phids[] = array($phid);
|
|
|
|
}
|
|
|
|
break;
|
2012-12-11 13:59:20 -08:00
|
|
|
}
|
|
|
|
|
2014-05-05 10:55:32 -07:00
|
|
|
if ($this->getComment()) {
|
|
|
|
$phids[] = array($this->getComment()->getAuthorPHID());
|
|
|
|
}
|
|
|
|
|
2012-12-11 13:59:20 -08:00
|
|
|
return array_mergev($phids);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setHandles(array $handles) {
|
|
|
|
$this->handles = $handles;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getHandle($phid) {
|
|
|
|
if (empty($this->handles[$phid])) {
|
|
|
|
throw new Exception(
|
2014-02-21 11:54:08 -08:00
|
|
|
pht(
|
2014-07-28 15:01:43 -07:00
|
|
|
'Transaction ("%s", of type "%s") requires a handle ("%s") that it '.
|
|
|
|
'did not load.',
|
2014-02-21 11:54:08 -08:00
|
|
|
$this->getPHID(),
|
2014-07-28 15:01:43 -07:00
|
|
|
$this->getTransactionType(),
|
2014-02-21 11:54:08 -08:00
|
|
|
$phid));
|
2012-12-11 13:59:20 -08:00
|
|
|
}
|
|
|
|
return $this->handles[$phid];
|
|
|
|
}
|
|
|
|
|
2013-05-26 09:51:14 -07:00
|
|
|
public function getHandleIfExists($phid) {
|
|
|
|
return idx($this->handles, $phid);
|
|
|
|
}
|
|
|
|
|
2013-01-24 17:23:05 -08:00
|
|
|
public function getHandles() {
|
|
|
|
if ($this->handles === null) {
|
|
|
|
throw new Exception(
|
2015-05-22 17:27:56 +10:00
|
|
|
pht('Transaction requires handles and it did not load them.'));
|
2013-01-24 17:23:05 -08:00
|
|
|
}
|
|
|
|
return $this->handles;
|
|
|
|
}
|
|
|
|
|
2013-06-18 10:02:34 -07:00
|
|
|
public function renderHandleLink($phid) {
|
2012-12-11 14:00:07 -08:00
|
|
|
if ($this->renderingTarget == self::TARGET_HTML) {
|
|
|
|
return $this->getHandle($phid)->renderLink();
|
|
|
|
} else {
|
2013-10-01 09:37:18 -07:00
|
|
|
return $this->getHandle($phid)->getLinkName();
|
2012-12-11 14:00:07 -08:00
|
|
|
}
|
2012-12-11 13:59:20 -08:00
|
|
|
}
|
|
|
|
|
2013-06-18 10:02:34 -07:00
|
|
|
public function renderHandleList(array $phids) {
|
2012-12-11 13:59:20 -08:00
|
|
|
$links = array();
|
|
|
|
foreach ($phids as $phid) {
|
|
|
|
$links[] = $this->renderHandleLink($phid);
|
|
|
|
}
|
2013-10-01 09:37:18 -07:00
|
|
|
if ($this->renderingTarget == self::TARGET_HTML) {
|
|
|
|
return phutil_implode_html(', ', $links);
|
|
|
|
} else {
|
|
|
|
return implode(', ', $links);
|
|
|
|
}
|
2012-12-11 13:59:20 -08:00
|
|
|
}
|
|
|
|
|
2014-03-14 14:27:45 -07:00
|
|
|
private function renderSubscriberList(array $phids, $change_type) {
|
|
|
|
if ($this->getRenderingTarget() == self::TARGET_TEXT) {
|
|
|
|
return $this->renderHandleList($phids);
|
|
|
|
} else {
|
|
|
|
$handles = array_select_keys($this->getHandles(), $phids);
|
|
|
|
return id(new SubscriptionListStringBuilder())
|
|
|
|
->setHandles($handles)
|
|
|
|
->setObjectPHID($this->getPHID())
|
|
|
|
->buildTransactionString($change_type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-29 10:57:32 -07:00
|
|
|
protected function renderPolicyName($phid, $state = 'old') {
|
2013-09-26 17:27:21 -07:00
|
|
|
$policy = PhabricatorPolicy::newFromPolicyAndHandle(
|
|
|
|
$phid,
|
|
|
|
$this->getHandleIfExists($phid));
|
|
|
|
if ($this->renderingTarget == self::TARGET_HTML) {
|
2014-04-29 09:42:54 -07:00
|
|
|
switch ($policy->getType()) {
|
|
|
|
case PhabricatorPolicyType::TYPE_CUSTOM:
|
|
|
|
$policy->setHref('/transactions/'.$state.'/'.$this->getPHID().'/');
|
|
|
|
$policy->setWorkflow(true);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2013-09-26 17:27:21 -07:00
|
|
|
$output = $policy->renderDescription();
|
|
|
|
} else {
|
|
|
|
$output = hsprintf('%s', $policy->getFullName());
|
|
|
|
}
|
|
|
|
return $output;
|
|
|
|
}
|
|
|
|
|
2012-12-11 13:59:35 -08:00
|
|
|
public function getIcon() {
|
Modernize Macro application
Summary: Adds feed, email, notifications, comments, partial editing, subscriptions, enable/disable, flags and crumbs to Macro.
Test Plan:
{F26839}
{F26840}
{F26841}
{F26842}
{F26843}
{F26844}
{F26845}
Reviewers: vrana, btrahan, chad
Reviewed By: vrana
CC: aran
Maniphest Tasks: T2157, T175, T2104
Differential Revision: https://secure.phabricator.com/D4141
2012-12-11 14:01:03 -08:00
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_COMMENT:
|
2014-05-05 12:00:27 -07:00
|
|
|
$comment = $this->getComment();
|
|
|
|
if ($comment && $comment->getIsRemoved()) {
|
2015-08-05 12:40:47 -07:00
|
|
|
return 'fa-trash';
|
2014-05-05 12:00:27 -07:00
|
|
|
}
|
2014-04-22 08:25:54 -07:00
|
|
|
return 'fa-comment';
|
Modernize Macro application
Summary: Adds feed, email, notifications, comments, partial editing, subscriptions, enable/disable, flags and crumbs to Macro.
Test Plan:
{F26839}
{F26840}
{F26841}
{F26842}
{F26843}
{F26844}
{F26845}
Reviewers: vrana, btrahan, chad
Reviewed By: vrana
CC: aran
Maniphest Tasks: T2157, T175, T2104
Differential Revision: https://secure.phabricator.com/D4141
2012-12-11 14:01:03 -08:00
|
|
|
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
|
2015-08-05 12:40:47 -07:00
|
|
|
$old = $this->getOldValue();
|
|
|
|
$new = $this->getNewValue();
|
|
|
|
$add = array_diff($new, $old);
|
|
|
|
$rem = array_diff($old, $new);
|
|
|
|
if ($add && $rem) {
|
|
|
|
return 'fa-user';
|
|
|
|
} else if ($add) {
|
|
|
|
return 'fa-user-plus';
|
|
|
|
} else if ($rem) {
|
|
|
|
return 'fa-user-times';
|
|
|
|
} else {
|
|
|
|
return 'fa-user';
|
|
|
|
}
|
Modernize Macro application
Summary: Adds feed, email, notifications, comments, partial editing, subscriptions, enable/disable, flags and crumbs to Macro.
Test Plan:
{F26839}
{F26840}
{F26841}
{F26842}
{F26843}
{F26844}
{F26845}
Reviewers: vrana, btrahan, chad
Reviewed By: vrana
CC: aran
Maniphest Tasks: T2157, T175, T2104
Differential Revision: https://secure.phabricator.com/D4141
2012-12-11 14:01:03 -08:00
|
|
|
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
|
|
|
case PhabricatorTransactions::TYPE_EDIT_POLICY:
|
2013-10-22 13:49:37 -07:00
|
|
|
case PhabricatorTransactions::TYPE_JOIN_POLICY:
|
2014-04-22 08:25:54 -07:00
|
|
|
return 'fa-lock';
|
2013-03-28 08:34:34 -07:00
|
|
|
case PhabricatorTransactions::TYPE_EDGE:
|
2014-04-22 08:25:54 -07:00
|
|
|
return 'fa-link';
|
2014-04-17 16:04:14 -07:00
|
|
|
case PhabricatorTransactions::TYPE_BUILDABLE:
|
2014-04-22 08:25:54 -07:00
|
|
|
return 'fa-wrench';
|
2014-04-21 15:33:59 -07:00
|
|
|
case PhabricatorTransactions::TYPE_TOKEN:
|
2014-05-12 10:08:32 -07:00
|
|
|
return 'fa-trophy';
|
2015-06-05 10:42:49 -07:00
|
|
|
case PhabricatorTransactions::TYPE_SPACE:
|
|
|
|
return 'fa-th-large';
|
Modernize Macro application
Summary: Adds feed, email, notifications, comments, partial editing, subscriptions, enable/disable, flags and crumbs to Macro.
Test Plan:
{F26839}
{F26840}
{F26841}
{F26842}
{F26843}
{F26844}
{F26845}
Reviewers: vrana, btrahan, chad
Reviewed By: vrana
CC: aran
Maniphest Tasks: T2157, T175, T2104
Differential Revision: https://secure.phabricator.com/D4141
2012-12-11 14:01:03 -08:00
|
|
|
}
|
|
|
|
|
2014-04-22 08:25:54 -07:00
|
|
|
return 'fa-pencil';
|
2012-12-11 13:59:35 -08:00
|
|
|
}
|
|
|
|
|
2014-04-21 15:33:59 -07:00
|
|
|
public function getToken() {
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_TOKEN:
|
|
|
|
$old = $this->getOldValue();
|
|
|
|
$new = $this->getNewValue();
|
|
|
|
if ($new) {
|
|
|
|
$icon = substr($new, 10);
|
|
|
|
} else {
|
|
|
|
$icon = substr($old, 10);
|
|
|
|
}
|
|
|
|
return array($icon, !$this->getNewValue());
|
|
|
|
}
|
|
|
|
|
|
|
|
return array(null, null);
|
|
|
|
}
|
|
|
|
|
2012-12-11 13:59:35 -08:00
|
|
|
public function getColor() {
|
2014-04-17 16:04:14 -07:00
|
|
|
switch ($this->getTransactionType()) {
|
2014-05-05 12:00:27 -07:00
|
|
|
case PhabricatorTransactions::TYPE_COMMENT;
|
|
|
|
$comment = $this->getComment();
|
|
|
|
if ($comment && $comment->getIsRemoved()) {
|
|
|
|
return 'black';
|
|
|
|
}
|
|
|
|
break;
|
2014-04-17 16:04:14 -07:00
|
|
|
case PhabricatorTransactions::TYPE_BUILDABLE:
|
|
|
|
switch ($this->getNewValue()) {
|
|
|
|
case HarbormasterBuildable::STATUS_PASSED:
|
|
|
|
return 'green';
|
|
|
|
case HarbormasterBuildable::STATUS_FAILED:
|
|
|
|
return 'red';
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2012-12-11 13:59:35 -08:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
Allow CustomField to provide ApplicationTransaction change details
Summary:
Ref T3886. Ref T418. For fields like "Summary" and "Test Plan" where changes can't be summarized in one line, allow CustomField to provide a "(Show Details)" link and render a diff.
Also consolidate some of the existing copy/paste, and simplify this featuer slightly now that we've move to dialogs.
Test Plan:
{F115918}
- Viewed "description"-style field changes in phlux, pholio, legalpad, maniphest, differential, ponder (questions), ponder (answers), and repositories.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T3886, T418
Differential Revision: https://secure.phabricator.com/D8284
2014-02-21 11:53:04 -08:00
|
|
|
protected function getTransactionCustomField() {
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_CUSTOMFIELD:
|
|
|
|
$key = $this->getMetadataValue('customfield:key');
|
|
|
|
if (!$key) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
$field = PhabricatorCustomField::getObjectField(
|
|
|
|
$this->getObject(),
|
|
|
|
PhabricatorCustomField::ROLE_APPLICATIONTRANSACTIONS,
|
|
|
|
$key);
|
|
|
|
if (!$field) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
$field->setViewer($this->getViewer());
|
|
|
|
return $field;
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2012-12-11 13:59:20 -08:00
|
|
|
public function shouldHide() {
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
|
|
|
case PhabricatorTransactions::TYPE_EDIT_POLICY:
|
2013-10-22 13:49:37 -07:00
|
|
|
case PhabricatorTransactions::TYPE_JOIN_POLICY:
|
2015-06-05 10:42:49 -07:00
|
|
|
case PhabricatorTransactions::TYPE_SPACE:
|
2012-12-11 13:59:20 -08:00
|
|
|
if ($this->getOldValue() === null) {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
break;
|
2014-03-08 11:21:38 -08:00
|
|
|
case PhabricatorTransactions::TYPE_CUSTOMFIELD:
|
|
|
|
$field = $this->getTransactionCustomField();
|
|
|
|
if ($field) {
|
|
|
|
return $field->shouldHideInApplicationTransactions($this);
|
|
|
|
}
|
2014-09-09 14:21:13 -07:00
|
|
|
case PhabricatorTransactions::TYPE_EDGE:
|
|
|
|
$edge_type = $this->getMetadataValue('edge:type');
|
|
|
|
switch ($edge_type) {
|
2015-01-01 15:40:26 +11:00
|
|
|
case PhabricatorObjectMentionsObjectEdgeType::EDGECONST:
|
2014-09-09 14:21:13 -07:00
|
|
|
return true;
|
|
|
|
break;
|
2015-01-01 15:40:26 +11:00
|
|
|
case PhabricatorObjectMentionedByObjectEdgeType::EDGECONST:
|
2014-09-16 12:12:35 -07:00
|
|
|
$new = ipull($this->getNewValue(), 'dst');
|
|
|
|
$old = ipull($this->getOldValue(), 'dst');
|
|
|
|
$add = array_diff($new, $old);
|
|
|
|
$add_value = reset($add);
|
|
|
|
$add_handle = $this->getHandle($add_value);
|
|
|
|
if ($add_handle->getPolicyFiltered()) {
|
|
|
|
return true;
|
|
|
|
}
|
2014-09-09 14:21:13 -07:00
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2012-12-11 13:59:20 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-02-25 15:29:10 -08:00
|
|
|
public function shouldHideForMail(array $xactions) {
|
2014-04-17 16:04:14 -07:00
|
|
|
switch ($this->getTransactionType()) {
|
2014-04-21 15:33:59 -07:00
|
|
|
case PhabricatorTransactions::TYPE_TOKEN:
|
|
|
|
return true;
|
2014-04-17 16:04:14 -07:00
|
|
|
case PhabricatorTransactions::TYPE_BUILDABLE:
|
|
|
|
switch ($this->getNewValue()) {
|
2014-05-15 07:02:30 -07:00
|
|
|
case HarbormasterBuildable::STATUS_FAILED:
|
|
|
|
// For now, only ever send mail when builds fail. We might let
|
2014-04-17 16:04:14 -07:00
|
|
|
// you customize this later, but in most cases this is probably
|
|
|
|
// completely uninteresting.
|
2014-05-15 07:02:30 -07:00
|
|
|
return false;
|
2014-04-17 16:04:14 -07:00
|
|
|
}
|
2014-05-15 07:02:30 -07:00
|
|
|
return true;
|
2014-09-09 14:21:13 -07:00
|
|
|
case PhabricatorTransactions::TYPE_EDGE:
|
|
|
|
$edge_type = $this->getMetadataValue('edge:type');
|
|
|
|
switch ($edge_type) {
|
2015-01-01 15:40:26 +11:00
|
|
|
case PhabricatorObjectMentionsObjectEdgeType::EDGECONST:
|
|
|
|
case PhabricatorObjectMentionedByObjectEdgeType::EDGECONST:
|
2014-09-09 14:21:13 -07:00
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2014-04-17 16:04:14 -07:00
|
|
|
}
|
|
|
|
|
2015-03-22 06:25:03 -07:00
|
|
|
// If a transaction publishes an inline comment:
|
|
|
|
//
|
|
|
|
// - Don't show it if there are other kinds of transactions. The
|
|
|
|
// rationale here is that application mail will make the presence
|
|
|
|
// of inline comments obvious enough by including them prominently
|
|
|
|
// in the body. We could change this in the future if the obviousness
|
|
|
|
// needs to be increased.
|
|
|
|
// - If there are only inline transactions, only show the first
|
|
|
|
// transaction. The rationale is that seeing multiple "added an inline
|
|
|
|
// comment" transactions is not useful.
|
|
|
|
|
|
|
|
if ($this->isInlineCommentTransaction()) {
|
|
|
|
foreach ($xactions as $xaction) {
|
|
|
|
if (!$xaction->isInlineCommentTransaction()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ($this !== head($xactions));
|
|
|
|
}
|
|
|
|
|
2013-07-29 08:38:25 -07:00
|
|
|
return $this->shouldHide();
|
|
|
|
}
|
|
|
|
|
2014-03-04 17:01:33 -08:00
|
|
|
public function shouldHideForFeed() {
|
2014-04-21 15:33:59 -07:00
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_TOKEN:
|
|
|
|
return true;
|
2014-04-29 11:10:34 -07:00
|
|
|
case PhabricatorTransactions::TYPE_BUILDABLE:
|
|
|
|
switch ($this->getNewValue()) {
|
2014-05-15 07:02:30 -07:00
|
|
|
case HarbormasterBuildable::STATUS_FAILED:
|
2014-04-29 11:10:34 -07:00
|
|
|
// For now, don't notify on build passes either. These are pretty
|
|
|
|
// high volume and annoying, with very little present value. We
|
|
|
|
// might want to turn them back on in the specific case of
|
|
|
|
// build successes on the current document?
|
2014-05-15 07:02:30 -07:00
|
|
|
return false;
|
2014-04-29 11:10:34 -07:00
|
|
|
}
|
2014-05-15 07:02:30 -07:00
|
|
|
return true;
|
2014-09-09 14:21:13 -07:00
|
|
|
case PhabricatorTransactions::TYPE_EDGE:
|
|
|
|
$edge_type = $this->getMetadataValue('edge:type');
|
|
|
|
switch ($edge_type) {
|
2015-01-01 15:40:26 +11:00
|
|
|
case PhabricatorObjectMentionsObjectEdgeType::EDGECONST:
|
|
|
|
case PhabricatorObjectMentionedByObjectEdgeType::EDGECONST:
|
2014-09-09 14:21:13 -07:00
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2015-03-22 06:37:34 -07:00
|
|
|
case PhabricatorTransactions::TYPE_INLINESTATE:
|
|
|
|
return true;
|
2014-04-21 15:33:59 -07:00
|
|
|
}
|
|
|
|
|
2014-03-04 17:01:33 -08:00
|
|
|
return $this->shouldHide();
|
|
|
|
}
|
|
|
|
|
2014-02-25 15:29:10 -08:00
|
|
|
public function getTitleForMail() {
|
|
|
|
return id(clone $this)->setRenderingTarget('text')->getTitle();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getBodyForMail() {
|
2015-03-22 06:25:03 -07:00
|
|
|
if ($this->isInlineCommentTransaction()) {
|
|
|
|
// We don't return inline comment content as mail body content, because
|
|
|
|
// applications need to contextualize it (by adding line numbers, for
|
|
|
|
// example) in order for it to make sense.
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2014-02-25 15:29:10 -08:00
|
|
|
$comment = $this->getComment();
|
|
|
|
if ($comment && strlen($comment->getContent())) {
|
|
|
|
return $comment->getContent();
|
|
|
|
}
|
2015-03-22 06:25:03 -07:00
|
|
|
|
2014-02-25 15:29:10 -08:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
Add ApplicationTransaction handling for transactions with no effect
Summary:
When a user submits an action with no effect (like an empty comment, an "abandon" on an already-accepted revision, or a "close, resolved" on a closed task) we want to alert them that their action isn't effective. These warnings fall into two general buckets:
- User is submitting two or more actions, and some aren't effective but some are. Prompt them to apply the effective actions only.
- A special case of this is where the only effective action is a comment. We provide tailored text ("Post Comment") in this case.
- User is submitting one action, which isn't effective. Tell them they're out of luck.
- A special case of this is an empty comment. We provide tailored text in this case.
By default, the transaction editor throws when transactions have no effect. The caller can then deal with this, or use `PhabricatorApplicationTransactionNoEffectResponse` to provide a standard dialog that gives the user information as above. For cases where we expect transactions to have no effect (notably, "edit" forms) we just continue on no-effect unconditionally.
Also fix an issue where new, combined or filtered transactions would not be represented properly in the Ajax response (i.e., return final transactions from `applyTransactions()`), and translate some strings.
Test Plan:
- Submitted empty and nonempy comments in Macro and Pholio.
- Submitted comments with new and existing "@mentions".
- Submitted edits in both applications.
Reviewers: btrahan, vrana
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T912, T2104
Differential Revision: https://secure.phabricator.com/D4160
2012-12-11 17:27:40 -08:00
|
|
|
public function getNoEffectDescription() {
|
|
|
|
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_COMMENT:
|
|
|
|
return pht('You can not post an empty comment.');
|
|
|
|
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
|
|
|
return pht(
|
|
|
|
'This %s already has that view policy.',
|
|
|
|
$this->getApplicationObjectTypeName());
|
|
|
|
case PhabricatorTransactions::TYPE_EDIT_POLICY:
|
|
|
|
return pht(
|
|
|
|
'This %s already has that edit policy.',
|
|
|
|
$this->getApplicationObjectTypeName());
|
2013-10-22 13:49:37 -07:00
|
|
|
case PhabricatorTransactions::TYPE_JOIN_POLICY:
|
|
|
|
return pht(
|
|
|
|
'This %s already has that join policy.',
|
|
|
|
$this->getApplicationObjectTypeName());
|
Add ApplicationTransaction handling for transactions with no effect
Summary:
When a user submits an action with no effect (like an empty comment, an "abandon" on an already-accepted revision, or a "close, resolved" on a closed task) we want to alert them that their action isn't effective. These warnings fall into two general buckets:
- User is submitting two or more actions, and some aren't effective but some are. Prompt them to apply the effective actions only.
- A special case of this is where the only effective action is a comment. We provide tailored text ("Post Comment") in this case.
- User is submitting one action, which isn't effective. Tell them they're out of luck.
- A special case of this is an empty comment. We provide tailored text in this case.
By default, the transaction editor throws when transactions have no effect. The caller can then deal with this, or use `PhabricatorApplicationTransactionNoEffectResponse` to provide a standard dialog that gives the user information as above. For cases where we expect transactions to have no effect (notably, "edit" forms) we just continue on no-effect unconditionally.
Also fix an issue where new, combined or filtered transactions would not be represented properly in the Ajax response (i.e., return final transactions from `applyTransactions()`), and translate some strings.
Test Plan:
- Submitted empty and nonempy comments in Macro and Pholio.
- Submitted comments with new and existing "@mentions".
- Submitted edits in both applications.
Reviewers: btrahan, vrana
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T912, T2104
Differential Revision: https://secure.phabricator.com/D4160
2012-12-11 17:27:40 -08:00
|
|
|
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
|
|
|
|
return pht(
|
|
|
|
'All users are already subscribed to this %s.',
|
|
|
|
$this->getApplicationObjectTypeName());
|
2015-06-05 10:42:49 -07:00
|
|
|
case PhabricatorTransactions::TYPE_SPACE:
|
|
|
|
return pht('This object is already in that space.');
|
2013-03-28 08:34:34 -07:00
|
|
|
case PhabricatorTransactions::TYPE_EDGE:
|
|
|
|
return pht('Edges already exist; transaction has no effect.');
|
Add ApplicationTransaction handling for transactions with no effect
Summary:
When a user submits an action with no effect (like an empty comment, an "abandon" on an already-accepted revision, or a "close, resolved" on a closed task) we want to alert them that their action isn't effective. These warnings fall into two general buckets:
- User is submitting two or more actions, and some aren't effective but some are. Prompt them to apply the effective actions only.
- A special case of this is where the only effective action is a comment. We provide tailored text ("Post Comment") in this case.
- User is submitting one action, which isn't effective. Tell them they're out of luck.
- A special case of this is an empty comment. We provide tailored text in this case.
By default, the transaction editor throws when transactions have no effect. The caller can then deal with this, or use `PhabricatorApplicationTransactionNoEffectResponse` to provide a standard dialog that gives the user information as above. For cases where we expect transactions to have no effect (notably, "edit" forms) we just continue on no-effect unconditionally.
Also fix an issue where new, combined or filtered transactions would not be represented properly in the Ajax response (i.e., return final transactions from `applyTransactions()`), and translate some strings.
Test Plan:
- Submitted empty and nonempy comments in Macro and Pholio.
- Submitted comments with new and existing "@mentions".
- Submitted edits in both applications.
Reviewers: btrahan, vrana
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T912, T2104
Differential Revision: https://secure.phabricator.com/D4160
2012-12-11 17:27:40 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
return pht('Transaction has no effect.');
|
|
|
|
}
|
|
|
|
|
2012-12-11 13:59:20 -08:00
|
|
|
public function getTitle() {
|
|
|
|
$author_phid = $this->getAuthorPHID();
|
|
|
|
|
|
|
|
$old = $this->getOldValue();
|
|
|
|
$new = $this->getNewValue();
|
|
|
|
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_COMMENT:
|
|
|
|
return pht(
|
|
|
|
'%s added a comment.',
|
|
|
|
$this->renderHandleLink($author_phid));
|
|
|
|
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
|
|
|
return pht(
|
2015-08-16 17:47:58 -07:00
|
|
|
'%s changed the visibility from "%s" to "%s".',
|
2012-12-11 13:59:20 -08:00
|
|
|
$this->renderHandleLink($author_phid),
|
2014-04-29 09:42:54 -07:00
|
|
|
$this->renderPolicyName($old, 'old'),
|
|
|
|
$this->renderPolicyName($new, 'new'));
|
2012-12-11 13:59:20 -08:00
|
|
|
case PhabricatorTransactions::TYPE_EDIT_POLICY:
|
|
|
|
return pht(
|
2015-08-16 17:47:58 -07:00
|
|
|
'%s changed the edit policy from "%s" to "%s".',
|
2012-12-11 13:59:20 -08:00
|
|
|
$this->renderHandleLink($author_phid),
|
2014-04-29 09:42:54 -07:00
|
|
|
$this->renderPolicyName($old, 'old'),
|
|
|
|
$this->renderPolicyName($new, 'new'));
|
2013-10-22 13:49:37 -07:00
|
|
|
case PhabricatorTransactions::TYPE_JOIN_POLICY:
|
|
|
|
return pht(
|
2015-08-16 17:47:58 -07:00
|
|
|
'%s changed the join policy from "%s" to "%s".',
|
2013-10-22 13:49:37 -07:00
|
|
|
$this->renderHandleLink($author_phid),
|
2014-04-29 09:42:54 -07:00
|
|
|
$this->renderPolicyName($old, 'old'),
|
|
|
|
$this->renderPolicyName($new, 'new'));
|
2015-06-05 10:42:49 -07:00
|
|
|
case PhabricatorTransactions::TYPE_SPACE:
|
|
|
|
return pht(
|
|
|
|
'%s shifted this object from the %s space to the %s space.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->renderHandleLink($old),
|
|
|
|
$this->renderHandleLink($new));
|
2012-12-11 13:59:20 -08:00
|
|
|
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
|
|
|
|
$add = array_diff($new, $old);
|
|
|
|
$rem = array_diff($old, $new);
|
|
|
|
|
|
|
|
if ($add && $rem) {
|
|
|
|
return pht(
|
|
|
|
'%s edited subscriber(s), added %d: %s; removed %d: %s.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
count($add),
|
2014-03-14 14:27:45 -07:00
|
|
|
$this->renderSubscriberList($add, 'add'),
|
2012-12-11 13:59:20 -08:00
|
|
|
count($rem),
|
2014-03-14 14:27:45 -07:00
|
|
|
$this->renderSubscriberList($rem, 'rem'));
|
2012-12-11 13:59:20 -08:00
|
|
|
} else if ($add) {
|
|
|
|
return pht(
|
|
|
|
'%s added %d subscriber(s): %s.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
count($add),
|
2014-03-14 14:27:45 -07:00
|
|
|
$this->renderSubscriberList($add, 'add'));
|
2013-09-23 14:29:59 -07:00
|
|
|
} else if ($rem) {
|
2012-12-11 13:59:20 -08:00
|
|
|
return pht(
|
2013-02-17 09:13:40 -08:00
|
|
|
'%s removed %d subscriber(s): %s.',
|
2012-12-11 13:59:20 -08:00
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
count($rem),
|
2014-03-14 14:27:45 -07:00
|
|
|
$this->renderSubscriberList($rem, 'rem'));
|
2013-09-23 14:29:59 -07:00
|
|
|
} else {
|
|
|
|
// This is used when rendering previews, before the user actually
|
|
|
|
// selects any CCs.
|
|
|
|
return pht(
|
|
|
|
'%s updated subscribers...',
|
|
|
|
$this->renderHandleLink($author_phid));
|
2012-12-11 13:59:20 -08:00
|
|
|
}
|
|
|
|
break;
|
2013-03-28 08:34:34 -07:00
|
|
|
case PhabricatorTransactions::TYPE_EDGE:
|
2013-07-19 15:59:29 -07:00
|
|
|
$new = ipull($new, 'dst');
|
|
|
|
$old = ipull($old, 'dst');
|
|
|
|
$add = array_diff($new, $old);
|
|
|
|
$rem = array_diff($old, $new);
|
2013-03-28 08:34:34 -07:00
|
|
|
$type = $this->getMetadata('edge:type');
|
2013-07-19 15:59:29 -07:00
|
|
|
$type = head($type);
|
|
|
|
|
2014-07-17 15:41:54 -07:00
|
|
|
$type_obj = PhabricatorEdgeType::getByConstant($type);
|
|
|
|
|
2013-07-19 15:59:29 -07:00
|
|
|
if ($add && $rem) {
|
2014-07-17 15:41:54 -07:00
|
|
|
return $type_obj->getTransactionEditString(
|
2013-07-19 15:59:29 -07:00
|
|
|
$this->renderHandleLink($author_phid),
|
2014-07-17 15:41:54 -07:00
|
|
|
new PhutilNumber(count($add) + count($rem)),
|
|
|
|
new PhutilNumber(count($add)),
|
2013-07-19 15:59:29 -07:00
|
|
|
$this->renderHandleList($add),
|
2014-07-17 15:41:54 -07:00
|
|
|
new PhutilNumber(count($rem)),
|
2013-07-19 15:59:29 -07:00
|
|
|
$this->renderHandleList($rem));
|
|
|
|
} else if ($add) {
|
2014-07-17 15:41:54 -07:00
|
|
|
return $type_obj->getTransactionAddString(
|
2013-07-19 15:59:29 -07:00
|
|
|
$this->renderHandleLink($author_phid),
|
2014-07-17 15:41:54 -07:00
|
|
|
new PhutilNumber(count($add)),
|
2013-07-19 15:59:29 -07:00
|
|
|
$this->renderHandleList($add));
|
2014-02-25 12:36:39 -08:00
|
|
|
} else if ($rem) {
|
2014-07-17 15:41:54 -07:00
|
|
|
return $type_obj->getTransactionRemoveString(
|
2013-07-19 15:59:29 -07:00
|
|
|
$this->renderHandleLink($author_phid),
|
2014-07-17 15:41:54 -07:00
|
|
|
new PhutilNumber(count($rem)),
|
2013-07-19 15:59:29 -07:00
|
|
|
$this->renderHandleList($rem));
|
2014-02-25 12:36:39 -08:00
|
|
|
} else {
|
2014-12-18 14:17:16 -08:00
|
|
|
return $type_obj->getTransactionPreviewString(
|
2014-02-25 12:36:39 -08:00
|
|
|
$this->renderHandleLink($author_phid));
|
2013-07-19 15:59:29 -07:00
|
|
|
}
|
|
|
|
|
2013-09-23 14:29:40 -07:00
|
|
|
case PhabricatorTransactions::TYPE_CUSTOMFIELD:
|
Allow CustomField to provide ApplicationTransaction change details
Summary:
Ref T3886. Ref T418. For fields like "Summary" and "Test Plan" where changes can't be summarized in one line, allow CustomField to provide a "(Show Details)" link and render a diff.
Also consolidate some of the existing copy/paste, and simplify this featuer slightly now that we've move to dialogs.
Test Plan:
{F115918}
- Viewed "description"-style field changes in phlux, pholio, legalpad, maniphest, differential, ponder (questions), ponder (answers), and repositories.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T3886, T418
Differential Revision: https://secure.phabricator.com/D8284
2014-02-21 11:53:04 -08:00
|
|
|
$field = $this->getTransactionCustomField();
|
2013-09-23 14:29:40 -07:00
|
|
|
if ($field) {
|
|
|
|
return $field->getApplicationTransactionTitle($this);
|
|
|
|
} else {
|
|
|
|
return pht(
|
|
|
|
'%s edited a custom field.',
|
|
|
|
$this->renderHandleLink($author_phid));
|
|
|
|
}
|
|
|
|
|
2014-04-21 15:33:59 -07:00
|
|
|
case PhabricatorTransactions::TYPE_TOKEN:
|
|
|
|
if ($old && $new) {
|
|
|
|
return pht(
|
|
|
|
'%s updated a token.',
|
|
|
|
$this->renderHandleLink($author_phid));
|
|
|
|
} else if ($old) {
|
|
|
|
return pht(
|
|
|
|
'%s rescinded a token.',
|
|
|
|
$this->renderHandleLink($author_phid));
|
|
|
|
} else {
|
|
|
|
return pht(
|
|
|
|
'%s awarded a token.',
|
|
|
|
$this->renderHandleLink($author_phid));
|
|
|
|
}
|
|
|
|
|
2014-04-17 16:04:14 -07:00
|
|
|
case PhabricatorTransactions::TYPE_BUILDABLE:
|
|
|
|
switch ($this->getNewValue()) {
|
2014-05-15 07:02:30 -07:00
|
|
|
case HarbormasterBuildable::STATUS_BUILDING:
|
|
|
|
return pht(
|
|
|
|
'%s started building %s.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->renderHandleLink(
|
|
|
|
$this->getMetadataValue('harbormaster:buildablePHID')));
|
2014-04-17 16:04:14 -07:00
|
|
|
case HarbormasterBuildable::STATUS_PASSED:
|
|
|
|
return pht(
|
|
|
|
'%s completed building %s.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->renderHandleLink(
|
|
|
|
$this->getMetadataValue('harbormaster:buildablePHID')));
|
|
|
|
case HarbormasterBuildable::STATUS_FAILED:
|
|
|
|
return pht(
|
|
|
|
'%s failed to build %s!',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->renderHandleLink(
|
|
|
|
$this->getMetadataValue('harbormaster:buildablePHID')));
|
|
|
|
default:
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2015-03-22 06:25:03 -07:00
|
|
|
case PhabricatorTransactions::TYPE_INLINESTATE:
|
|
|
|
$done = 0;
|
|
|
|
$undone = 0;
|
|
|
|
foreach ($new as $phid => $state) {
|
|
|
|
if ($state == PhabricatorInlineCommentInterface::STATE_DONE) {
|
|
|
|
$done++;
|
|
|
|
} else {
|
|
|
|
$undone++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($done && $undone) {
|
|
|
|
return pht(
|
|
|
|
'%s marked %s inline comment(s) as done and %s inline comment(s) '.
|
|
|
|
'as not done.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
new PhutilNumber($done),
|
|
|
|
new PhutilNumber($undone));
|
|
|
|
} else if ($done) {
|
|
|
|
return pht(
|
|
|
|
'%s marked %s inline comment(s) as done.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
new PhutilNumber($done));
|
|
|
|
} else {
|
|
|
|
return pht(
|
|
|
|
'%s marked %s inline comment(s) as not done.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
new PhutilNumber($undone));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2012-12-11 13:59:20 -08:00
|
|
|
default:
|
|
|
|
return pht(
|
|
|
|
'%s edited this %s.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->getApplicationObjectTypeName());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-02 08:45:43 -08:00
|
|
|
public function getTitleForFeed() {
|
2012-12-11 14:00:21 -08:00
|
|
|
$author_phid = $this->getAuthorPHID();
|
|
|
|
$object_phid = $this->getObjectPHID();
|
|
|
|
|
|
|
|
$old = $this->getOldValue();
|
|
|
|
$new = $this->getNewValue();
|
|
|
|
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_COMMENT:
|
|
|
|
return pht(
|
|
|
|
'%s added a comment to %s.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->renderHandleLink($object_phid));
|
|
|
|
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
|
|
|
return pht(
|
|
|
|
'%s changed the visibility for %s.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->renderHandleLink($object_phid));
|
|
|
|
case PhabricatorTransactions::TYPE_EDIT_POLICY:
|
|
|
|
return pht(
|
|
|
|
'%s changed the edit policy for %s.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->renderHandleLink($object_phid));
|
2013-10-22 13:49:37 -07:00
|
|
|
case PhabricatorTransactions::TYPE_JOIN_POLICY:
|
|
|
|
return pht(
|
|
|
|
'%s changed the join policy for %s.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->renderHandleLink($object_phid));
|
2012-12-11 14:00:21 -08:00
|
|
|
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
|
|
|
|
return pht(
|
|
|
|
'%s updated subscribers of %s.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->renderHandleLink($object_phid));
|
2015-06-05 10:42:49 -07:00
|
|
|
case PhabricatorTransactions::TYPE_SPACE:
|
|
|
|
return pht(
|
|
|
|
'%s shifted %s from the %s space to the %s space.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->renderHandleLink($object_phid),
|
|
|
|
$this->renderHandleLink($old),
|
|
|
|
$this->renderHandleLink($new));
|
2013-03-28 08:34:34 -07:00
|
|
|
case PhabricatorTransactions::TYPE_EDGE:
|
2014-07-17 15:41:54 -07:00
|
|
|
$new = ipull($new, 'dst');
|
|
|
|
$old = ipull($old, 'dst');
|
|
|
|
$add = array_diff($new, $old);
|
|
|
|
$rem = array_diff($old, $new);
|
2013-07-19 15:59:29 -07:00
|
|
|
$type = $this->getMetadata('edge:type');
|
|
|
|
$type = head($type);
|
2014-07-17 15:41:54 -07:00
|
|
|
|
|
|
|
$type_obj = PhabricatorEdgeType::getByConstant($type);
|
|
|
|
|
|
|
|
if ($add && $rem) {
|
|
|
|
return $type_obj->getFeedEditString(
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->renderHandleLink($object_phid),
|
|
|
|
new PhutilNumber(count($add) + count($rem)),
|
|
|
|
new PhutilNumber(count($add)),
|
|
|
|
$this->renderHandleList($add),
|
|
|
|
new PhutilNumber(count($rem)),
|
|
|
|
$this->renderHandleList($rem));
|
|
|
|
} else if ($add) {
|
|
|
|
return $type_obj->getFeedAddString(
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->renderHandleLink($object_phid),
|
|
|
|
new PhutilNumber(count($add)),
|
|
|
|
$this->renderHandleList($add));
|
|
|
|
} else if ($rem) {
|
|
|
|
return $type_obj->getFeedRemoveString(
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->renderHandleLink($object_phid),
|
|
|
|
new PhutilNumber(count($rem)),
|
|
|
|
$this->renderHandleList($rem));
|
|
|
|
} else {
|
|
|
|
return pht(
|
|
|
|
'%s edited edge metadata for %s.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->renderHandleLink($object_phid));
|
|
|
|
}
|
|
|
|
|
2013-09-24 14:51:36 -07:00
|
|
|
case PhabricatorTransactions::TYPE_CUSTOMFIELD:
|
Allow CustomField to provide ApplicationTransaction change details
Summary:
Ref T3886. Ref T418. For fields like "Summary" and "Test Plan" where changes can't be summarized in one line, allow CustomField to provide a "(Show Details)" link and render a diff.
Also consolidate some of the existing copy/paste, and simplify this featuer slightly now that we've move to dialogs.
Test Plan:
{F115918}
- Viewed "description"-style field changes in phlux, pholio, legalpad, maniphest, differential, ponder (questions), ponder (answers), and repositories.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T3886, T418
Differential Revision: https://secure.phabricator.com/D8284
2014-02-21 11:53:04 -08:00
|
|
|
$field = $this->getTransactionCustomField();
|
2013-09-24 14:51:36 -07:00
|
|
|
if ($field) {
|
2015-01-02 08:45:43 -08:00
|
|
|
return $field->getApplicationTransactionTitleForFeed($this);
|
2013-09-24 14:51:36 -07:00
|
|
|
} else {
|
|
|
|
return pht(
|
|
|
|
'%s edited a custom field on %s.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->renderHandleLink($object_phid));
|
|
|
|
}
|
2014-04-17 16:04:14 -07:00
|
|
|
case PhabricatorTransactions::TYPE_BUILDABLE:
|
|
|
|
switch ($this->getNewValue()) {
|
2014-05-15 07:02:30 -07:00
|
|
|
case HarbormasterBuildable::STATUS_BUILDING:
|
|
|
|
return pht(
|
|
|
|
'%s started building %s for %s.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->renderHandleLink(
|
|
|
|
$this->getMetadataValue('harbormaster:buildablePHID')),
|
|
|
|
$this->renderHandleLink($object_phid));
|
2014-04-17 16:04:14 -07:00
|
|
|
case HarbormasterBuildable::STATUS_PASSED:
|
|
|
|
return pht(
|
|
|
|
'%s completed building %s for %s.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->renderHandleLink(
|
|
|
|
$this->getMetadataValue('harbormaster:buildablePHID')),
|
|
|
|
$this->renderHandleLink($object_phid));
|
|
|
|
case HarbormasterBuildable::STATUS_FAILED:
|
|
|
|
return pht(
|
|
|
|
'%s failed to build %s for %s.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$this->renderHandleLink(
|
|
|
|
$this->getMetadataValue('harbormaster:buildablePHID')),
|
|
|
|
$this->renderHandleLink($object_phid));
|
|
|
|
default:
|
|
|
|
return null;
|
|
|
|
}
|
2013-09-24 14:51:36 -07:00
|
|
|
|
2012-12-11 14:00:21 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
return $this->getTitle();
|
|
|
|
}
|
|
|
|
|
2014-08-26 14:36:35 -07:00
|
|
|
public function getMarkupFieldsForFeed(PhabricatorFeedStory $story) {
|
|
|
|
$fields = array();
|
|
|
|
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_COMMENT:
|
|
|
|
$text = $this->getComment()->getContent();
|
|
|
|
if (strlen($text)) {
|
|
|
|
$fields[] = 'comment/'.$this->getID();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $fields;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getMarkupTextForFeed(PhabricatorFeedStory $story, $field) {
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_COMMENT:
|
|
|
|
$text = $this->getComment()->getContent();
|
|
|
|
return PhabricatorMarkupEngine::summarize($text);
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2013-08-19 11:51:22 -07:00
|
|
|
public function getBodyForFeed(PhabricatorFeedStory $story) {
|
2013-07-25 16:59:36 -07:00
|
|
|
$old = $this->getOldValue();
|
|
|
|
$new = $this->getNewValue();
|
|
|
|
|
|
|
|
$body = null;
|
|
|
|
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_COMMENT:
|
|
|
|
$text = $this->getComment()->getContent();
|
2014-08-26 14:36:35 -07:00
|
|
|
if (strlen($text)) {
|
|
|
|
$body = $story->getMarkupFieldOutput('comment/'.$this->getID());
|
|
|
|
}
|
2013-07-25 16:59:36 -07:00
|
|
|
break;
|
|
|
|
}
|
2014-08-26 14:36:35 -07:00
|
|
|
|
2013-07-25 16:59:36 -07:00
|
|
|
return $body;
|
|
|
|
}
|
|
|
|
|
2012-12-11 14:00:07 -08:00
|
|
|
public function getActionStrength() {
|
2015-03-22 06:37:34 -07:00
|
|
|
if ($this->isInlineCommentTransaction()) {
|
|
|
|
return 0.25;
|
|
|
|
}
|
|
|
|
|
2012-12-11 14:00:07 -08:00
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_COMMENT:
|
|
|
|
return 0.5;
|
2014-05-19 12:23:32 -07:00
|
|
|
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
|
|
|
|
$old = $this->getOldValue();
|
|
|
|
$new = $this->getNewValue();
|
|
|
|
|
|
|
|
$add = array_diff($old, $new);
|
|
|
|
$rem = array_diff($new, $old);
|
|
|
|
|
|
|
|
// If this action is the actor subscribing or unsubscribing themselves,
|
|
|
|
// it is less interesting. In particular, if someone makes a comment and
|
|
|
|
// also implicitly subscribes themselves, we should treat the
|
|
|
|
// transaction group as "comment", not "subscribe". In this specific
|
|
|
|
// case (one affected user, and that affected user it the actor),
|
|
|
|
// decrease the action strength.
|
|
|
|
|
|
|
|
if ((count($add) + count($rem)) != 1) {
|
|
|
|
// Not exactly one CC change.
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$affected_phid = head(array_merge($add, $rem));
|
|
|
|
if ($affected_phid != $this->getAuthorPHID()) {
|
|
|
|
// Affected user is someone else.
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make this weaker than TYPE_COMMENT.
|
|
|
|
return 0.25;
|
2012-12-11 14:00:07 -08:00
|
|
|
}
|
|
|
|
return 1.0;
|
|
|
|
}
|
|
|
|
|
2014-02-24 15:57:35 -08:00
|
|
|
public function isCommentTransaction() {
|
|
|
|
if ($this->hasComment()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_COMMENT:
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-03-22 06:25:03 -07:00
|
|
|
public function isInlineCommentTransaction() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-12-11 14:00:07 -08:00
|
|
|
public function getActionName() {
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_COMMENT:
|
|
|
|
return pht('Commented On');
|
|
|
|
case PhabricatorTransactions::TYPE_VIEW_POLICY:
|
|
|
|
case PhabricatorTransactions::TYPE_EDIT_POLICY:
|
2013-10-22 13:49:37 -07:00
|
|
|
case PhabricatorTransactions::TYPE_JOIN_POLICY:
|
2012-12-11 14:00:07 -08:00
|
|
|
return pht('Changed Policy');
|
|
|
|
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
|
|
|
|
return pht('Changed Subscribers');
|
2014-04-17 16:04:14 -07:00
|
|
|
case PhabricatorTransactions::TYPE_BUILDABLE:
|
|
|
|
switch ($this->getNewValue()) {
|
|
|
|
case HarbormasterBuildable::STATUS_PASSED:
|
|
|
|
return pht('Build Passed');
|
|
|
|
case HarbormasterBuildable::STATUS_FAILED:
|
|
|
|
return pht('Build Failed');
|
|
|
|
default:
|
|
|
|
return pht('Build Status');
|
|
|
|
}
|
2012-12-11 14:00:07 -08:00
|
|
|
default:
|
|
|
|
return pht('Updated');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getMailTags() {
|
|
|
|
return array();
|
|
|
|
}
|
|
|
|
|
2013-02-17 06:37:02 -08:00
|
|
|
public function hasChangeDetails() {
|
Allow CustomField to provide ApplicationTransaction change details
Summary:
Ref T3886. Ref T418. For fields like "Summary" and "Test Plan" where changes can't be summarized in one line, allow CustomField to provide a "(Show Details)" link and render a diff.
Also consolidate some of the existing copy/paste, and simplify this featuer slightly now that we've move to dialogs.
Test Plan:
{F115918}
- Viewed "description"-style field changes in phlux, pholio, legalpad, maniphest, differential, ponder (questions), ponder (answers), and repositories.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T3886, T418
Differential Revision: https://secure.phabricator.com/D8284
2014-02-21 11:53:04 -08:00
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_CUSTOMFIELD:
|
|
|
|
$field = $this->getTransactionCustomField();
|
|
|
|
if ($field) {
|
|
|
|
return $field->getApplicationTransactionHasChangeDetails($this);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2013-02-17 06:37:02 -08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-03-04 12:54:20 -08:00
|
|
|
public function renderChangeDetails(PhabricatorUser $viewer) {
|
Allow CustomField to provide ApplicationTransaction change details
Summary:
Ref T3886. Ref T418. For fields like "Summary" and "Test Plan" where changes can't be summarized in one line, allow CustomField to provide a "(Show Details)" link and render a diff.
Also consolidate some of the existing copy/paste, and simplify this featuer slightly now that we've move to dialogs.
Test Plan:
{F115918}
- Viewed "description"-style field changes in phlux, pholio, legalpad, maniphest, differential, ponder (questions), ponder (answers), and repositories.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T3886, T418
Differential Revision: https://secure.phabricator.com/D8284
2014-02-21 11:53:04 -08:00
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case PhabricatorTransactions::TYPE_CUSTOMFIELD:
|
|
|
|
$field = $this->getTransactionCustomField();
|
|
|
|
if ($field) {
|
|
|
|
return $field->getApplicationTransactionChangeDetails($this, $viewer);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-05-04 11:11:46 -07:00
|
|
|
return $this->renderTextCorpusChangeDetails(
|
|
|
|
$viewer,
|
|
|
|
$this->getOldValue(),
|
|
|
|
$this->getNewValue());
|
Allow CustomField to provide ApplicationTransaction change details
Summary:
Ref T3886. Ref T418. For fields like "Summary" and "Test Plan" where changes can't be summarized in one line, allow CustomField to provide a "(Show Details)" link and render a diff.
Also consolidate some of the existing copy/paste, and simplify this featuer slightly now that we've move to dialogs.
Test Plan:
{F115918}
- Viewed "description"-style field changes in phlux, pholio, legalpad, maniphest, differential, ponder (questions), ponder (answers), and repositories.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T3886, T418
Differential Revision: https://secure.phabricator.com/D8284
2014-02-21 11:53:04 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
public function renderTextCorpusChangeDetails(
|
|
|
|
PhabricatorUser $viewer,
|
|
|
|
$old,
|
|
|
|
$new) {
|
|
|
|
|
|
|
|
require_celerity_resource('differential-changeset-view-css');
|
|
|
|
|
|
|
|
$view = id(new PhabricatorApplicationTransactionTextDiffDetailView())
|
|
|
|
->setUser($viewer)
|
|
|
|
->setOldText($old)
|
|
|
|
->setNewText($new);
|
|
|
|
|
|
|
|
return $view->render();
|
2013-02-17 06:37:02 -08:00
|
|
|
}
|
2012-12-11 13:59:20 -08:00
|
|
|
|
2013-03-09 19:23:50 -08:00
|
|
|
public function attachTransactionGroup(array $group) {
|
2015-05-14 06:50:28 +10:00
|
|
|
assert_instances_of($group, __CLASS__);
|
2013-03-09 19:23:50 -08:00
|
|
|
$this->transactionGroup = $group;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getTransactionGroup() {
|
|
|
|
return $this->transactionGroup;
|
|
|
|
}
|
|
|
|
|
2013-12-27 05:51:15 -08:00
|
|
|
/**
|
|
|
|
* Should this transaction be visually grouped with an existing transaction
|
|
|
|
* group?
|
|
|
|
*
|
|
|
|
* @param list<PhabricatorApplicationTransaction> List of transactions.
|
|
|
|
* @return bool True to display in a group with the other transactions.
|
|
|
|
*/
|
|
|
|
public function shouldDisplayGroupWith(array $group) {
|
|
|
|
$this_source = null;
|
|
|
|
if ($this->getContentSource()) {
|
|
|
|
$this_source = $this->getContentSource()->getSource();
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($group as $xaction) {
|
|
|
|
// Don't group transactions by different authors.
|
|
|
|
if ($xaction->getAuthorPHID() != $this->getAuthorPHID()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Don't group transactions for different objects.
|
|
|
|
if ($xaction->getObjectPHID() != $this->getObjectPHID()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Don't group anything into a group which already has a comment.
|
2014-02-24 15:57:35 -08:00
|
|
|
if ($xaction->isCommentTransaction()) {
|
2013-12-27 05:51:15 -08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Don't group transactions from different content sources.
|
|
|
|
$other_source = null;
|
|
|
|
if ($xaction->getContentSource()) {
|
|
|
|
$other_source = $xaction->getContentSource()->getSource();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($other_source != $this_source) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Don't group transactions which happened more than 2 minutes apart.
|
|
|
|
$apart = abs($xaction->getDateCreated() - $this->getDateCreated());
|
|
|
|
if ($apart > (60 * 2)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-04-17 15:57:34 -07:00
|
|
|
public function renderExtraInformationLink() {
|
|
|
|
$herald_xscript_id = $this->getMetadataValue('herald:transcriptID');
|
|
|
|
|
|
|
|
if ($herald_xscript_id) {
|
|
|
|
return phutil_tag(
|
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => '/herald/transcript/'.$herald_xscript_id.'/',
|
|
|
|
),
|
|
|
|
pht('View Herald Transcript'));
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2014-10-01 07:09:34 -07:00
|
|
|
public function renderAsTextForDoorkeeper(
|
|
|
|
DoorkeeperFeedStoryPublisher $publisher,
|
|
|
|
PhabricatorFeedStory $story,
|
|
|
|
array $xactions) {
|
|
|
|
|
|
|
|
$text = array();
|
|
|
|
$body = array();
|
|
|
|
|
|
|
|
foreach ($xactions as $xaction) {
|
|
|
|
$xaction_body = $xaction->getBodyForMail();
|
|
|
|
if ($xaction_body !== null) {
|
|
|
|
$body[] = $xaction_body;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($xaction->shouldHideForMail($xactions)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$old_target = $xaction->getRenderingTarget();
|
2015-05-14 06:50:28 +10:00
|
|
|
$new_target = self::TARGET_TEXT;
|
2014-10-01 07:09:34 -07:00
|
|
|
$xaction->setRenderingTarget($new_target);
|
|
|
|
|
|
|
|
if ($publisher->getRenderWithImpliedContext()) {
|
|
|
|
$text[] = $xaction->getTitle();
|
|
|
|
} else {
|
2015-01-02 08:45:43 -08:00
|
|
|
$text[] = $xaction->getTitleForFeed();
|
2014-10-01 07:09:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
$xaction->setRenderingTarget($old_target);
|
|
|
|
}
|
|
|
|
|
|
|
|
$text = implode("\n", $text);
|
|
|
|
$body = implode("\n\n", $body);
|
|
|
|
|
|
|
|
return rtrim($text."\n\n".$body);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-09 19:23:50 -08:00
|
|
|
|
2012-12-11 13:59:20 -08:00
|
|
|
/* -( PhabricatorPolicyInterface Implementation )-------------------------- */
|
|
|
|
|
|
|
|
|
|
|
|
public function getCapabilities() {
|
|
|
|
return array(
|
|
|
|
PhabricatorPolicyCapability::CAN_VIEW,
|
|
|
|
PhabricatorPolicyCapability::CAN_EDIT,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getPolicy($capability) {
|
|
|
|
switch ($capability) {
|
|
|
|
case PhabricatorPolicyCapability::CAN_VIEW:
|
|
|
|
return $this->getViewPolicy();
|
|
|
|
case PhabricatorPolicyCapability::CAN_EDIT:
|
|
|
|
return $this->getEditPolicy();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
|
|
|
return ($viewer->getPHID() == $this->getAuthorPHID());
|
|
|
|
}
|
|
|
|
|
2013-09-27 08:43:41 -07:00
|
|
|
public function describeAutomaticCapability($capability) {
|
2015-02-02 14:41:50 -08:00
|
|
|
return pht(
|
|
|
|
'Transactions are visible to users that can see the object which was '.
|
|
|
|
'acted upon. Some transactions - in particular, comments - are '.
|
|
|
|
'editable by the transaction author.');
|
2013-09-27 08:43:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-07-21 23:59:22 +10:00
|
|
|
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
2014-05-01 18:25:30 -07:00
|
|
|
|
|
|
|
|
|
|
|
public function destroyObjectPermanently(
|
|
|
|
PhabricatorDestructionEngine $engine) {
|
|
|
|
|
|
|
|
$this->openTransaction();
|
|
|
|
$comment_template = null;
|
|
|
|
try {
|
|
|
|
$comment_template = $this->getApplicationTransactionCommentObject();
|
|
|
|
} catch (Exception $ex) {
|
|
|
|
// Continue; no comments for these transactions.
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($comment_template) {
|
|
|
|
$comments = $comment_template->loadAllWhere(
|
|
|
|
'transactionPHID = %s',
|
|
|
|
$this->getPHID());
|
|
|
|
foreach ($comments as $comment) {
|
|
|
|
$engine->destroyObject($comment);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->delete();
|
|
|
|
$this->saveTransaction();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-12-11 13:59:20 -08:00
|
|
|
}
|