Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2892000
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Advanced/Developer...
View Handle
View Hovercard
Size
29 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
rP Phorge
Attached
Detach File
Event Timeline
Log In to Comment