Page MenuHomePhorge

No OneTemporary

diff --git a/src/applications/differential/controller/DifferentialInlineCommentEditController.php b/src/applications/differential/controller/DifferentialInlineCommentEditController.php
index 91445f3032..f1fd4e206f 100644
--- a/src/applications/differential/controller/DifferentialInlineCommentEditController.php
+++ b/src/applications/differential/controller/DifferentialInlineCommentEditController.php
@@ -1,211 +1,183 @@
<?php
final class DifferentialInlineCommentEditController
extends PhabricatorInlineCommentController {
protected function newInlineCommentQuery() {
return new DifferentialDiffInlineCommentQuery();
}
+ protected function newContainerObject() {
+ return $this->loadRevision();
+ }
+
private function getRevisionID() {
return $this->getRequest()->getURIData('id');
}
private function loadRevision() {
$viewer = $this->getViewer();
$revision_id = $this->getRevisionID();
$revision = id(new DifferentialRevisionQuery())
->setViewer($viewer)
->withIDs(array($revision_id))
->executeOne();
if (!$revision) {
throw new Exception(pht('Invalid revision ID "%s".', $revision_id));
}
return $revision;
}
protected function createComment() {
// Verify revision and changeset correspond to actual objects, and are
// connected to one another.
$changeset_id = $this->getChangesetID();
$viewer = $this->getViewer();
$revision = $this->loadRevision();
$changeset = id(new DifferentialChangesetQuery())
->setViewer($viewer)
->withIDs(array($changeset_id))
->executeOne();
if (!$changeset) {
throw new Exception(
pht(
'Invalid changeset ID "%s"!',
$changeset_id));
}
$diff = $changeset->getDiff();
if ($diff->getRevisionID() != $revision->getID()) {
throw new Exception(
pht(
'Changeset ID "%s" is part of diff ID "%s", but that diff '.
'is attached to revision "%s", not revision "%s".',
$changeset_id,
$diff->getID(),
$diff->getRevisionID(),
$revision->getID()));
}
return id(new DifferentialInlineComment())
->setRevision($revision)
->setChangesetID($changeset_id);
}
protected function loadCommentForDone($id) {
$viewer = $this->getViewer();
$inline = $this->loadCommentByID($id);
if (!$inline) {
throw new Exception(pht('Unable to load inline "%d".', $id));
}
$changeset = id(new DifferentialChangesetQuery())
->setViewer($viewer)
->withIDs(array($inline->getChangesetID()))
->executeOne();
if (!$changeset) {
throw new Exception(pht('Unable to load changeset.'));
}
$diff = id(new DifferentialDiffQuery())
->setViewer($viewer)
->withIDs(array($changeset->getDiffID()))
->executeOne();
if (!$diff) {
throw new Exception(pht('Unable to load diff.'));
}
$revision = id(new DifferentialRevisionQuery())
->setViewer($viewer)
->withIDs(array($diff->getRevisionID()))
->executeOne();
if (!$revision) {
throw new Exception(pht('Unable to load revision.'));
}
$viewer_phid = $viewer->getPHID();
$is_owner = ($viewer_phid == $revision->getAuthorPHID());
$is_author = ($viewer_phid == $inline->getAuthorPHID());
$is_draft = ($inline->isDraft());
if ($is_owner) {
// You own the revision, so you can mark the comment as "Done".
} else if ($is_author && $is_draft) {
// You made this comment and it's still a draft, so you can mark
// it as "Done".
} else {
throw new Exception(
pht(
'You are not the revision owner, and this is not a draft comment '.
'you authored.'));
}
return $inline;
}
protected function canEditInlineComment(
PhabricatorUser $viewer,
DifferentialInlineComment $inline) {
// Only the author may edit a comment.
if ($inline->getAuthorPHID() != $viewer->getPHID()) {
return false;
}
// Saved comments may not be edited, for now, although the schema now
// supports it.
if (!$inline->isDraft()) {
return false;
}
// Inline must be attached to the active revision.
if ($inline->getRevisionID() != $this->getRevisionID()) {
return false;
}
return true;
}
- protected function deleteComment(PhabricatorInlineComment $inline) {
- $inline->openTransaction();
- $inline->setIsDeleted(1)->save();
- $this->syncDraft();
- $inline->saveTransaction();
- }
-
- protected function undeleteComment(
- PhabricatorInlineComment $inline) {
- $inline->openTransaction();
- $inline->setIsDeleted(0)->save();
- $this->syncDraft();
- $inline->saveTransaction();
- }
-
- protected function saveComment(PhabricatorInlineComment $inline) {
- $inline->openTransaction();
- $inline->save();
- $this->syncDraft();
- $inline->saveTransaction();
- }
-
protected function loadObjectOwnerPHID(
PhabricatorInlineComment $inline) {
return $this->loadRevision()->getAuthorPHID();
}
protected function hideComments(array $ids) {
$viewer = $this->getViewer();
$table = new DifferentialHiddenComment();
$conn_w = $table->establishConnection('w');
$sql = array();
foreach ($ids as $id) {
$sql[] = qsprintf(
$conn_w,
'(%s, %d)',
$viewer->getPHID(),
$id);
}
queryfx(
$conn_w,
'INSERT IGNORE INTO %T (userPHID, commentID) VALUES %LQ',
$table->getTableName(),
$sql);
}
protected function showComments(array $ids) {
$viewer = $this->getViewer();
$table = new DifferentialHiddenComment();
$conn_w = $table->establishConnection('w');
queryfx(
$conn_w,
'DELETE FROM %T WHERE userPHID = %s AND commentID IN (%Ld)',
$table->getTableName(),
$viewer->getPHID(),
$ids);
}
- private function syncDraft() {
- $viewer = $this->getViewer();
- $revision = $this->loadRevision();
-
- $revision->newDraftEngine()
- ->setObject($revision)
- ->setViewer($viewer)
- ->synchronize();
- }
-
}
diff --git a/src/applications/differential/engine/DifferentialRevisionDraftEngine.php b/src/applications/differential/engine/DifferentialRevisionDraftEngine.php
index 249569e896..22b103c525 100644
--- a/src/applications/differential/engine/DifferentialRevisionDraftEngine.php
+++ b/src/applications/differential/engine/DifferentialRevisionDraftEngine.php
@@ -1,19 +1,20 @@
<?php
final class DifferentialRevisionDraftEngine
extends PhabricatorDraftEngine {
protected function hasCustomDraftContent() {
$viewer = $this->getViewer();
$revision = $this->getObject();
$inlines = id(new DifferentialDiffInlineCommentQuery())
->setViewer($viewer)
->withRevisionPHIDs(array($revision->getPHID()))
->withPublishableComments(true)
+ ->setLimit(1)
->execute();
return (bool)$inlines;
}
}
diff --git a/src/applications/diffusion/controller/DiffusionInlineCommentController.php b/src/applications/diffusion/controller/DiffusionInlineCommentController.php
index 8d6b733ce0..b8ef547827 100644
--- a/src/applications/diffusion/controller/DiffusionInlineCommentController.php
+++ b/src/applications/diffusion/controller/DiffusionInlineCommentController.php
@@ -1,125 +1,116 @@
<?php
final class DiffusionInlineCommentController
extends PhabricatorInlineCommentController {
protected function newInlineCommentQuery() {
return new DiffusionDiffInlineCommentQuery();
}
+ protected function newContainerObject() {
+ return $this->loadCommit();
+ }
+
private function getCommitPHID() {
return $this->getRequest()->getURIData('phid');
}
private function loadCommit() {
$viewer = $this->getViewer();
$commit_phid = $this->getCommitPHID();
$commit = id(new DiffusionCommitQuery())
->setViewer($viewer)
->withPHIDs(array($commit_phid))
->executeOne();
if (!$commit) {
throw new Exception(pht('Invalid commit PHID "%s"!', $commit_phid));
}
return $commit;
}
protected function createComment() {
$commit = $this->loadCommit();
// TODO: Write a real PathQuery object?
$path_id = $this->getChangesetID();
$path = queryfx_one(
id(new PhabricatorRepository())->establishConnection('r'),
'SELECT path FROM %T WHERE id = %d',
PhabricatorRepository::TABLE_PATH,
$path_id);
if (!$path) {
throw new Exception(pht('Invalid path ID!'));
}
return id(new PhabricatorAuditInlineComment())
->setCommitPHID($commit->getPHID())
->setPathID($path_id);
}
protected function loadCommentForDone($id) {
$viewer = $this->getViewer();
$inline = $this->loadCommentByID($id);
if (!$inline) {
throw new Exception(pht('Failed to load comment "%d".', $id));
}
$commit = id(new DiffusionCommitQuery())
->setViewer($viewer)
->withPHIDs(array($inline->getCommitPHID()))
->executeOne();
if (!$commit) {
throw new Exception(pht('Failed to load commit.'));
}
$owner_phid = $commit->getAuthorPHID();
$viewer_phid = $viewer->getPHID();
$viewer_is_owner = ($owner_phid && ($owner_phid == $viewer_phid));
$viewer_is_author = ($viewer_phid == $inline->getAuthorPHID());
$is_draft = $inline->isDraft();
if ($viewer_is_owner) {
// You can mark inlines on your own commits as "Done".
} else if ($viewer_is_author && $is_draft) {
// You can mark your own unsubmitted inlines as "Done".
} else {
throw new Exception(
pht(
'You can not mark this comment as complete: you did not author '.
'the commit and the comment is not a draft you wrote.'));
}
return $inline;
}
protected function canEditInlineComment(
PhabricatorUser $viewer,
PhabricatorAuditInlineComment $inline) {
// Only the author may edit a comment.
if ($inline->getAuthorPHID() != $viewer->getPHID()) {
return false;
}
// Saved comments may not be edited.
if ($inline->getTransactionPHID()) {
return false;
}
// Inline must be attached to the active revision.
if ($inline->getCommitPHID() != $this->getCommitPHID()) {
return false;
}
return true;
}
- protected function deleteComment(PhabricatorInlineComment $inline) {
- $inline->setIsDeleted(1)->save();
- }
-
- protected function undeleteComment(
- PhabricatorInlineComment $inline) {
- $inline->setIsDeleted(0)->save();
- }
-
- protected function saveComment(PhabricatorInlineComment $inline) {
- return $inline->save();
- }
-
protected function loadObjectOwnerPHID(
PhabricatorInlineComment $inline) {
return $this->loadCommit()->getAuthorPHID();
}
}
diff --git a/src/applications/diffusion/engine/DiffusionCommitDraftEngine.php b/src/applications/diffusion/engine/DiffusionCommitDraftEngine.php
index 6245cf60fd..8837dbe63f 100644
--- a/src/applications/diffusion/engine/DiffusionCommitDraftEngine.php
+++ b/src/applications/diffusion/engine/DiffusionCommitDraftEngine.php
@@ -1,19 +1,20 @@
<?php
final class DiffusionCommitDraftEngine
extends PhabricatorDraftEngine {
protected function hasCustomDraftContent() {
$viewer = $this->getViewer();
$commit = $this->getObject();
$inlines = id(new DiffusionDiffInlineCommentQuery())
->setViewer($viewer)
->withCommitPHIDs(array($commit->getPHID()))
->withPublishableComments(true)
+ ->setLimit(1)
->execute();
return (bool)$inlines;
}
}
diff --git a/src/infrastructure/diff/PhabricatorInlineCommentController.php b/src/infrastructure/diff/PhabricatorInlineCommentController.php
index 5e6698bec8..529bd34c6e 100644
--- a/src/infrastructure/diff/PhabricatorInlineCommentController.php
+++ b/src/infrastructure/diff/PhabricatorInlineCommentController.php
@@ -1,497 +1,558 @@
<?php
abstract class PhabricatorInlineCommentController
extends PhabricatorController {
+ private $containerObject;
+
abstract protected function createComment();
abstract protected function newInlineCommentQuery();
abstract protected function loadCommentForDone($id);
abstract protected function loadObjectOwnerPHID(
PhabricatorInlineComment $inline);
- abstract protected function deleteComment(
- PhabricatorInlineComment $inline);
- abstract protected function undeleteComment(
- PhabricatorInlineComment $inline);
- abstract protected function saveComment(
- PhabricatorInlineComment $inline);
+ abstract protected function newContainerObject();
+
+ final protected function getContainerObject() {
+ if ($this->containerObject === null) {
+ $object = $this->newContainerObject();
+ if (!$object) {
+ throw new Exception(
+ pht(
+ 'Failed to load container object for inline comment.'));
+ }
+ $this->containerObject = $object;
+ }
+
+ return $this->containerObject;
+ }
protected function hideComments(array $ids) {
throw new PhutilMethodNotImplementedException();
}
protected function showComments(array $ids) {
throw new PhutilMethodNotImplementedException();
}
private $changesetID;
private $isNewFile;
private $isOnRight;
private $lineNumber;
private $lineLength;
private $commentText;
private $operation;
private $commentID;
private $renderer;
private $replyToCommentPHID;
public function getCommentID() {
return $this->commentID;
}
public function getOperation() {
return $this->operation;
}
public function getCommentText() {
return $this->commentText;
}
public function getLineLength() {
return $this->lineLength;
}
public function getLineNumber() {
return $this->lineNumber;
}
public function getIsOnRight() {
return $this->isOnRight;
}
public function getChangesetID() {
return $this->changesetID;
}
public function getIsNewFile() {
return $this->isNewFile;
}
public function setRenderer($renderer) {
$this->renderer = $renderer;
return $this;
}
public function getRenderer() {
return $this->renderer;
}
public function setReplyToCommentPHID($phid) {
$this->replyToCommentPHID = $phid;
return $this;
}
public function getReplyToCommentPHID() {
return $this->replyToCommentPHID;
}
public function processRequest() {
$request = $this->getRequest();
$viewer = $this->getViewer();
$this->readRequestParameters();
$op = $this->getOperation();
switch ($op) {
case 'hide':
case 'show':
if (!$request->validateCSRF()) {
return new Aphront404Response();
}
$ids = $request->getStrList('ids');
if ($ids) {
if ($op == 'hide') {
$this->hideComments($ids);
} else {
$this->showComments($ids);
}
}
return id(new AphrontAjaxResponse())->setContent(array());
case 'done':
if (!$request->validateCSRF()) {
return new Aphront404Response();
}
$inline = $this->loadCommentForDone($this->getCommentID());
$is_draft_state = false;
$is_checked = false;
switch ($inline->getFixedState()) {
case PhabricatorInlineComment::STATE_DRAFT:
$next_state = PhabricatorInlineComment::STATE_UNDONE;
break;
case PhabricatorInlineComment::STATE_UNDRAFT:
$next_state = PhabricatorInlineComment::STATE_DONE;
$is_checked = true;
break;
case PhabricatorInlineComment::STATE_DONE:
$next_state = PhabricatorInlineComment::STATE_UNDRAFT;
$is_draft_state = true;
break;
default:
case PhabricatorInlineComment::STATE_UNDONE:
$next_state = PhabricatorInlineComment::STATE_DRAFT;
$is_draft_state = true;
$is_checked = true;
break;
}
$inline->setFixedState($next_state)->save();
return id(new AphrontAjaxResponse())
->setContent(
array(
'isChecked' => $is_checked,
'draftState' => $is_draft_state,
));
case 'delete':
case 'undelete':
case 'refdelete':
if (!$request->validateCSRF()) {
return new Aphront404Response();
}
// NOTE: For normal deletes, we just process the delete immediately
// and show an "Undo" action. For deletes by reference from the
// preview ("refdelete"), we prompt first (because the "Undo" may
// not draw, or may not be easy to locate).
if ($op == 'refdelete') {
if (!$request->isFormPost()) {
return $this->newDialog()
->setTitle(pht('Really delete comment?'))
->addHiddenInput('id', $this->getCommentID())
->addHiddenInput('op', $op)
->appendParagraph(pht('Delete this inline comment?'))
->addCancelButton('#')
->addSubmitButton(pht('Delete'));
}
}
$is_delete = ($op == 'delete' || $op == 'refdelete');
$inline = $this->loadCommentByIDForEdit($this->getCommentID());
if ($is_delete) {
- $this->deleteComment($inline);
+ $inline->setIsDeleted(1);
} else {
- $this->undeleteComment($inline);
+ $inline->setIsDeleted(0);
}
+ $this->saveComment($inline);
+
return $this->buildEmptyResponse();
case 'edit':
$inline = $this->loadCommentByIDForEdit($this->getCommentID());
$text = $this->getCommentText();
if ($request->isFormPost()) {
if (strlen($text)) {
$inline
->setContent($text)
->setIsEditing(false);
$this->saveComment($inline);
- $this->purgeVersionedDrafts($inline);
return $this->buildRenderedCommentResponse(
$inline,
$this->getIsOnRight());
} else {
- $this->deleteComment($inline);
- $this->purgeVersionedDrafts($inline);
+ $inline->setIsDeleted(1);
+
+ $this->saveComment($inline);
return $this->buildEmptyResponse();
}
} else {
- $inline->setIsEditing(true);
+ // NOTE: At time of writing, the "editing" state of inlines is
+ // preserved by simluating a click on "Edit" when the inline loads.
- if (strlen($text)) {
- $inline->setContent($text);
- }
+ // In this case, we don't want to "saveComment()", because it
+ // recalculates object drafts and purges versioned drafts.
+
+ // The recalculation is merely unnecessary (state doesn't change)
+ // but purging drafts means that loading a page and then closing it
+ // discards your drafts.
- $this->saveComment($inline);
+ // To avoid the purge, only invoke "saveComment()" if we actually
+ // have changes to apply.
+
+ $is_dirty = false;
+ if (!$inline->getIsEditing()) {
+ $inline->setIsEditing(true);
+ $is_dirty = true;
+ }
if (strlen($text)) {
- $this->purgeVersionedDrafts($inline);
+ $inline->setContent($text);
+ $is_dirty = true;
+ } else {
+ PhabricatorInlineComment::loadAndAttachVersionedDrafts(
+ $viewer,
+ array($inline));
}
- PhabricatorInlineComment::loadAndAttachVersionedDrafts(
- $viewer,
- array($inline));
+ if ($is_dirty) {
+ $this->saveComment($inline);
+ }
}
$edit_dialog = $this->buildEditDialog($inline)
->setTitle(pht('Edit Inline Comment'));
$view = $this->buildScaffoldForView($edit_dialog);
return $this->newInlineResponse($inline, $view);
case 'cancel':
$inline = $this->loadCommentByIDForEdit($this->getCommentID());
$inline->setIsEditing(false);
// If the user uses "Undo" to get into an edited state ("AB"), then
// clicks cancel to return to the previous state ("A"), we also want
// to set the stored state back to "A".
$text = $this->getCommentText();
if (strlen($text)) {
$inline->setContent($text);
}
$content = $inline->getContent();
if (!strlen($content)) {
- $this->deleteComment($inline);
- } else {
- $this->saveComment($inline);
+ $inline->setIsDeleted(1);
}
- $this->purgeVersionedDrafts($inline);
+ $this->saveComment($inline);
return $this->buildEmptyResponse();
case 'draft':
$inline = $this->loadCommentByIDForEdit($this->getCommentID());
$versioned_draft = PhabricatorVersionedDraft::loadOrCreateDraft(
$inline->getPHID(),
$viewer->getPHID(),
$inline->getID());
$text = $this->getCommentText();
$versioned_draft
->setProperty('inline.text', $text)
->save();
+ // We have to synchronize the draft engine after saving a versioned
+ // draft, because taking an inline comment from "no text, no draft"
+ // to "no text, text in a draft" marks the container object as having
+ // a draft.
+ $draft_engine = $this->newDraftEngine();
+ if ($draft_engine) {
+ $draft_engine->synchronize();
+ } else {
+ phlog('no draft engine');
+ }
+
return $this->buildEmptyResponse();
case 'new':
case 'reply':
default:
// NOTE: We read the values from the client (the display values), not
// the values from the database (the original values) when replying.
// In particular, when replying to a ghost comment which was moved
// across diffs and then moved backward to the most recent visible
// line, we want to reply on the display line (which exists), not on
// the comment's original line (which may not exist in this changeset).
$is_new = $this->getIsNewFile();
$number = $this->getLineNumber();
$length = $this->getLineLength();
$inline = $this->createComment()
->setChangesetID($this->getChangesetID())
->setAuthorPHID($viewer->getPHID())
->setIsNewFile($is_new)
->setLineNumber($number)
->setLineLength($length)
->setContent($this->getCommentText())
->setReplyToCommentPHID($this->getReplyToCommentPHID())
->setIsEditing(true);
// If you own this object, mark your own inlines as "Done" by default.
$owner_phid = $this->loadObjectOwnerPHID($inline);
if ($owner_phid) {
if ($viewer->getPHID() == $owner_phid) {
$fixed_state = PhabricatorInlineComment::STATE_DRAFT;
$inline->setFixedState($fixed_state);
}
}
$this->saveComment($inline);
$edit_dialog = $this->buildEditDialog($inline);
if ($this->getOperation() == 'reply') {
$edit_dialog->setTitle(pht('Reply to Inline Comment'));
} else {
$edit_dialog->setTitle(pht('New Inline Comment'));
}
$view = $this->buildScaffoldForView($edit_dialog);
return $this->newInlineResponse($inline, $view);
}
}
private function readRequestParameters() {
$request = $this->getRequest();
// NOTE: This isn't necessarily a DifferentialChangeset ID, just an
// application identifier for the changeset. In Diffusion, it's a Path ID.
$this->changesetID = $request->getInt('changesetID');
$this->isNewFile = (int)$request->getBool('is_new');
$this->isOnRight = $request->getBool('on_right');
$this->lineNumber = $request->getInt('number');
$this->lineLength = $request->getInt('length');
$this->commentText = $request->getStr('text');
$this->commentID = $request->getInt('id');
$this->operation = $request->getStr('op');
$this->renderer = $request->getStr('renderer');
$this->replyToCommentPHID = $request->getStr('replyToCommentPHID');
if ($this->getReplyToCommentPHID()) {
$reply_phid = $this->getReplyToCommentPHID();
$reply_comment = $this->loadCommentByPHID($reply_phid);
if (!$reply_comment) {
throw new Exception(
pht('Failed to load comment "%s".', $reply_phid));
}
// When replying, force the new comment into the same location as the
// old comment. If we don't do this, replying to a ghost comment from
// diff A while viewing diff B can end up placing the two comments in
// different places while viewing diff C, because the porting algorithm
// makes a different decision. Forcing the comments to bind to the same
// place makes sure they stick together no matter which diff is being
// viewed. See T10562 for discussion.
$this->changesetID = $reply_comment->getChangesetID();
$this->isNewFile = $reply_comment->getIsNewFile();
$this->lineNumber = $reply_comment->getLineNumber();
$this->lineLength = $reply_comment->getLineLength();
}
}
private function buildEditDialog(PhabricatorInlineComment $inline) {
$request = $this->getRequest();
$viewer = $this->getViewer();
$edit_dialog = id(new PHUIDiffInlineCommentEditView())
->setViewer($viewer)
->setInlineComment($inline)
->setIsOnRight($this->getIsOnRight())
->setRenderer($this->getRenderer());
return $edit_dialog;
}
private function buildEmptyResponse() {
return id(new AphrontAjaxResponse())
->setContent(
array(
'inline' => array(),
'view' => null,
));
}
private function buildRenderedCommentResponse(
PhabricatorInlineComment $inline,
$on_right) {
$request = $this->getRequest();
$viewer = $this->getViewer();
$engine = new PhabricatorMarkupEngine();
$engine->setViewer($viewer);
$engine->addObject(
$inline,
PhabricatorInlineComment::MARKUP_FIELD_BODY);
$engine->process();
$phids = array($viewer->getPHID());
$handles = $this->loadViewerHandles($phids);
$object_owner_phid = $this->loadObjectOwnerPHID($inline);
$view = id(new PHUIDiffInlineCommentDetailView())
->setUser($viewer)
->setInlineComment($inline)
->setIsOnRight($on_right)
->setMarkupEngine($engine)
->setHandles($handles)
->setEditable(true)
->setCanMarkDone(false)
->setObjectOwnerPHID($object_owner_phid);
$view = $this->buildScaffoldForView($view);
return $this->newInlineResponse($inline, $view);
}
private function buildScaffoldForView(PHUIDiffInlineCommentView $view) {
$renderer = DifferentialChangesetHTMLRenderer::getHTMLRendererByKey(
$this->getRenderer());
$view = $renderer->getRowScaffoldForInline($view);
return id(new PHUIDiffInlineCommentTableScaffold())
->addRowScaffold($view);
}
private function newInlineResponse(
PhabricatorInlineComment $inline,
$view) {
$response = array(
'inline' => array(
'id' => $inline->getID(),
),
'view' => hsprintf('%s', $view),
);
return id(new AphrontAjaxResponse())
->setContent($response);
}
- private function purgeVersionedDrafts(
- PhabricatorInlineComment $inline) {
- $viewer = $this->getViewer();
- PhabricatorVersionedDraft::purgeDrafts(
- $inline->getPHID(),
- $viewer->getPHID());
- }
-
final protected function loadCommentByID($id) {
$query = $this->newInlineCommentQuery()
->withIDs(array($id));
return $this->loadCommentByQuery($query);
}
final protected function loadCommentByPHID($phid) {
$query = $this->newInlineCommentQuery()
->withPHIDs(array($phid));
return $this->loadCommentByQuery($query);
}
final protected function loadCommentByIDForEdit($id) {
$viewer = $this->getViewer();
$query = $this->newInlineCommentQuery()
->withIDs(array($id));
$inline = $this->loadCommentByQuery($query);
if (!$inline) {
throw new Exception(
pht(
'Unable to load inline "%s".',
$id));
}
if (!$this->canEditInlineComment($viewer, $inline)) {
throw new Exception(
pht(
'Inline comment "%s" is not editable.',
$id));
}
return $inline;
}
private function loadCommentByQuery(
PhabricatorDiffInlineCommentQuery $query) {
$viewer = $this->getViewer();
$inline = $query
->setViewer($viewer)
->executeOne();
if ($inline) {
$inline = $inline->newInlineCommentObject();
}
return $inline;
}
+ private function saveComment(PhabricatorInlineComment $inline) {
+ $viewer = $this->getViewer();
+ $draft_engine = $this->newDraftEngine();
+
+ $inline->openTransaction();
+ $inline->save();
+
+ PhabricatorVersionedDraft::purgeDrafts(
+ $inline->getPHID(),
+ $viewer->getPHID());
+
+ if ($draft_engine) {
+ $draft_engine->synchronize();
+ }
+
+ $inline->saveTransaction();
+ }
+
+ private function newDraftEngine() {
+ $viewer = $this->getViewer();
+ $object = $this->getContainerObject();
+
+ if (!($object instanceof PhabricatorDraftInterface)) {
+ return null;
+ }
+
+ return $object->newDraftEngine()
+ ->setObject($object)
+ ->setViewer($viewer);
+ }
+
}

File Metadata

Mime Type
text/x-diff
Expires
Sun, Jan 19, 16:02 (2 w, 6 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1126299
Default Alt Text
(29 KB)

Event Timeline