1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-26 15:30:58 +01:00

Merge Differential comment migration to ApplicationTransactions

Summary: Ref T2222. This merges the `tmp.differential` branch, including the
comment -> application transaction migration, to `master`.

Auditors: btrahan
This commit is contained in:
epriestley 2014-02-13 17:04:53 -08:00
commit e88d0f9c42
21 changed files with 977 additions and 415 deletions

View file

@ -0,0 +1,222 @@
<?php
$conn_w = id(new DifferentialRevision())->establishConnection('w');
$rows = new LiskRawMigrationIterator($conn_w, 'differential_comment');
$content_source = PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_LEGACY,
array())->serialize();
echo "Migrating Differential comments to modern storage...\n";
foreach ($rows as $row) {
$id = $row['id'];
echo "Migrating comment {$id}...\n";
$revision = id(new DifferentialRevision())->load($row['revisionID']);
if (!$revision) {
echo "No revision, continuing.\n";
continue;
}
$revision_phid = $revision->getPHID();
$comments = queryfx_all(
$conn_w,
'SELECT * FROM %T WHERE legacyCommentID = %d',
'differential_transaction_comment',
$id);
$main_comments = array();
$inline_comments = array();
foreach ($comments as $comment) {
if ($comment['changesetID']) {
$inline_comments[] = $comment;
} else {
$main_comments[] = $comment;
}
}
$metadata = json_decode($row['metadata'], true);
if (!is_array($metadata)) {
$metadata = array();
}
$key_cc = DifferentialComment::METADATA_ADDED_CCS;
$key_add_rev = DifferentialComment::METADATA_ADDED_REVIEWERS;
$key_rem_rev = DifferentialComment::METADATA_REMOVED_REVIEWERS;
$key_diff_id = DifferentialComment::METADATA_DIFF_ID;
$xactions = array();
// Build the main action transaction.
switch ($row['action']) {
case DifferentialAction::ACTION_COMMENT:
case DifferentialAction::ACTION_ADDREVIEWERS:
case DifferentialAction::ACTION_ADDCCS:
case DifferentialAction::ACTION_UPDATE:
case DifferentialTransaction::TYPE_INLINE:
// These actions will have their transactions created by other rules.
break;
default:
// Otherwise, this is a normal action (like an accept or reject).
$xactions[] = array(
'type' => DifferentialTransaction::TYPE_ACTION,
'old' => null,
'new' => $row['action'],
);
break;
}
// Build the diff update transaction, if one exists.
$diff_id = idx($metadata, $key_diff_id);
if (!is_scalar($diff_id)) {
$diff_id = null;
}
if ($diff_id || $row['action'] == DifferentialAction::ACTION_UPDATE) {
$xactions[] = array(
'type' => DifferentialTransaction::TYPE_UPDATE,
'old' => null,
'new' => $diff_id,
);
}
// Build the add/remove reviewers transaction, if one exists.
$add_rev = idx($metadata, $key_add_rev, array());
if (!is_array($add_rev)) {
$add_rev = array();
}
$rem_rev = idx($metadata, $key_rem_rev, array());
if (!is_array($rem_rev)) {
$rem_rev = array();
}
if ($add_rev || $rem_rev) {
$old = array();
foreach ($rem_rev as $phid) {
if (!is_scalar($phid)) {
continue;
}
$old[$phid] = array(
'src' => $revision_phid,
'type' => PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER,
'dst' => $phid,
);
}
$new = array();
foreach ($add_rev as $phid) {
if (!is_scalar($phid)) {
continue;
}
$new[$phid] = array(
'src' => $revision_phid,
'type' => PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER,
'dst' => $phid,
);
}
$xactions[] = array(
'type' => PhabricatorTransactions::TYPE_EDGE,
'old' => $old,
'new' => $new,
'meta' => array(
'edge:type' => PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER,
),
);
}
// Build the CC transaction, if one exists.
$add_cc = idx($metadata, $key_cc, array());
if (!is_array($add_cc)) {
$add_cc = array();
}
if ($add_cc) {
$xactions[] = array(
'type' => PhabricatorTransactions::TYPE_SUBSCRIBERS,
'old' => array(),
'new' => array_fuse($add_cc),
);
}
// Build the main comment transaction.
foreach ($main_comments as $main) {
$xactions[] = array(
'type' => PhabricatorTransactions::TYPE_COMMENT,
'old' => null,
'new' => null,
'phid' => $main['transactionPHID'],
'comment' => $main,
);
}
// Build inline comment transactions.
foreach ($inline_comments as $inline) {
$xactions[] = array(
'type' => DifferentialTransaction::TYPE_INLINE,
'old' => null,
'new' => null,
'phid' => $inline['transactionPHID'],
'comment' => $inline,
);
}
foreach ($xactions as $xaction) {
// Generate a new PHID, if we don't already have one from the comment
// table. We pregenerated into the comment table to make this a little
// easier, so we only need to write to one table.
$xaction_phid = idx($xaction, 'phid');
if (!$xaction_phid) {
$xaction_phid = PhabricatorPHID::generateNewPHID(
PhabricatorApplicationTransactionPHIDTypeTransaction::TYPECONST,
DifferentialPHIDTypeRevision::TYPECONST);
}
unset($xaction['phid']);
$comment_phid = null;
$comment_version = 0;
if (idx($xaction, 'comment')) {
$comment_phid = $xaction['comment']['phid'];
$comment_version = 1;
}
$old = idx($xaction, 'old');
$new = idx($xaction, 'new');
$meta = idx($xaction, 'meta', array());
queryfx(
$conn_w,
'INSERT INTO %T (phid, authorPHID, objectPHID, viewPolicy, editPolicy,
commentPHID, commentVersion, transactionType, oldValue, newValue,
contentSource, metadata, dateCreated, dateModified)
VALUES (%s, %s, %s, %s, %s, %ns, %d, %s, %ns, %ns, %s, %s, %d, %d)',
'differential_transaction',
// PHID, authorPHID, objectPHID
$xaction_phid,
(string)$row['authorPHID'],
$revision_phid,
// viewPolicy, editPolicy, commentPHID, commentVersion
'public',
(string)$row['authorPHID'],
$comment_phid,
$comment_version,
// transactionType, oldValue, newValue, contentSource, metadata
$xaction['type'],
json_encode($old),
json_encode($new),
$content_source,
json_encode($meta),
// dates
$row['dateCreated'],
$row['dateModified']);
}
}
echo "Done.\n";

View file

@ -437,7 +437,6 @@ phutil_register_library_map(array(
'DifferentialReviewersFieldSpecification' => 'applications/differential/field/specification/DifferentialReviewersFieldSpecification.php',
'DifferentialReviewersView' => 'applications/differential/view/DifferentialReviewersView.php',
'DifferentialRevision' => 'applications/differential/storage/DifferentialRevision.php',
'DifferentialRevisionCommentListView' => 'applications/differential/view/DifferentialRevisionCommentListView.php',
'DifferentialRevisionCommentView' => 'applications/differential/view/DifferentialRevisionCommentView.php',
'DifferentialRevisionControlSystem' => 'applications/differential/constants/DifferentialRevisionControlSystem.php',
'DifferentialRevisionDetailRenderer' => 'applications/differential/controller/DifferentialRevisionDetailRenderer.php',
@ -464,6 +463,8 @@ phutil_register_library_map(array(
'DifferentialTitleFieldSpecification' => 'applications/differential/field/specification/DifferentialTitleFieldSpecification.php',
'DifferentialTransaction' => 'applications/differential/storage/DifferentialTransaction.php',
'DifferentialTransactionComment' => 'applications/differential/storage/DifferentialTransactionComment.php',
'DifferentialTransactionQuery' => 'applications/differential/query/DifferentialTransactionQuery.php',
'DifferentialTransactionView' => 'applications/differential/view/DifferentialTransactionView.php',
'DifferentialUnitFieldSpecification' => 'applications/differential/field/specification/DifferentialUnitFieldSpecification.php',
'DifferentialUnitStatus' => 'applications/differential/constants/DifferentialUnitStatus.php',
'DifferentialUnitTestResult' => 'applications/differential/constants/DifferentialUnitTestResult.php',
@ -2856,11 +2857,7 @@ phutil_register_library_map(array(
'DifferentialChangesetTwoUpRenderer' => 'DifferentialChangesetHTMLRenderer',
'DifferentialChangesetTwoUpTestRenderer' => 'DifferentialChangesetTestRenderer',
'DifferentialChangesetViewController' => 'DifferentialController',
'DifferentialComment' =>
array(
0 => 'DifferentialDAO',
1 => 'PhabricatorMarkupInterface',
),
'DifferentialComment' => 'PhabricatorMarkupInterface',
'DifferentialCommentEditor' => 'PhabricatorEditor',
'DifferentialCommentMail' => 'DifferentialMail',
'DifferentialCommentPreviewController' => 'DifferentialController',
@ -2954,7 +2951,6 @@ phutil_register_library_map(array(
5 => 'HarbormasterBuildableInterface',
6 => 'PhabricatorSubscribableInterface',
),
'DifferentialRevisionCommentListView' => 'AphrontView',
'DifferentialRevisionCommentView' => 'AphrontView',
'DifferentialRevisionDetailView' => 'AphrontView',
'DifferentialRevisionEditController' => 'DifferentialController',
@ -2981,6 +2977,8 @@ phutil_register_library_map(array(
'DifferentialTitleFieldSpecification' => 'DifferentialFreeformFieldSpecification',
'DifferentialTransaction' => 'PhabricatorApplicationTransaction',
'DifferentialTransactionComment' => 'PhabricatorApplicationTransactionComment',
'DifferentialTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'DifferentialTransactionView' => 'PhabricatorApplicationTransactionView',
'DifferentialUnitFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialViewPolicyFieldSpecification' => 'DifferentialFieldSpecification',
'DiffusionBranchTableController' => 'DiffusionController',

View file

@ -1,11 +1,16 @@
<?php
/**
* @group conduit
*/
final class ConduitAPI_differential_getrevisioncomments_Method
extends ConduitAPI_differential_Method {
public function getMethodStatus() {
return self::METHOD_STATUS_DEPRECATED;
}
public function getMethodStatusDescription() {
return pht('Obsolete and doomed, see T2222.');
}
public function getMethodDescription() {
return "Retrieve Differential Revision Comments.";
}
@ -13,7 +18,7 @@ final class ConduitAPI_differential_getrevisioncomments_Method
public function defineParamTypes() {
return array(
'ids' => 'required list<int>',
'inlines' => 'optional bool',
'inlines' => 'optional bool (deprecated)',
);
}
@ -34,47 +39,36 @@ final class ConduitAPI_differential_getrevisioncomments_Method
return $results;
}
$comments = id(new DifferentialCommentQuery())
->withRevisionIDs($revision_ids)
$revisions = id(new DifferentialRevisionQuery())
->setViewer($request->getUser())
->withIDs($revision_ids)
->execute();
$with_inlines = $request->getValue('inlines');
if ($with_inlines) {
$inlines = id(new DifferentialInlineCommentQuery())
->withRevisionIDs($revision_ids)
->execute();
$changesets = array();
if ($inlines) {
$changesets = id(new DifferentialChangeset())->loadAllWhere(
'id IN (%Ld)',
array_unique(mpull($inlines, 'getChangesetID')));
$inlines = mgroup($inlines, 'getCommentID');
}
if (!$revisions) {
return $results;
}
$comments = id(new DifferentialCommentQuery())
->withRevisionPHIDs(mpull($revisions, 'getPHID'))
->execute();
$revisions = mpull($revisions, null, 'getPHID');
foreach ($comments as $comment) {
// TODO: Sort this out in the ID -> PHID change.
$revision_id = $comment->getRevisionID();
$revision = idx($revisions, $comment->getRevisionPHID());
if (!$revision) {
continue;
}
$result = array(
'revisionID' => $revision_id,
'revisionID' => $revision->getID(),
'action' => $comment->getAction(),
'authorPHID' => $comment->getAuthorPHID(),
'dateCreated' => $comment->getDateCreated(),
'content' => $comment->getContent(),
);
if ($with_inlines) {
$result['inlines'] = array();
foreach (idx($inlines, $comment->getID(), array()) as $inline) {
$changeset = idx($changesets, $inline->getChangesetID());
$result['inlines'][] = $this->buildInlineInfoDictionary(
$inline,
$changeset);
}
// TODO: Put synthetic inlines without an attached comment somewhere.
}
$results[$revision_id][] = $result;
$results[$revision->getID()][] = $result;
}
return $results;

View file

@ -90,6 +90,11 @@ final class DifferentialAction {
$title = pht('%s reopened this revision.',
$author_name);
break;
case DifferentialTransaction::TYPE_INLINE:
$title = pht(
'%s added an inline comment.',
$author_name);
break;
default:
$title = pht('Ghosts happened to this revision.');
break;
@ -117,6 +122,7 @@ final class DifferentialAction {
self::ACTION_ADDCCS => 'added CCs to',
self::ACTION_CLAIM => 'commandeered',
self::ACTION_REOPEN => 'reopened',
DifferentialTransaction::TYPE_INLINE => 'commented on',
);
if (!empty($verbs[$action])) {

View file

@ -258,21 +258,25 @@ final class DifferentialRevisionViewController extends DifferentialController {
$revision_detail->setActions($actions);
$revision_detail->setUser($user);
$comment_view = new DifferentialRevisionCommentListView();
$comment_view->setComments($comments);
$comment_view->setHandles($handles);
$comment_view->setInlineComments($inlines);
$comment_view->setChangesets($all_changesets);
$comment_view->setUser($user);
$comment_view->setTargetDiff($target);
$comment_view->setVersusDiffID($diff_vs);
$comment_view->setRevision($revision);
$comment_view = $this->buildTransactions(
$revision,
$diff_vs ? $diffs[$diff_vs] : $target,
$target,
$all_changesets);
$wrap_id = celerity_generate_unique_node_id();
$comment_view = phutil_tag(
'div',
array(
'id' => $wrap_id,
),
$comment_view);
if ($arc_project) {
Javelin::initBehavior(
'repository-crossreference',
array(
'section' => $comment_view->getID(),
'section' => $wrap_id,
'projects' => $project_phids,
));
}
@ -926,4 +930,38 @@ final class DifferentialRevisionViewController extends DifferentialController {
return id(new AphrontRedirectResponse())->setURI($file->getBestURI());
}
private function buildTransactions(
DifferentialRevision $revision,
DifferentialDiff $left_diff,
DifferentialDiff $right_diff,
array $changesets) {
$viewer = $this->getRequest()->getUser();
$xactions = id(new DifferentialTransactionQuery())
->setViewer($viewer)
->withObjectPHIDs(array($revision->getPHID()))
->needComments(true)
->execute();
$engine = id(new PhabricatorMarkupEngine())
->setViewer($viewer);
$timeline = id(new DifferentialTransactionView())
->setUser($viewer)
->setObjectPHID($revision->getPHID())
->setChangesets($changesets)
->setRevision($revision)
->setLeftDiff($left_diff)
->setRightDiff($right_diff)
->setTransactions($xactions);
// TODO: Make this work and restore edit links. We need to copy
// `revisionPHID` to the new version of the comment. This should be simple,
// but can happen post-merge. See T2222.
$timeline->setShowEditActions(false);
return $timeline;
}
}

View file

@ -561,9 +561,15 @@ final class DifferentialCommentEditor extends PhabricatorEditor {
->setRevision($revision);
if ($this->contentSource) {
$template->setContentSource($this->contentSource);
$content_source = $this->contentSource;
} else {
$content_source = PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_LEGACY,
array());
}
$template->setContentSource($content_source);
$comments = array();
// If this edit performs a meaningful action, save a transaction for the
@ -624,7 +630,7 @@ final class DifferentialCommentEditor extends PhabricatorEditor {
// If this edit has comments or inline comments, save a transaction for
// the comment content.
if (strlen($this->message) || $inline_comments) {
if (strlen($this->message)) {
$comments[] = id(clone $template)
->setAction(DifferentialAction::ACTION_COMMENT)
->setContent((string)$this->message);
@ -634,8 +640,6 @@ final class DifferentialCommentEditor extends PhabricatorEditor {
$comment->save();
}
$last_comment = last($comments);
$changesets = array();
if ($inline_comments) {
$load_ids = mpull($inline_comments, 'getChangesetID');
@ -646,12 +650,13 @@ final class DifferentialCommentEditor extends PhabricatorEditor {
$load_ids);
}
foreach ($inline_comments as $inline) {
// For now, attach inlines to the last comment. We'll eventually give
// them their own transactions, but this would be fairly gross during
// the storage transition and we'll have to do special thing with these
// during migration anyway.
$inline->setCommentID($last_comment->getID());
$inline->save();
$inline_xaction_comment = $inline->getTransactionCommentForSave();
$inline_xaction_comment->setRevisionPHID($revision->getPHID());
$comments[] = id(clone $template)
->setAction(DifferentialTransaction::TYPE_INLINE)
->setProxyComment($inline_xaction_comment)
->save();
}
}
@ -702,7 +707,7 @@ final class DifferentialCommentEditor extends PhabricatorEditor {
// NOTE: Don't use this, it will be removed after ApplicationTransactions.
// For now, it powers inline comment rendering over the Asana brdige.
'temporaryCommentID' => $last_comment->getID(),
'temporaryTransactionPHIDs' => mpull($comments, 'getPHID'),
);
id(new PhabricatorFeedStoryPublisher())

View file

@ -701,10 +701,18 @@ final class DifferentialRevisionEditor extends PhabricatorEditor {
$template = id(new DifferentialComment())
->setAuthorPHID($this->getActorPHID())
->setRevision($this->revision);
if ($this->contentSource) {
$template->setContentSource($this->contentSource);
$content_source = $this->contentSource;
} else {
$content_source = PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_LEGACY,
array());
}
$template->setContentSource($content_source);
// Write the "update active diff" transaction.
id(clone $template)
->setAction(DifferentialAction::ACTION_UPDATE)

View file

@ -154,6 +154,10 @@ final class DifferentialCommentMail extends DifferentialMail {
$body[] = null;
foreach ($this->getComments() as $comment) {
if ($comment->getAction() == DifferentialTransaction::TYPE_INLINE) {
// These have comment content now, but are rendered below.
continue;
}
$content = $comment->getContent();
if (strlen($content)) {
$body[] = $this->formatText($content);

View file

@ -6,67 +6,29 @@
final class DifferentialCommentQuery
extends PhabricatorOffsetPagedQuery {
private $revisionIDs;
private $revisionPHIDs;
public function withRevisionIDs(array $ids) {
$this->revisionIDs = $ids;
public function withRevisionPHIDs(array $phids) {
$this->revisionPHIDs = $phids;
return $this;
}
public function execute() {
$table = new DifferentialComment();
$conn_r = $table->establishConnection('r');
// TODO: We're getting rid of this, it is the bads.
$viewer = PhabricatorUser::getOmnipotentUser();
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildLimitClause($conn_r));
$xactions = id(new DifferentialTransactionQuery())
->setViewer($viewer)
->withObjectPHIDs($this->revisionPHIDs)
->needComments(true)
->execute();
$comments = $table->loadAllFromArray($data);
// We've moved the actual text storage into DifferentialTransactionComment,
// so load the relevant pieces of text we need.
if ($comments) {
$this->loadCommentText($comments);
$results = array();
foreach ($xactions as $xaction) {
$results[] = DifferentialComment::newFromModernTransaction($xaction);
}
return $comments;
return $results;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->revisionIDs) {
$where[] = qsprintf(
$conn_r,
'revisionID IN (%Ld)',
$this->revisionIDs);
}
return $this->formatWhereClause($where);
}
private function loadCommentText(array $comments) {
$table = new DifferentialTransactionComment();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T WHERE legacyCommentID IN (%Ld) AND changesetID IS NULL',
$table->getTableName(),
mpull($comments, 'getID'));
$texts = $table->loadAllFromArray($data);
$texts = mpull($texts, null, 'getLegacyCommentID');
foreach ($comments as $comment) {
$text = idx($texts, $comment->getID());
if ($text) {
$comment->setProxyComment($text);
}
}
}
}

View file

@ -0,0 +1,10 @@
<?php
final class DifferentialTransactionQuery
extends PhabricatorApplicationTransactionQuery {
public function getTemplateApplicationTransaction() {
return new DifferentialTransaction();
}
}

View file

@ -53,7 +53,7 @@ final class DifferentialSearchIndexer
time());
$comments = id(new DifferentialCommentQuery())
->withRevisionIDs(array($rev->getID()))
->withRevisionPHIDs(array($rev->getPHID()))
->execute();
$inlines = id(new DifferentialInlineCommentQuery())

View file

@ -1,6 +1,9 @@
<?php
final class DifferentialComment extends DifferentialDAO
/**
* Temporary proxy shell around ApplicationTransactions.
*/
final class DifferentialComment
implements PhabricatorMarkupInterface {
const METADATA_ADDED_REVIEWERS = 'added-reviewers';
@ -10,36 +13,244 @@ final class DifferentialComment extends DifferentialDAO
const MARKUP_FIELD_BODY = 'markup:body';
protected $authorPHID;
protected $revisionID;
protected $action;
protected $content = '';
protected $cache;
protected $metadata = array();
protected $contentSource;
private $arbitraryDiffForFacebook;
private $proxyComment;
private $proxy;
public function __construct() {
$this->proxy = new DifferentialTransaction();
}
public function __clone() {
$this->proxy = clone $this->proxy;
if ($this->proxyComment) {
$this->proxyComment = clone $this->proxyComment;
}
}
public static function newFromModernTransaction(
DifferentialTransaction $xaction) {
$obj = new DifferentialComment();
$obj->proxy = $xaction;
if ($xaction->hasComment()) {
$obj->proxyComment = $xaction->getComment();
}
return $obj;
}
public function getPHID() {
return $this->proxy->getPHID();
}
public function getContent() {
return $this->getProxyComment()->getContent();
}
public function setContent($content) {
// NOTE: We no longer read this field, but there's no cost to continuing
// to write it in case something goes horribly wrong, since it makes it
// far easier to back out of this.
$this->content = $content;
$this->getProxyComment()->setContent($content);
return $this;
}
public function getAuthorPHID() {
return $this->proxy->getAuthorPHID();
}
public function setAuthorPHID($author_phid) {
$this->proxy->setAuthorPHID($author_phid);
return $this;
}
public function setContentSource($content_source) {
$this->proxy->setContentSource($content_source);
$this->proxyComment->setContentSource($content_source);
return $this;
}
public function setAction($action) {
$meta = array();
switch ($action) {
case DifferentialAction::ACTION_COMMENT:
$type = PhabricatorTransactions::TYPE_COMMENT;
$old = null;
$new = null;
break;
case DifferentialAction::ACTION_ADDREVIEWERS:
$type = PhabricatorTransactions::TYPE_EDGE;
$old = array();
$new = array();
$meta = array(
'edge:type' => PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER,
);
break;
case DifferentialAction::ACTION_ADDCCS:
$type = PhabricatorTransactions::TYPE_SUBSCRIBERS;
$old = array();
$new = array();
break;
case DifferentialAction::ACTION_UPDATE:
$type = DifferentialTransaction::TYPE_UPDATE;
$old = null;
$new = null;
break;
case DifferentialTransaction::TYPE_INLINE:
$type = $action;
$old = null;
$new = null;
break;
default:
$type = DifferentialTransaction::TYPE_ACTION;
$old = null;
$new = $action;
break;
}
$xaction = $this->proxy;
$xaction
->setTransactionType($type)
->setOldValue($old)
->setNewValue($new);
if ($meta) {
foreach ($meta as $key => $value) {
$xaction->setMetadataValue($key, $value);
}
}
return $this;
}
public function getAction() {
switch ($this->proxy->getTransactionType()) {
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
return DifferentialAction::ACTION_ADDCCS;
case DifferentialTransaction::TYPE_UPDATE:
return DifferentialAction::ACTION_UPDATE;
case PhabricatorTransactions::TYPE_EDGE:
return DifferentialAction::ACTION_ADDREVIEWERS;
case PhabricatorTransactions::TYPE_COMMENT:
return DifferentialAction::ACTION_COMMENT;
case DifferentialTransaction::TYPE_INLINE:
return DifferentialTransaction::TYPE_INLINE;
default:
return $this->proxy->getNewValue();
}
}
public function setMetadata(array $metadata) {
if (!$this->proxy->getTransactionType()) {
throw new Exception(pht('Call setAction() before setMetadata()!'));
}
$key_cc = self::METADATA_ADDED_CCS;
$key_add_rev = self::METADATA_ADDED_REVIEWERS;
$key_rem_rev = self::METADATA_REMOVED_REVIEWERS;
$key_diff_id = self::METADATA_DIFF_ID;
switch ($this->proxy->getTransactionType()) {
case DifferentialTransaction::TYPE_UPDATE:
$id = idx($metadata, $key_diff_id);
$this->proxy->setNewValue($id);
break;
case PhabricatorTransactions::TYPE_EDGE:
$rem = idx($metadata, $key_rem_rev, array());
$old = array();
foreach ($rem as $phid) {
$old[$phid] = array(
'src' => $this->proxy->getObjectPHID(),
'type' => PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER,
'dst' => $phid,
);
}
$this->proxy->setOldValue($old);
$add = idx($metadata, $key_add_rev, array());
$new = array();
foreach ($add as $phid) {
$new[$phid] = array(
'src' => $this->proxy->getObjectPHID(),
'type' => PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER,
'dst' => $phid,
);
}
$this->proxy->setNewValue($new);
break;
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
$phids = idx($metadata, $key_cc, array());
$new = array();
foreach ($phids as $phid) {
$new[$phid] = $phid;
}
$this->proxy->setNewValue($new);
break;
default:
break;
}
return $this;
}
public function getMetadata() {
if (!$this->proxy->getTransactionType()) {
throw new Exception(pht('Call setAction() before getMetadata()!'));
}
$key_cc = self::METADATA_ADDED_CCS;
$key_add_rev = self::METADATA_ADDED_REVIEWERS;
$key_rem_rev = self::METADATA_REMOVED_REVIEWERS;
$key_diff_id = self::METADATA_DIFF_ID;
$type = $this->proxy->getTransactionType();
switch ($type) {
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
$value = $this->proxy->getNewValue();
if (!$value) {
$value = array();
}
return array(
$key_cc => $value,
);
case DifferentialTransaction::TYPE_UPDATE:
return array(
$key_diff_id => $this->proxy->getNewValue(),
);
case PhabricatorTransactions::TYPE_EDGE:
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
$old = $this->proxy->getOldValue();
if (!$old) {
$old = array();
}
$new = $this->proxy->getNewValue();
if (!$new) {
$new = array();
}
$rem = array_diff_key($old, $new);
$add = array_diff_key($new, $old);
if ($type == PhabricatorTransactions::TYPE_EDGE) {
return array(
$key_add_rev => array_keys($add),
$key_rem_rev => array_keys($rem),
);
} else {
return array(
$key_cc => array_keys($add),
);
}
default:
return array();
}
}
public function getContentSource() {
return $this->proxy->getContentSource();
}
private function getProxyComment() {
if (!$this->proxyComment) {
$this->proxyComment = new DifferentialTransactionComment();
@ -48,16 +259,14 @@ final class DifferentialComment extends DifferentialDAO
}
public function setProxyComment(DifferentialTransactionComment $proxy) {
if ($this->proxyComment) {
throw new Exception(pht('You can not overwrite a proxy comment.'));
}
$this->proxyComment = $proxy;
return $this;
}
public function setRevision(DifferentialRevision $revision) {
$this->getProxyComment()->setRevisionPHID($revision->getPHID());
return $this->setRevisionID($revision->getID());
$this->proxy->setObjectPHID($revision->getPHID());
return $this;
}
public function giveFacebookSomeArbitraryDiff(DifferentialDiff $diff) {
@ -66,48 +275,19 @@ final class DifferentialComment extends DifferentialDAO
}
public function getRequiredHandlePHIDs() {
$phids = array();
$metadata = $this->getMetadata();
$added_reviewers = idx(
$metadata,
self::METADATA_ADDED_REVIEWERS);
if ($added_reviewers) {
foreach ($added_reviewers as $phid) {
$phids[] = $phid;
}
}
$added_ccs = idx(
$metadata,
self::METADATA_ADDED_CCS);
if ($added_ccs) {
foreach ($added_ccs as $phid) {
$phids[] = $phid;
}
switch ($this->proxy->getTransactionType()) {
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
case PhabricatorTransactions::TYPE_EDGE:
return array_merge(
array_keys($this->proxy->getOldValue()),
array_keys($this->proxy->getNewValue()));
}
return $phids;
}
public function getConfiguration() {
return array(
self::CONFIG_SERIALIZATION => array(
'metadata' => self::SERIALIZATION_JSON,
),
) + parent::getConfiguration();
}
public function setContentSource(PhabricatorContentSource $content_source) {
$this->contentSource = $content_source->serialize();
return $this;
}
public function getContentSource() {
return PhabricatorContentSource::newFromSerialized($this->contentSource);
return array();
}
public function getMarkupFieldKey($field) {
return 'DC:'.$this->getID();
return 'DC:'.$this->getPHID();
}
public function newMarkupEngine($field) {
@ -126,37 +306,49 @@ final class DifferentialComment extends DifferentialDAO
}
public function shouldUseMarkupCache($field) {
return (bool)$this->getID();
return (bool)$this->getPHID();
}
public function getDateCreated() {
return $this->proxy->getDateCreated();
}
public function getRevisionPHID() {
return $this->proxy->getObjectPHID();
}
public function save() {
$this->openTransaction();
$result = parent::save();
$this->proxy->openTransaction();
$this->proxy
->setViewPolicy('public')
->setEditPolicy($this->getAuthorPHID())
->save();
if ($this->getContent() !== null) {
$content_source = PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_LEGACY,
array());
if ($this->getContent() !== null ||
$this->getProxyComment()->getChangesetID()) {
$xaction_phid = PhabricatorPHID::generateNewPHID(
PhabricatorApplicationTransactionPHIDTypeTransaction::TYPECONST,
DifferentialPHIDTypeRevision::TYPECONST);
$proxy = $this->getProxyComment();
$proxy
$this->getProxyComment()
->setAuthorPHID($this->getAuthorPHID())
->setViewPolicy('public')
->setEditPolicy($this->getAuthorPHID())
->setContentSource($content_source)
->setCommentVersion(1)
->setLegacyCommentID($this->getID())
->setTransactionPHID($xaction_phid)
->setTransactionPHID($this->proxy->getPHID())
->save();
$this->proxy
->setCommentVersion(1)
->setCommentPHID($this->getProxyComment()->getPHID())
->save();
}
$this->saveTransaction();
$this->proxy->saveTransaction();
return $result;
return $this;
}
public function delete() {
$this->proxy->delete();
return $this;
}
}

View file

@ -14,7 +14,7 @@ final class DifferentialInlineComment
$this->proxy = clone $this->proxy;
}
public function save() {
public function getTransactionCommentForSave() {
$content_source = PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_LEGACY,
array());
@ -23,8 +23,14 @@ final class DifferentialInlineComment
->setViewPolicy('public')
->setEditPolicy($this->getAuthorPHID())
->setContentSource($content_source)
->setCommentVersion(1)
->save();
->setCommentVersion(1);
return $this->proxy;
}
public function save() {
$this->getTransactionCommentForSave()->save();
return $this;
}
@ -74,7 +80,7 @@ final class DifferentialInlineComment
}
public function isDraft() {
return !$this->getCommentID();
return !$this->proxy->getTransactionPHID();
}
public function setChangesetID($id) {

View file

@ -158,7 +158,7 @@ final class DifferentialRevision extends DifferentialDAO
return array();
}
return id(new DifferentialCommentQuery())
->withRevisionIDs(array($this->getID()))
->withRevisionPHIDs(array($this->getPHID()))
->execute();
}
@ -194,7 +194,7 @@ final class DifferentialRevision extends DifferentialDAO
$this->getID());
$comments = id(new DifferentialCommentQuery())
->withRevisionIDs(array($this->getID()))
->withRevisionPHIDs(array($this->getPHID()))
->execute();
foreach ($comments as $comment) {
$comment->delete();

View file

@ -2,6 +2,10 @@
final class DifferentialTransaction extends PhabricatorApplicationTransaction {
const TYPE_INLINE = 'differential:inline';
const TYPE_UPDATE = 'differential:update';
const TYPE_ACTION = 'differential:action';
public function getApplicationName() {
return 'differential';
}
@ -14,4 +18,101 @@ final class DifferentialTransaction extends PhabricatorApplicationTransaction {
return new DifferentialTransactionComment();
}
public function getTitle() {
$author_phid = $this->getAuthorPHID();
$author_handle = $this->renderHandleLink($author_phid);
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_INLINE:
return pht(
'%s added inline comments.',
$author_handle);
case self::TYPE_UPDATE:
if ($new) {
// TODO: Migrate to PHIDs and use handles here?
// TODO: Link this?
return pht(
'%s updated this revision to Diff #%d.',
$author_handle,
$new);
} else {
return pht(
'%s updated this revision.',
$author_handle);
}
case self::TYPE_ACTION:
return DifferentialAction::getBasicStoryText($new, $author_handle);
}
return parent::getTitle();
}
public function getIcon() {
switch ($this->getTransactionType()) {
case self::TYPE_INLINE:
return 'comment';
case self::TYPE_UPDATE:
return 'refresh';
case self::TYPE_ACTION:
switch ($this->getNewValue()) {
case DifferentialAction::ACTION_CLOSE:
return 'ok';
case DifferentialAction::ACTION_ACCEPT:
return 'enable';
case DifferentialAction::ACTION_REJECT:
case DifferentialAction::ACTION_ABANDON:
return 'delete';
case DifferentialAction::ACTION_RETHINK:
return 'disable';
case DifferentialAction::ACTION_REQUEST:
return 'refresh';
case DifferentialAction::ACTION_RECLAIM:
case DifferentialAction::ACTION_REOPEN:
return 'new';
case DifferentialAction::ACTION_RESIGN:
return 'undo';
case DifferentialAction::ACTION_CLAIM:
return 'user';
}
}
return parent::getIcon();
}
public function getColor() {
switch ($this->getTransactionType()) {
case self::TYPE_UPDATE:
return PhabricatorTransactions::COLOR_SKY;
case self::TYPE_ACTION:
switch ($this->getNewValue()) {
case DifferentialAction::ACTION_CLOSE:
return PhabricatorTransactions::COLOR_BLUE;
case DifferentialAction::ACTION_ACCEPT:
return PhabricatorTransactions::COLOR_GREEN;
case DifferentialAction::ACTION_REJECT:
return PhabricatorTransactions::COLOR_RED;
case DifferentialAction::ACTION_ABANDON:
return PhabricatorTransactions::COLOR_BLACK;
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();
}
}

View file

@ -1,209 +0,0 @@
<?php
final class DifferentialRevisionCommentListView extends AphrontView {
private $comments;
private $handles;
private $inlines;
private $changesets;
private $target;
private $versusDiffID;
private $id;
private $revision;
public function setRevision(DifferentialRevision $revision) {
$this->revision = $revision;
return $this;
}
public function getRevision() {
return $this->revision;
}
public function setComments(array $comments) {
assert_instances_of($comments, 'DifferentialComment');
$this->comments = $comments;
return $this;
}
public function setInlineComments(array $inline_comments) {
assert_instances_of($inline_comments, 'PhabricatorInlineCommentInterface');
$this->inlines = $inline_comments;
return $this;
}
public function setHandles(array $handles) {
assert_instances_of($handles, 'PhabricatorObjectHandle');
$this->handles = $handles;
return $this;
}
public function setChangesets(array $changesets) {
assert_instances_of($changesets, 'DifferentialChangeset');
$this->changesets = $changesets;
return $this;
}
public function setTargetDiff(DifferentialDiff $target) {
$this->target = $target;
return $this;
}
public function setVersusDiffID($diff_vs) {
$this->versusDiffID = $diff_vs;
return $this;
}
public function getID() {
if (!$this->id) {
$this->id = celerity_generate_unique_node_id();
}
return $this->id;
}
public function render() {
$this->requireResource('differential-revision-comment-list-css');
$engine = new PhabricatorMarkupEngine();
$engine->setViewer($this->user);
foreach ($this->comments as $comment) {
$comment->giveFacebookSomeArbitraryDiff($this->target);
$engine->addObject(
$comment,
DifferentialComment::MARKUP_FIELD_BODY);
}
foreach ($this->inlines as $inline) {
$engine->addObject(
$inline,
PhabricatorInlineCommentInterface::MARKUP_FIELD_BODY);
}
$engine->process();
$inlines = mgroup($this->inlines, 'getCommentID');
$num = 1;
$html = array();
foreach ($this->comments as $comment) {
$view = new DifferentialRevisionCommentView();
$view->setComment($comment);
$view->setUser($this->user);
$view->setHandles($this->handles);
$view->setMarkupEngine($engine);
$view->setInlineComments(idx($inlines, $comment->getID(), array()));
$view->setChangesets($this->changesets);
$view->setTargetDiff($this->target);
$view->setRevision($this->getRevision());
$view->setVersusDiffID($this->versusDiffID);
if ($comment->getAction() == DifferentialAction::ACTION_SUMMARIZE) {
$view->setAnchorName('summary');
} else if ($comment->getAction() == DifferentialAction::ACTION_TESTPLAN) {
$view->setAnchorName('test-plan');
} else {
$view->setAnchorName('comment-'.$num);
$num++;
}
$html[] = $view->render();
}
$objs = array_reverse(array_values($this->comments));
$html = array_reverse(array_values($html));
$user = $this->user;
$last_comment = null;
// Find the most recent comment by the viewer.
foreach ($objs as $position => $comment) {
if ($user && ($comment->getAuthorPHID() == $user->getPHID())) {
if ($last_comment === null) {
$last_comment = $position;
} else if ($last_comment == $position - 1) {
// If the viewer made several comments in a row, show them all. This
// is a spaz rule for epriestley.
$last_comment = $position;
}
}
}
$header = array();
$hidden = array();
if ($last_comment !== null) {
foreach ($objs as $position => $comment) {
if (!$comment->getID()) {
// These are synthetic comments with summary/test plan information.
$header[] = $html[$position];
unset($html[$position]);
continue;
}
if ($position <= $last_comment) {
// Always show comments after the viewer's last comment.
continue;
}
if ($position < 3) {
// Always show the 3 most recent comments.
continue;
}
$hidden[] = $position;
}
}
if (count($hidden) <= 3) {
// Don't hide if there's not much to hide.
$hidden = array();
}
$header = array_reverse($header);
$hidden = array_select_keys($html, $hidden);
$visible = array_diff_key($html, $hidden);
$hidden = array_reverse($hidden);
$visible = array_reverse($visible);
if ($hidden) {
$this->initBehavior(
'differential-show-all-comments',
array(
'markup' => implode("\n", $hidden),
));
$hidden = javelin_tag(
'div',
array(
'sigil' => "differential-all-comments-container",
),
phutil_tag(
'div',
array(
'class' => 'differential-older-comments-are-hidden',
),
array(
pht(
'%s older comments are hidden.',
new PhutilNumber(count($hidden))),
' ',
javelin_tag(
'a',
array(
'href' => '#',
'mustcapture' => true,
'sigil' => 'differential-show-all-comments',
),
pht('Show all comments.')),
)));
} else {
$hidden = null;
}
return javelin_tag(
'div',
array(
'class' => 'differential-comment-list',
'id' => $this->getID(),
),
array_merge($header, array($hidden), $visible));
}
}

View file

@ -0,0 +1,191 @@
<?php
final class DifferentialTransactionView
extends PhabricatorApplicationTransactionView {
private $changesets;
private $revision;
private $rightDiff;
private $leftDiff;
public function setLeftDiff(DifferentialDiff $left_diff) {
$this->leftDiff = $left_diff;
return $this;
}
public function getLeftDiff() {
return $this->leftDiff;
}
public function setRightDiff(DifferentialDiff $right_diff) {
$this->rightDiff = $right_diff;
return $this;
}
public function getRightDiff() {
return $this->rightDiff;
}
public function setRevision(DifferentialRevision $revision) {
$this->revision = $revision;
return $this;
}
public function getRevision() {
return $this->revision;
}
public function setChangesets(array $changesets) {
assert_instances_of($changesets, 'DifferentialChangeset');
$this->changesets = $changesets;
return $this;
}
public function getChangesets() {
return $this->changesets;
}
// TODO: There's a whole lot of code duplication between this and
// PholioTransactionView to handle inlines. Merge this into the core? Some of
// it can probably be shared, while other parts are trickier.
protected function shouldGroupTransactions(
PhabricatorApplicationTransaction $u,
PhabricatorApplicationTransaction $v) {
if ($u->getAuthorPHID() != $v->getAuthorPHID()) {
// Don't group transactions by different authors.
return false;
}
if (($v->getDateCreated() - $u->getDateCreated()) > 60) {
// Don't group if transactions that happened more than 60s apart.
return false;
}
switch ($u->getTransactionType()) {
case PhabricatorTransactions::TYPE_COMMENT:
case DifferentialTransaction::TYPE_INLINE:
break;
default:
return false;
}
switch ($v->getTransactionType()) {
case DifferentialTransaction::TYPE_INLINE:
return true;
}
return parent::shouldGroupTransactions($u, $v);
}
protected function renderTransactionContent(
PhabricatorApplicationTransaction $xaction) {
$out = array();
$type_inline = DifferentialTransaction::TYPE_INLINE;
$group = $xaction->getTransactionGroup();
if ($xaction->getTransactionType() == $type_inline) {
array_unshift($group, $xaction);
} else {
$out[] = parent::renderTransactionContent($xaction);
}
if (!$group) {
return $out;
}
$inlines = array();
foreach ($group as $xaction) {
switch ($xaction->getTransactionType()) {
case DifferentialTransaction::TYPE_INLINE:
$inlines[] = $xaction;
break;
default:
throw new Exception("Unknown grouped transaction type!");
}
}
if ($inlines) {
$inline_view = new PhabricatorInlineSummaryView();
$changesets = $this->getChangesets();
$changesets = mpull($changesets, null, 'getID');
// Group the changesets by file and reorder them by display order.
$inline_groups = array();
foreach ($inlines as $inline) {
$inline_groups[$inline->getComment()->getChangesetID()][] = $inline;
}
$changsets = msort($changesets, 'getFilename');
$inline_groups = array_select_keys(
$inline_groups,
array_keys($changesets));
foreach ($inline_groups as $changeset_id => $group) {
// Sort the group of inlines by line number.
$by_line = array();
foreach ($group as $inline) {
$by_line[] = array(
'line' => ((int)$inline->getComment()->getLineNumber() << 16) +
((int)$inline->getComment()->getLineLength()),
'inline' => $inline,
);
}
$by_line = isort($by_line, 'line');
$group = ipull($by_line, 'inline');
$changeset = $changesets[$changeset_id];
$items = array();
foreach ($group as $inline) {
$comment = $inline->getComment();
$item = array(
'id' => $comment->getID(),
'line' => $comment->getLineNumber(),
'length' => $comment->getLineLength(),
'content' => parent::renderTransactionContent($inline),
);
$changeset_diff_id = $changeset->getDiffID();
if ($comment->getIsNewFile()) {
$visible_diff_id = $this->getRightDiff()->getID();
} else {
$visible_diff_id = $this->getLeftDiff()->getID();
}
// TODO: We still get one edge case wrong here, when we have a
// versus diff and the file didn't exist in the old version. The
// comment is visible because we show the left side of the target
// diff when there's no corresponding file in the versus diff, but
// we incorrectly link it off-page.
$is_visible = ($changeset_diff_id == $visible_diff_id);
if (!$is_visible) {
$item['where'] = pht('(On Diff #%d)', $changeset_diff_id);
$revision_id = $this->getRevision()->getID();
$comment_id = $comment->getID();
$item['href'] =
"/D".$revision_id.
"?id=".$changeset_diff_id.
"#inline-".$comment_id;
}
$items[] = $item;
}
$inline_view->addCommentGroup(
$changeset->getFilename(),
$items);
}
$out[] = $inline_view;
}
return $out;
}
}

View file

@ -117,6 +117,14 @@ final class PhabricatorFeedStoryDifferential extends PhabricatorFeedStory {
$one_line = pht('%s reopened revision %s',
$actor_link, $revision_link);
break;
case DifferentialTransaction::TYPE_INLINE:
$one_line = pht('%s added inline comments to %s',
$actor_link, $revision_link);
break;
default:
$one_line = pht('%s edited %s',
$actor_link, $revision_link);
break;
}
return $one_line;
@ -200,6 +208,14 @@ final class PhabricatorFeedStoryDifferential extends PhabricatorFeedStory {
$one_line = pht('%s reopened revision %s %s',
$author_name, $revision_title, $revision_uri);
break;
case DifferentialTransaction::TYPE_INLINE:
$one_line = pht('%s added inline comments to %s %s',
$author_name, $revision_title, $revision_uri);
break;
default:
$one_line = pht('%s edited %s %s',
$author_name, $revision_title, $revision_uri);
break;
}
return $one_line;
@ -308,6 +324,14 @@ final class PhabricatorFeedStoryDifferential extends PhabricatorFeedStory {
$title = pht('%s reopened revision %s',
$author_name, $revision_name);
break;
case DifferentialTransaction::TYPE_INLINE:
$title = pht('%s added inline comments to %s',
$author_name, $revision_name);
break;
default:
$title = pht('%s edited revision %s',
$author_name, $revision_name);
break;
}
}
@ -319,28 +343,41 @@ final class PhabricatorFeedStoryDifferential extends PhabricatorFeedStory {
}
// Roughly render inlines into the comment.
$comment_id = $data->getValue('temporaryCommentID');
if ($comment_id) {
$inlines = id(new DifferentialInlineCommentQuery())
->withCommentIDs(array($comment_id))
$xaction_phids = $data->getValue('temporaryTransactionPHIDs');
if ($xaction_phids) {
$inlines = id(new DifferentialTransactionQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withPHIDs($xaction_phids)
->needComments(true)
->withTransactionTypes(
array(
DifferentialTransaction::TYPE_INLINE,
))
->execute();
if ($inlines) {
$title .= "\n\n";
$title .= pht('Inline Comments');
$title .= "\n";
$changeset_ids = mpull($inlines, 'getChangesetID');
$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) {
$changeset = idx($changesets, $inline->getChangesetID());
$comment = $inline->getComment();
$changeset = idx($changesets, $comment->getChangesetID());
if (!$changeset) {
continue;
}
$filename = $changeset->getDisplayFilename();
$linenumber = $inline->getLineNumber();
$inline_text = $engine->markupText($inline->getContent());
$linenumber = $comment->getLineNumber();
$inline_text = $engine->markupText($comment->getContent());
$inline_text = rtrim($inline_text);
$title .= "{$filename}:{$linenumber} {$inline_text}\n";

View file

@ -1,8 +1,5 @@
<?php
/**
* @group pholio
*/
final class PholioTransaction extends PhabricatorApplicationTransaction {
public function getApplicationName() {

View file

@ -16,7 +16,7 @@ final class PholioTransactionView
}
if (($v->getDateCreated() - $u->getDateCreated()) > 60) {
// Don't group if transactions happend more than 60s apart.
// Don't group if transactions happened more than 60s apart.
return false;
}

View file

@ -24,7 +24,7 @@ final class ReleephDiffChurnFieldSpecification
$diff_rev = $this->getReleephRequest()->loadDifferentialRevision();
$comments = id(new DifferentialCommentQuery())
->withRevisionIDs(array($diff_rev->getID()))
->withRevisionPHIDs(array($diff_rev->getPHID()))
->execute();
$counts = array();