public function execute()
 {
     $table = new DifferentialTransactionComment();
     $conn_r = $table->establishConnection('r');
     $data = queryfx_all($conn_r, 'SELECT * FROM %T %Q %Q', $table->getTableName(), $this->buildWhereClause($conn_r), $this->buildLimitClause($conn_r));
     $comments = $table->loadAllFromArray($data);
     foreach ($comments as $key => $value) {
         $comments[$key] = DifferentialInlineComment::newFromModernComment($value);
     }
     return $comments;
 }
 public static function loadUnsubmittedInlineComments(PhabricatorUser $viewer, DifferentialRevision $revision)
 {
     // TODO: This probably needs to move somewhere more central as we move
     // away from DifferentialInlineCommentQuery, but
     // PhabricatorApplicationTransactionCommentQuery is currently `final` and
     // I'm not yet decided on how to approach that. For now, just get the PHIDs
     // and then execute a PHID-based query through the standard stack.
     $table = new DifferentialTransactionComment();
     $conn_r = $table->establishConnection('r');
     $phids = queryfx_all($conn_r, 'SELECT phid FROM %T
     WHERE revisionPHID = %s
       AND authorPHID = %s
       AND transactionPHID IS NULL', $table->getTableName(), $revision->getPHID(), $viewer->getPHID());
     $phids = ipull($phids, 'phid');
     if (!$phids) {
         return array();
     }
     return id(new PhabricatorApplicationTransactionCommentQuery())->setTemplate(new DifferentialTransactionComment())->setViewer($viewer)->withPHIDs($phids)->execute();
 }
 public function execute()
 {
     $table = new DifferentialTransactionComment();
     $conn_r = $table->establishConnection('r');
     $data = queryfx_all($conn_r, 'SELECT * FROM %T %Q %Q', $table->getTableName(), $this->buildWhereClause($conn_r), $this->buildLimitClause($conn_r));
     $comments = $table->loadAllFromArray($data);
     if ($this->needHidden) {
         $viewer_phid = $this->getViewer()->getPHID();
         if ($viewer_phid && $comments) {
             $hidden = queryfx_all($conn_r, 'SELECT commentID FROM %T WHERE userPHID = %s
         AND commentID IN (%Ls)', id(new DifferentialHiddenComment())->getTableName(), $viewer_phid, mpull($comments, 'getID'));
             $hidden = array_fuse(ipull($hidden, 'commentID'));
         } else {
             $hidden = array();
         }
         foreach ($comments as $inline) {
             $inline->attachIsHidden(isset($hidden[$inline->getID()]));
         }
     }
     foreach ($comments as $key => $value) {
         $comments[$key] = DifferentialInlineComment::newFromModernComment($value);
     }
     return $comments;
 }
 private function renderInlineCommentsForMail(PhabricatorLiskDAO $object, array $inlines)
 {
     $context_key = 'metamta.differential.unified-comment-context';
     $show_context = PhabricatorEnv::getEnvConfig($context_key);
     $changeset_ids = array();
     $line_numbers_by_changeset = array();
     foreach ($inlines as $inline) {
         $id = $inline->getComment()->getChangesetID();
         $changeset_ids[$id] = $id;
         $line_numbers_by_changeset[$id][] = $inline->getComment()->getLineNumber();
     }
     $changesets = id(new DifferentialChangesetQuery())->setViewer($this->getActor())->withIDs($changeset_ids)->needHunks(true)->execute();
     $inline_groups = DifferentialTransactionComment::sortAndGroupInlines($inlines, $changesets);
     if ($show_context) {
         $hunk_parser = new DifferentialHunkParser();
         $table = new DifferentialTransactionComment();
         $conn_r = $table->establishConnection('r');
         $queries = array();
         foreach ($line_numbers_by_changeset as $id => $line_numbers) {
             $queries[] = qsprintf($conn_r, '(changesetID = %d AND lineNumber IN (%Ld))', $id, $line_numbers);
         }
         $all_comments = id(new DifferentialTransactionComment())->loadAllWhere('transactionPHID IS NOT NULL AND (%Q)', implode(' OR ', $queries));
         $comments_by_line_number = array();
         foreach ($all_comments as $comment) {
             $comments_by_line_number[$comment->getChangesetID()][$comment->getLineNumber()][$comment->getID()] = $comment;
         }
         $author_phids = mpull($all_comments, 'getAuthorPHID');
         $authors = id(new PhabricatorPeopleQuery())->setViewer($this->getActor())->withPHIDs($author_phids)->execute();
         $authors_by_phid = mpull($authors, null, 'getPHID');
     }
     $section = new PhabricatorMetaMTAMailSection();
     foreach ($inline_groups as $changeset_id => $group) {
         $changeset = idx($changesets, $changeset_id);
         if (!$changeset) {
             continue;
         }
         foreach ($group as $inline) {
             $comment = $inline->getComment();
             $file = $changeset->getFilename();
             $start = $comment->getLineNumber();
             $len = $comment->getLineLength();
             if ($len) {
                 $range = $start . '-' . ($start + $len);
             } else {
                 $range = $start;
             }
             $inline_content = $comment->getContent();
             if (!$show_context) {
                 $section->addFragment("{$file}:{$range} {$inline_content}");
             } else {
                 $patch = $hunk_parser->makeContextDiff($changeset->getHunks(), $comment->getIsNewFile(), $comment->getLineNumber(), $comment->getLineLength(), 1);
                 $nested_comments = $this->nestCommentHistory($inline->getComment(), $comments_by_line_number, $authors_by_phid);
                 $section->addFragment('================')->addFragment(pht('Comment at: %s:%s', $file, $range))->addPlaintextFragment($patch)->addHTMLFragment($this->renderPatchHTMLForMail($patch))->addFragment('----------------')->addFragment($nested_comments)->addFragment(null);
             }
         }
     }
     return $section;
 }
 protected function applyBuiltinExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     switch ($xaction->getTransactionType()) {
         case PhabricatorTransactions::TYPE_INLINESTATE:
             $table = new DifferentialTransactionComment();
             $conn_w = $table->establishConnection('w');
             foreach ($xaction->getNewValue() as $phid => $state) {
                 queryfx($conn_w, 'UPDATE %T SET fixedState = %s WHERE phid = %s', $table->getTableName(), $state, $phid);
             }
             break;
     }
     return parent::applyBuiltinExternalTransaction($object, $xaction);
 }
 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();
         $inline_groups = DifferentialTransactionComment::sortAndGroupInlines($inlines, $changesets);
         foreach ($inline_groups as $changeset_id => $group) {
             $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;
 }
 private function getInlineURI(DifferentialTransactionComment $comment)
 {
     $changeset = $this->getChangeset($comment->getChangesetID());
     if (!$changeset) {
         return null;
     }
     $diff = $changeset->getDiff();
     if (!$diff) {
         return null;
     }
     $revision = $diff->getRevision();
     if (!$revision) {
         return null;
     }
     $link_href = '/' . $revision->getMonogram() . '#inline-' . $comment->getID();
     $link_href = PhabricatorEnv::getProductionURI($link_href);
     return $link_href;
 }