Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/differential/editor/comment/DifferentialCommentEditor.php b/src/applications/differential/editor/comment/DifferentialCommentEditor.php
index 38826563f3..8f741d577a 100755
--- a/src/applications/differential/editor/comment/DifferentialCommentEditor.php
+++ b/src/applications/differential/editor/comment/DifferentialCommentEditor.php
@@ -1,332 +1,317 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class DifferentialCommentEditor {
protected $revision;
protected $actorPHID;
protected $action;
protected $attachInlineComments;
protected $message;
protected $addCC;
protected $changedByCommit;
protected $addedReviewers = array();
public function __construct(
DifferentialRevision $revision,
$actor_phid,
$action) {
$this->revision = $revision;
$this->actorPHID = $actor_phid;
$this->action = $action;
}
public function setMessage($message) {
$this->message = $message;
return $this;
}
public function setAttachInlineComments($attach) {
$this->attachInlineComments = $attach;
return $this;
}
public function setAddCC($add) {
$this->addCC = $add;
return $this;
}
public function setChangedByCommit($changed_by_commit) {
$this->changedByCommit = $changed_by_commit;
return $this;
}
public function getChangedByCommit() {
return $this->changedByCommit;
}
public function setAddedReviewers($added_reviewers) {
$this->addedReviewers = $added_reviewers;
return $this;
}
public function getAddedReviewers() {
return $this->addedReviewers;
}
public function save() {
$revision = $this->revision;
$action = $this->action;
$actor_phid = $this->actorPHID;
$actor_is_author = ($actor_phid == $revision->getAuthorPHID());
$revision_status = $revision->getStatus();
$revision->loadRelationships();
$reviewer_phids = $revision->getReviewers();
if ($reviewer_phids) {
$reviewer_phids = array_combine($reviewer_phids, $reviewer_phids);
}
switch ($action) {
case DifferentialAction::ACTION_COMMENT:
break;
case DifferentialAction::ACTION_RESIGN:
if ($actor_is_author) {
throw new Exception('You can not resign from your own revision!');
}
if (isset($reviewer_phids[$actor_phid])) {
DifferentialRevisionEditor::alterReviewers(
$revision,
$reviewer_phids,
$rem = array($actor_phid),
$add = array(),
$actor_phid);
}
break;
case DifferentialAction::ACTION_ABANDON:
if (!$actor_is_author) {
throw new Exception('You can only abandon your revisions.');
}
if ($revision_status == DifferentialRevisionStatus::COMMITTED) {
throw new Exception('You can not abandon a committed revision.');
}
if ($revision_status == DifferentialRevisionStatus::ABANDONED) {
$action = DifferentialAction::ACTION_COMMENT;
break;
}
$revision
->setStatus(DifferentialRevisionStatus::ABANDONED)
->save();
break;
case DifferentialAction::ACTION_ACCEPT:
if ($actor_is_author) {
throw new Exception('You can not accept your own revision.');
}
if (($revision_status != DifferentialRevisionStatus::NEEDS_REVIEW) &&
($revision_status != DifferentialRevisionStatus::NEEDS_REVISION)) {
$action = DifferentialAction::ACTION_COMMENT;
break;
}
$revision
->setStatus(DifferentialRevisionStatus::ACCEPTED)
->save();
if (!isset($reviewer_phids[$actor_phid])) {
DifferentialRevisionEditor::alterReviewers(
$revision,
$reviewer_phids,
$rem = array(),
$add = array($actor_phid),
$actor_phid);
}
break;
case DifferentialAction::ACTION_REQUEST:
if (!$actor_is_author) {
throw new Exception('You must own a revision to request review.');
}
if (($revision_status != DifferentialRevisionStatus::NEEDS_REVISION) &&
($revision_status != DifferentialRevisionStatus::ACCEPTED)) {
$action = DifferentialAction::ACTION_COMMENT;
break;
}
$revision
->setStatus(DifferentialRevisionStatus::NEEDS_REVIEW)
->save();
break;
case DifferentialAction::ACTION_REJECT:
if ($actor_is_author) {
throw new Exception(
'You can not request changes to your own revision.');
}
if (($revision_status != DifferentialRevisionStatus::NEEDS_REVIEW) &&
($revision_status != DifferentialRevisionStatus::ACCEPTED)) {
$action = DifferentialAction::ACTION_COMMENT;
break;
}
if (!isset($reviewer_phids[$actor_phid])) {
DifferentialRevisionEditor::alterReviewers(
$revision,
$reviewer_phids,
$rem = array(),
$add = array($actor_phid),
$actor_phid);
}
$revision
->setStatus(DifferentialRevisionStatus::NEEDS_REVISION)
->save();
break;
case DifferentialAction::ACTION_RECLAIM:
if (!$actor_is_author) {
throw new Exception('You can not reclaim a revision you do not own.');
}
if ($revision_status != DifferentialRevisionStatus::ABANDONED) {
$action = DifferentialAction::ACTION_COMMENT;
break;
}
$revision
->setStatus(DifferentialRevisionStatus::NEEDS_REVIEW)
->save();
break;
case DifferentialAction::ACTION_COMMIT:
// This is handled externally. (TODO)
break;
case DifferentialAction::ACTION_ADDREVIEWERS:
$added_reviewers = $this->getAddedReviewers();
foreach ($added_reviewers as $k => $user_phid) {
if ($user_phid == $revision->getAuthorPHID()) {
unset($added_reviewers[$k]);
}
if (!empty($reviewer_phids[$user_phid])) {
unset($added_reviewers[$k]);
}
}
$added_reviewers = array_unique($added_reviewers);
if ($added_reviewers) {
DifferentialRevisionEditor::alterReviewers(
$revision,
$reviewer_phids,
$rem = array(),
$add = $added_reviewers,
$actor_phid);
$handles = id(new PhabricatorObjectHandleData($added_reviewers))
->loadHandles();
$usernames = mpull($handles, 'getName');
$this->message =
'Added reviewers: '.implode(', ', $usernames)."\n\n".
$this->message;
} else {
$action = DifferentialAction::ACTION_COMMENT;
}
break;
default:
throw new Exception('Unsupported action.');
}
- // Reload relationships to pick up any reviewer changes.
+ if ($this->addCC) {
+ DifferentialRevisionEditor::addCC(
+ $revision,
+ $this->actorPHID,
+ $this->actorPHID);
+ }
+
+ // Reload relationships to pick up any reviewer/CC changes.
$revision->loadRelationships();
$inline_comments = array();
if ($this->attachInlineComments) {
$inline_comments = id(new DifferentialInlineComment())->loadAllWhere(
'authorPHID = %s AND revisionID = %d AND commentID IS NULL',
$this->actorPHID,
$revision->getID());
}
$comment = id(new DifferentialComment())
->setAuthorPHID($this->actorPHID)
->setRevisionID($revision->getID())
->setAction($action)
->setContent((string)$this->message)
->save();
-// $diff = id(new Diff())->loadActiveWithRevision($revision);
-// $changesets = id(new DifferentialChangeset())->loadAllWithDiff($diff);
-
+ $changesets = array();
if ($inline_comments) {
-/*
- // We may have feedback on non-current changesets. Rather than orphaning
- // it, just submit it. This is non-ideal but not horrible.
- $inline_changeset_ids = array_pull($inline_comments, 'getChangesetID');
- $load = array();
- foreach ($inline_changeset_ids as $id) {
- if (empty($changesets[$id])) {
- $load[] = $id;
- }
+ $load_ids = mpull($inline_comments, 'getChangesetID');
+ if ($load_ids) {
+ $load_ids = array_unique($load_ids);
+ $changesets = id(new DifferentialChangeset())->loadAllWhere(
+ 'id in (%Ld)',
+ $load_ids);
}
- if ($load) {
- $changesets += id(new DifferentialChangeset())->loadAllWithIDs($load);
- }
-*/
foreach ($inline_comments as $inline) {
$inline->setCommentID($comment->getID());
$inline->save();
}
}
$phids = array($this->actorPHID);
$handles = id(new PhabricatorObjectHandleData($phids))
->loadHandles();
$actor_handle = $handles[$this->actorPHID];
id(new DifferentialCommentMail(
$revision,
$actor_handle,
$comment,
- /* $changesets TODO */ array(),
- /* $inline_comments TODO */ array()))
+ $changesets,
+ $inline_comments))
->setToPHIDs(
array_merge(
$revision->getReviewers(),
array($revision->getAuthorPHID())))
->setCCPHIDs($revision->getCCPHIDs())
->setChangedByCommit($this->getChangedByCommit())
->send();
-/*
-
- tODO
-
- if ($this->addCC) {
- require_module_lazy('site/tools/differential/lib/editor/revision');
- DifferentialRevisionEditor::addCCFBID(
- $revision,
- $this->actorPHID,
- $this->actorPHID);
- }
-*/
-
/*
TODO
$event = array(
'revision_id' => $revision->getID(),
'fbid' => $revision->getFBID(),
'feedback_id' => $feedback->getID(),
'action' => $feedback->getAction(),
'actor' => $this->actorPHID,
);
id(new ToolsTimelineEvent('difx', fb_json_encode($event)))->record();
*/
return $comment;
}
}
diff --git a/src/applications/differential/editor/comment/__init__.php b/src/applications/differential/editor/comment/__init__.php
index 11fbcdc6ba..2412349c94 100644
--- a/src/applications/differential/editor/comment/__init__.php
+++ b/src/applications/differential/editor/comment/__init__.php
@@ -1,20 +1,21 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/differential/constants/action');
phutil_require_module('phabricator', 'applications/differential/constants/revisionstatus');
phutil_require_module('phabricator', 'applications/differential/editor/revision');
phutil_require_module('phabricator', 'applications/differential/mail/comment');
+phutil_require_module('phabricator', 'applications/differential/storage/changeset');
phutil_require_module('phabricator', 'applications/differential/storage/comment');
phutil_require_module('phabricator', 'applications/differential/storage/inlinecomment');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phutil', 'utils');
phutil_require_source('DifferentialCommentEditor.php');
diff --git a/src/applications/differential/editor/revision/DifferentialRevisionEditor.php b/src/applications/differential/editor/revision/DifferentialRevisionEditor.php
index a68fc3ae4d..73bf1999ac 100644
--- a/src/applications/differential/editor/revision/DifferentialRevisionEditor.php
+++ b/src/applications/differential/editor/revision/DifferentialRevisionEditor.php
@@ -1,629 +1,572 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Handle major edit operations to DifferentialRevision -- adding and removing
* reviewers, diffs, and CCs. Unlike simple edits, these changes trigger
* complicated email workflows.
*/
class DifferentialRevisionEditor {
protected $revision;
protected $actorPHID;
protected $cc = null;
protected $reviewers = null;
protected $diff;
protected $comments;
protected $silentUpdate;
public function __construct(DifferentialRevision $revision, $actor_phid) {
$this->revision = $revision;
$this->actorPHID = $actor_phid;
}
public static function newRevisionFromConduitWithDiff(
array $fields,
DifferentialDiff $diff,
$user_phid) {
$revision = new DifferentialRevision();
$revision->setPHID($revision->generatePHID());
$revision->setAuthorPHID($user_phid);
$revision->setStatus(DifferentialRevisionStatus::NEEDS_REVIEW);
$editor = new DifferentialRevisionEditor($revision, $user_phid);
$editor->copyFieldsFromConduit($fields);
$editor->addDiff($diff, null);
$editor->save();
return $revision;
}
public function copyFieldsFromConduit(array $fields) {
$revision = $this->revision;
$revision->setTitle((string)$fields['title']);
$revision->setSummary((string)$fields['summary']);
$revision->setTestPlan((string)$fields['testPlan']);
$revision->setBlameRevision((string)$fields['blameRevision']);
$revision->setRevertPlan((string)$fields['revertPlan']);
$this->setReviewers($fields['reviewerPHIDs']);
$this->setCCPHIDs($fields['ccPHIDs']);
}
-
-/*
- public static function newRevisionFromRawMessageWithDiff(
- DifferentialRawMessage $message,
- Diff $diff,
- $user) {
-
- if ($message->getRevisionID()) {
- throw new Exception(
- "The provided commit message is already associated with a ".
- "Differential revision.");
- }
-
- if ($message->getReviewedByNames()) {
- throw new Exception(
- "The provided commit message contains a 'Reviewed By:' field.");
- }
-
- $revision = new DifferentialRevision();
- $revision->setPHID($revision->generatePHID());
-
- $revision->setOwnerID($user);
- $revision->setStatus(DifferentialRevisionStatus::NEEDS_REVIEW);
- $revision->attachReviewers(array());
- $revision->attachCCPHIDs(array());
-
- $editor = new DifferentialRevisionEditor($revision, $user);
-
- self::copyFields($editor, $revision, $message, $user);
-
- $editor->addDiff($diff, null);
- $editor->save();
-
- return $revision;
- }
-
-
- public static function copyFields(
- DifferentialRevisionEditor $editor,
- DifferentialRevision $revision,
- DifferentialRawMessage $message,
- $user) {
-
- $revision->setName($message->getTitle());
- $revision->setSummary($message->getSummary());
- $revision->setTestPlan($message->getTestPlan());
- $revision->setSVNBlameRevision($message->getBlameRevision());
- $revision->setRevert($message->getRevertPlan());
- $revision->setPlatformImpact($message->getPlatformImpact());
- $revision->setBugzillaID($message->getBugzillaID());
-
- $editor->setReviewers($message->getReviewerPHIDs());
- $editor->setCCPHIDs($message->getCCPHIDs());
- }
-
-*/
-
public function getRevision() {
return $this->revision;
}
public function setReviewers(array $reviewers) {
$this->reviewers = $reviewers;
return $this;
}
public function setCCPHIDs(array $cc) {
$this->cc = $cc;
return $this;
}
public function addDiff(DifferentialDiff $diff, $comments) {
if ($diff->getRevisionID() &&
$diff->getRevisionID() != $this->getRevision()->getID()) {
$diff_id = (int)$diff->getID();
$targ_id = (int)$this->getRevision()->getID();
$real_id = (int)$diff->getRevisionID();
throw new Exception(
"Can not attach diff #{$diff_id} to Revision D{$targ_id}, it is ".
"already attached to D{$real_id}.");
}
$this->diff = $diff;
$this->comments = $comments;
return $this;
}
protected function getDiff() {
return $this->diff;
}
protected function getComments() {
return $this->comments;
}
protected function getActorPHID() {
return $this->actorPHID;
}
public function isNewRevision() {
return !$this->getRevision()->getID();
}
/**
* A silent update does not trigger Herald rules or send emails. This is used
* for auto-amends at commit time.
*/
public function setSilentUpdate($silent) {
$this->silentUpdate = $silent;
return $this;
}
public function save() {
$revision = $this->getRevision();
// TODO
// $revision->openTransaction();
$is_new = $this->isNewRevision();
if ($is_new) {
// These fields aren't nullable; set them to sensible defaults if they
// haven't been configured. We're just doing this so we can generate an
// ID for the revision if we don't have one already.
$revision->setLineCount(0);
if ($revision->getStatus() === null) {
$revision->setStatus(DifferentialRevisionStatus::NEEDS_REVIEW);
}
if ($revision->getTitle() === null) {
$revision->setTitle('Untitled Revision');
}
if ($revision->getAuthorPHID() === null) {
$revision->setAuthorPHID($this->getActorPHID());
}
$revision->save();
}
$revision->loadRelationships();
if ($this->reviewers === null) {
$this->reviewers = $revision->getReviewers();
}
if ($this->cc === null) {
$this->cc = $revision->getCCPHIDs();
}
// We're going to build up three dictionaries: $add, $rem, and $stable. The
// $add dictionary has added reviewers/CCs. The $rem dictionary has
// reviewers/CCs who have been removed, and the $stable array is
// reviewers/CCs who haven't changed. We're going to send new reviewers/CCs
// a different ("welcome") email than we send stable reviewers/CCs.
$old = array(
'rev' => array_fill_keys($revision->getReviewers(), true),
'ccs' => array_fill_keys($revision->getCCPHIDs(), true),
);
$diff = $this->getDiff();
$xscript_header = null;
$xscript_uri = null;
$new = array(
'rev' => array_fill_keys($this->reviewers, true),
'ccs' => array_fill_keys($this->cc, true),
);
$rem_ccs = array();
if ($diff) {
$diff->setRevisionID($revision->getID());
$revision->setLineCount($diff->getLineCount());
// TODO!
// $revision->setRepositoryID($diff->getRepositoryID());
/*
$iface = new DifferentialRevisionHeraldable($revision);
$iface->setExplicitCCs($new['ccs']);
$iface->setExplicitReviewers($new['rev']);
$iface->setForbiddenCCs($revision->getForbiddenCCPHIDs());
$iface->setForbiddenReviewers($revision->getForbiddenReviewers());
$iface->setDiff($diff);
$xscript = HeraldEngine::loadAndApplyRules($iface);
$xscript_uri = $xscript->getURI();
$xscript_phid = $xscript->getPHID();
$xscript_header = $xscript->getXHeraldRulesHeader();
$sub = array(
'rev' => array(),
'ccs' => $iface->getCCsAddedByHerald(),
);
$rem_ccs = $iface->getCCsRemovedByHerald();
*/
// TODO!
$sub = array(
'rev' => array(),
'ccs' => array(),
);
} else {
$sub = array(
'rev' => array(),
'ccs' => array(),
);
}
// Remove any CCs which are prevented by Herald rules.
$sub['ccs'] = array_diff_key($sub['ccs'], $rem_ccs);
$new['ccs'] = array_diff_key($new['ccs'], $rem_ccs);
$add = array();
$rem = array();
$stable = array();
foreach (array('rev', 'ccs') as $key) {
$add[$key] = array();
if ($new[$key] !== null) {
$add[$key] += array_diff_key($new[$key], $old[$key]);
}
$add[$key] += array_diff_key($sub[$key], $old[$key]);
$combined = $sub[$key];
if ($new[$key] !== null) {
$combined += $new[$key];
}
$rem[$key] = array_diff_key($old[$key], $combined);
$stable[$key] = array_diff_key($old[$key], $add[$key] + $rem[$key]);
}
self::alterReviewers(
$revision,
$this->reviewers,
array_keys($rem['rev']),
array_keys($add['rev']),
$this->actorPHID);
/*
// TODO: When Herald is brought over, run through this stuff to figure
// out which adds are Herald's fault.
if ($add['ccs'] || $rem['ccs']) {
foreach (array_keys($add['ccs']) as $id) {
if (empty($new['ccs'][$id])) {
$reason_phid = 'TODO';//$xscript_phid;
} else {
$reason_phid = $this->getActorPHID();
}
}
foreach (array_keys($rem['ccs']) as $id) {
if (empty($new['ccs'][$id])) {
$reason_phid = $this->getActorPHID();
} else {
$reason_phid = 'TODO';//$xscript_phid;
}
}
}
*/
self::alterCCs(
$revision,
$this->cc,
array_keys($rem['ccs']),
array_keys($add['ccs']),
$this->actorPHID);
// Add the author to the relevant set of users so they get a copy of the
// email.
if (!$this->silentUpdate) {
if ($is_new) {
$add['rev'][$this->getActorPHID()] = true;
} else {
$stable['rev'][$this->getActorPHID()] = true;
}
}
$mail = array();
$phids = array($this->getActorPHID());
$handles = id(new PhabricatorObjectHandleData($phids))
->loadHandles();
$actor_handle = $handles[$this->getActorPHID()];
$changesets = null;
$comment = null;
if ($diff) {
$changesets = $diff->loadChangesets();
// TODO: This should probably be in DifferentialFeedbackEditor?
if (!$is_new) {
$comment = $this->createComment();
}
if ($comment) {
$mail[] = id(new DifferentialNewDiffMail(
$revision,
$actor_handle,
$changesets))
->setIsFirstMailAboutRevision($is_new)
->setIsFirstMailToRecipients($is_new)
->setComments($this->getComments())
->setToPHIDs(array_keys($stable['rev']))
->setCCPHIDs(array_keys($stable['ccs']));
}
// Save the changes we made above.
$diff->setDescription(substr($this->getComments(), 0, 80));
$diff->save();
// An updated diff should require review, as long as it's not committed
// or accepted. The "accepted" status is "sticky" to encourage courtesy
// re-diffs after someone accepts with minor changes/suggestions.
$status = $revision->getStatus();
if ($status != DifferentialRevisionStatus::COMMITTED &&
$status != DifferentialRevisionStatus::ACCEPTED) {
$revision->setStatus(DifferentialRevisionStatus::NEEDS_REVIEW);
}
} else {
$diff = $revision->loadActiveDiff();
if ($diff) {
$changesets = $diff->loadChangesets();
} else {
$changesets = array();
}
}
$revision->save();
// TODO
// $revision->saveTransaction();
$event = array(
'revision_id' => $revision->getID(),
'PHID' => $revision->getPHID(),
'action' => $is_new ? 'create' : 'update',
'actor' => $this->getActorPHID(),
);
// TODO: When timelines get implemented, move indexing to them.
PhabricatorSearchDifferentialIndexer::indexRevision($revision);
// TODO
// id(new ToolsTimelineEvent('difx', fb_json_encode($event)))->record();
if ($this->silentUpdate) {
return;
}
$revision->loadRelationships();
if ($add['rev']) {
$message = id(new DifferentialNewDiffMail(
$revision,
$actor_handle,
$changesets))
->setIsFirstMailAboutRevision($is_new)
->setIsFirstMailToRecipients(true)
->setToPHIDs(array_keys($add['rev']));
if ($is_new) {
// The first time we send an email about a revision, put the CCs in
// the "CC:" field of the same "Review Requested" email that reviewers
// get, so you don't get two initial emails if you're on a list that
// is CC'd.
$message->setCCPHIDs(array_keys($add['ccs']));
}
$mail[] = $message;
}
// If you were added as a reviewer and a CC, just give you the reviewer
// email. We could go to greater lengths to prevent this, but there's
// bunch of stuff with list subscriptions anyway. You can still get two
// emails, but only if a revision is updated and you are added as a reviewer
// at the same time a list you are on is added as a CC, which is rare and
// reasonable.
$add['ccs'] = array_diff_key($add['ccs'], $add['rev']);
if (!$is_new && $add['ccs']) {
$mail[] = id(new DifferentialCCWelcomeMail(
$revision,
$actor_handle,
$changesets))
->setIsFirstMailToRecipients(true)
->setToPHIDs(array_keys($add['ccs']));
}
foreach ($mail as $message) {
// TODO
// $message->setHeraldTranscriptURI($xscript_uri);
// $message->setXHeraldRulesHeader($xscript_header);
$message->send();
}
}
public static function addCC(
DifferentialRevision $revision,
$phid,
$reason) {
return self::alterCCs(
$revision,
$revision->getCCPHIDs(),
$rem = array(),
$add = array($phid),
$reason);
}
public static function removeCC(
DifferentialRevision $revision,
$phid,
$reason) {
return self::alterCCs(
$revision,
$revision->getCCPHIDs(),
$rem = array($phid),
$add = array(),
$reason);
}
protected static function alterCCs(
DifferentialRevision $revision,
array $stable_phids,
array $rem_phids,
array $add_phids,
$reason_phid) {
return self::alterRelationships(
$revision,
$stable_phids,
$rem_phids,
$add_phids,
$reason_phid,
DifferentialRevision::RELATION_SUBSCRIBED);
}
public static function alterReviewers(
DifferentialRevision $revision,
array $stable_phids,
array $rem_phids,
array $add_phids,
$reason_phid) {
return self::alterRelationships(
$revision,
$stable_phids,
$rem_phids,
$add_phids,
$reason_phid,
DifferentialRevision::RELATION_REVIEWER);
}
private static function alterRelationships(
DifferentialRevision $revision,
array $stable_phids,
array $rem_phids,
array $add_phids,
$reason_phid,
$relation_type) {
$rem_map = array_fill_keys($rem_phids, true);
$add_map = array_fill_keys($add_phids, true);
$seq_map = array_values($stable_phids);
$seq_map = array_flip($seq_map);
foreach ($rem_map as $phid => $ignored) {
if (!isset($seq_map[$phid])) {
$seq_map[$phid] = count($seq_map);
}
}
foreach ($add_map as $phid => $ignored) {
if (!isset($seq_map[$phid])) {
$seq_map[$phid] = count($seq_map);
}
}
$raw = $revision->getRawRelations($relation_type);
$raw = ipull($raw, null, 'objectPHID');
$sequence = count($seq_map);
foreach ($raw as $phid => $ignored) {
if (isset($seq_map[$phid])) {
$raw[$phid]['sequence'] = $seq_map[$phid];
} else {
$raw[$phid]['sequence'] = $sequence++;
}
}
$raw = isort($raw, 'sequence');
foreach ($raw as $phid => $ignored) {
if (isset($rem_map[$phid])) {
unset($raw[$phid]);
}
}
foreach ($add_phids as $add) {
$raw[$add] = array(
'objectPHID' => $add,
'sequence' => idx($seq_map, $add, $sequence++),
'reasonPHID' => $reason_phid,
);
}
$conn_w = $revision->establishConnection('w');
$sql = array();
foreach ($raw as $relation) {
$sql[] = qsprintf(
$conn_w,
'(%d, %s, %s, %d, %s)',
$revision->getID(),
$relation_type,
$relation['objectPHID'],
$relation['sequence'],
$relation['reasonPHID']);
}
$conn_w->openTransaction();
queryfx(
$conn_w,
'DELETE FROM %T WHERE revisionID = %d AND relation = %s',
DifferentialRevision::RELATIONSHIP_TABLE,
$revision->getID(),
$relation_type);
if ($sql) {
queryfx(
$conn_w,
'INSERT INTO %T
(revisionID, relation, objectPHID, sequence, reasonPHID)
VALUES %Q',
DifferentialRevision::RELATIONSHIP_TABLE,
implode(', ', $sql));
}
$conn_w->saveTransaction();
}
private function createComment() {
$revision_id = $this->revision->getID();
$comment = id(new DifferentialComment())
->setAuthorPHID($this->getActorPHID())
->setRevisionID($revision_id)
->setContent($this->getComments())
->setAction('update');
$comment->save();
return $comment;
}
}
diff --git a/src/applications/differential/mail/comment/DifferentialCommentMail.php b/src/applications/differential/mail/comment/DifferentialCommentMail.php
index a206a7aab4..6df4468719 100755
--- a/src/applications/differential/mail/comment/DifferentialCommentMail.php
+++ b/src/applications/differential/mail/comment/DifferentialCommentMail.php
@@ -1,119 +1,125 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class DifferentialCommentMail extends DifferentialMail {
protected $changedByCommit;
public function setChangedByCommit($changed_by_commit) {
$this->changedByCommit = $changed_by_commit;
return $this;
}
public function getChangedByCommit() {
return $this->changedByCommit;
}
public function __construct(
DifferentialRevision $revision,
PhabricatorObjectHandle $actor,
DifferentialComment $comment,
array $changesets,
array $inline_comments) {
$this->setRevision($revision);
$this->setActorHandle($actor);
$this->setComment($comment);
$this->setChangesets($changesets);
$this->setInlineComments($inline_comments);
}
protected function renderSubject() {
$revision = $this->getRevision();
$verb = $this->getVerb();
return ucwords($verb).': '.$revision->getTitle();
}
protected function getVerb() {
$comment = $this->getComment();
$action = $comment->getAction();
$verb = DifferentialAction::getActionPastTenseVerb($action);
return $verb;
}
protected function renderBody() {
$comment = $this->getComment();
$actor = $this->getActorName();
$name = $this->getRevision()->getTitle();
$verb = $this->getVerb();
$body = array();
$body[] = "{$actor} has {$verb} the revision \"{$name}\".";
$body[] = null;
$content = $comment->getContent();
if (strlen($content)) {
$body[] = $this->formatText($content);
$body[] = null;
}
if ($this->getChangedByCommit()) {
$body[] = 'CHANGED PRIOR TO COMMIT';
$body[] = ' This revision was updated prior to commit.';
$body[] = null;
}
$inlines = $this->getInlineComments();
if ($inlines) {
$body[] = 'INLINE COMMENTS';
$changesets = $this->getChangesets();
foreach ($inlines as $inline) {
$changeset = $changesets[$inline->getChangesetID()];
if (!$changeset) {
throw new Exception('Changeset missing!');
}
$file = $changeset->getFilename();
- $line = $inline->renderLineRange();
+ $start = $inline->getLineNumber();
+ $len = $inline->getLineLength();
+ if ($len) {
+ $range = $start.'-'.($start + $len);
+ } else {
+ $range = $start;
+ }
$content = $inline->getContent();
- $body[] = $this->formatText("{$file}:{$line} {$content}");
+ $body[] = $this->formatText("{$file}:{$range} {$content}");
}
$body[] = null;
}
$body[] = $this->renderRevisionDetailLink();
$revision = $this->getRevision();
if ($revision->getStatus() == DifferentialRevisionStatus::COMMITTED) {
/*
TODO
$rev_ref = $revision->getRevisionRef();
if ($rev_ref) {
$body[] = " Detail URL: ".$rev_ref->getDetailURL();
}
*/
}
$body[] = null;
return implode("\n", $body);
}
}
diff --git a/src/applications/differential/view/revisioncomment/DifferentialRevisionCommentView.php b/src/applications/differential/view/revisioncomment/DifferentialRevisionCommentView.php
index 58a4460065..1aeebbaac8 100644
--- a/src/applications/differential/view/revisioncomment/DifferentialRevisionCommentView.php
+++ b/src/applications/differential/view/revisioncomment/DifferentialRevisionCommentView.php
@@ -1,191 +1,196 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class DifferentialRevisionCommentView extends AphrontView {
private $comment;
private $handles;
private $markupEngine;
private $preview;
private $inlines;
private $changesets;
public function setComment($comment) {
$this->comment = $comment;
return $this;
}
public function setHandles(array $handles) {
$this->handles = $handles;
return $this;
}
public function setMarkupEngine($markup_engine) {
$this->markupEngine = $markup_engine;
return $this;
}
public function setPreview($preview) {
$this->preview = $preview;
return $this;
}
public function setInlineComments(array $inline_comments) {
$this->inlines = $inline_comments;
return $this;
}
public function setChangesets(array $changesets) {
// Ship these in sorted by getSortKey() and keyed by ID... or else!
$this->changesets = $changesets;
return $this;
}
public function render() {
require_celerity_resource('phabricator-remarkup-css');
require_celerity_resource('differential-revision-comment-css');
$comment = $this->comment;
$action = $comment->getAction();
$action_class = 'differential-comment-action-'.phutil_escape_html($action);
if ($this->preview) {
$date = 'COMMENT PREVIEW';
} else {
$date = date('F jS, Y g:i:s A', $comment->getDateCreated());
}
$author = $this->handles[$comment->getAuthorPHID()];
$author_link = $author->renderLink();
$verb = DifferentialAction::getActionPastTenseVerb($comment->getAction());
$verb = phutil_escape_html($verb);
$content = $comment->getContent();
if (strlen(rtrim($content))) {
$title = "{$author_link} {$verb} this revision:";
$cache = $comment->getCache();
if (strlen($cache)) {
$content = $cache;
} else {
$content = $this->markupEngine->markupText($content);
if ($comment->getID()) {
$comment->setCache($content);
$comment->save();
}
}
$content =
'<div class="phabricator-remarkup">'.
$content.
'</div>';
} else {
$title = null;
$content =
'<div class="differential-comment-nocontent">'.
"<p>{$author_link} {$verb} this revision.</p>".
'</div>';
}
if ($this->inlines) {
$inline_render = array();
$inlines = $this->inlines;
$changesets = $this->changesets;
$inlines_by_changeset = mgroup($inlines, 'getChangesetID');
$inlines_by_changeset = array_select_keys(
$inlines_by_changeset,
array_keys($this->changesets));
$inline_render[] = '<table class="differential-inline-summary">';
foreach ($inlines_by_changeset as $changeset_id => $inlines) {
$changeset = $changesets[$changeset_id];
$inlines = msort($inlines, 'getLineNumber');
$inline_render[] =
'<tr>'.
'<th colspan="2">'.
$changeset->getFileName().
'</th>'.
'</tr>';
foreach ($inlines as $inline) {
if (!$inline->getLineLength()) {
$lines = $inline->getLineNumber();
} else {
$lines = $inline->getLineNumber()."\xE2\x80\x93".
($inline->getLineNumber() + $inline->getLineLength());
}
$lines = phutil_render_tag(
'a',
array(
'href' => '#inline-'.$inline->getID(),
'class' => 'num',
),
$lines);
- $content = $inline->getCache();
- if (!strlen($content)) {
- $content = $this->markupEngine->markupText($content);
- if ($inline->getID()) {
- $inline->setCache($content);
- $inline->save();
+ $inline_content = $inline->getContent();
+ if (strlen($inline_content)) {
+ $inline_cache = $inline->getCache();
+ if ($inline_cache) {
+ $inline_content = $inline_cache;
+ } else {
+ $inline_content = $this->markupEngine->markupText($content);
+ if ($inline->getID()) {
+ $inline->setCache($inline_content);
+ $inline->save();
+ }
}
}
$inline_render[] =
'<tr>'.
'<td class="inline-line-number">'.$lines.'</td>'.
- '<td>'.$content.'</td>'.
+ '<td>'.$inline_content.'</td>'.
'</tr>';
}
}
$inline_render[] = '</table>';
$inline_render = implode("\n", $inline_render);
$inline_render =
'<div class="differential-inline-summary-section">'.
'Inline Comments'.
'</div>'.
$inline_render;
} else {
$inline_render = null;
}
$background = null;
$uri = $author->getImageURI();
if ($uri) {
$background = "background-image: url('{$uri}');";
}
return
'<div class="differential-comment '.$action_class.'">'.
'<div class="differential-comment-head">'.
'<div class="differential-comment-date">'.$date.'</div>'.
'<div class="differential-comment-title">'.$title.'</div>'.
'</div>'.
'<div class="differential-comment-body" style="'.$background.'">'.
'<div class="differential-comment-content">'.
'<div class="differential-comment-core">'.
$content.
'</div>'.
$inline_render.
'</div>'.
'</div>'.
'</div>';
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jun 10, 5:04 PM (1 d, 12 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
140572
Default Alt Text
(40 KB)

Event Timeline