diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -4884,6 +4884,7 @@ 'TokenGiveConduitAPIMethod' => 'applications/tokens/conduit/TokenGiveConduitAPIMethod.php', 'TokenGivenConduitAPIMethod' => 'applications/tokens/conduit/TokenGivenConduitAPIMethod.php', 'TokenQueryConduitAPIMethod' => 'applications/tokens/conduit/TokenQueryConduitAPIMethod.php', + 'TransactionSearchConduitAPIMethod' => 'applications/transactions/conduit/TransactionSearchConduitAPIMethod.php', 'UserConduitAPIMethod' => 'applications/people/conduit/UserConduitAPIMethod.php', 'UserDisableConduitAPIMethod' => 'applications/people/conduit/UserDisableConduitAPIMethod.php', 'UserEnableConduitAPIMethod' => 'applications/people/conduit/UserEnableConduitAPIMethod.php', @@ -10631,6 +10632,7 @@ 'TokenGiveConduitAPIMethod' => 'TokenConduitAPIMethod', 'TokenGivenConduitAPIMethod' => 'TokenConduitAPIMethod', 'TokenQueryConduitAPIMethod' => 'TokenConduitAPIMethod', + 'TransactionSearchConduitAPIMethod' => 'ConduitAPIMethod', 'UserConduitAPIMethod' => 'ConduitAPIMethod', 'UserDisableConduitAPIMethod' => 'UserConduitAPIMethod', 'UserEnableConduitAPIMethod' => 'UserConduitAPIMethod', diff --git a/src/applications/transactions/conduit/TransactionSearchConduitAPIMethod.php b/src/applications/transactions/conduit/TransactionSearchConduitAPIMethod.php new file mode 100644 --- /dev/null +++ b/src/applications/transactions/conduit/TransactionSearchConduitAPIMethod.php @@ -0,0 +1,152 @@ + 'phid|string', + ) + $this->getPagerParamTypes(); + } + + protected function defineReturnType() { + return 'list'; + } + + protected function defineErrorTypes() { + return array(); + } + + protected function execute(ConduitAPIRequest $request) { + $viewer = $request->getUser(); + $pager = $this->newPager($request); + + $object_name = $request->getValue('objectIdentifier', null); + if (!strlen($object_name)) { + throw new Exception( + pht( + 'When calling "transaction.search", you must provide an object to '. + 'retrieve transactions for.')); + } + + $object = id(new PhabricatorObjectQuery()) + ->setViewer($viewer) + ->withNames(array($object_name)) + ->executeOne(); + if (!$object) { + throw new Exception( + pht( + 'No object "%s" exists.', + $object_name)); + } + + if (!($object instanceof PhabricatorApplicationTransactionInterface)) { + throw new Exception( + pht( + 'Object "%s" does not implement "%s", so transactions can not '. + 'be loaded for it.')); + } + + $xaction_query = PhabricatorApplicationTransactionQuery::newQueryForObject( + $object); + + $xactions = $xaction_query + ->withObjectPHIDs(array($object->getPHID())) + ->setViewer($viewer) + ->executeWithCursorPager($pager); + + if ($xactions) { + $template = head($xactions)->getApplicationTransactionCommentObject(); + + $query = new PhabricatorApplicationTransactionTemplatedCommentQuery(); + + $comment_map = $query + ->setViewer($viewer) + ->setTemplate($template) + ->withTransactionPHIDs(mpull($xactions, 'getPHID')) + ->execute(); + + $comment_map = msort($comment_map, 'getCommentVersion'); + $comment_map = array_reverse($comment_map); + $comment_map = mgroup($comment_map, 'getTransactionPHID'); + } else { + $comment_map = array(); + } + + $data = array(); + foreach ($xactions as $xaction) { + $comments = idx($comment_map, $xaction->getPHID()); + + $comment_data = array(); + if ($comments) { + $removed = head($comments)->getIsDeleted(); + + foreach ($comments as $comment) { + if ($removed) { + // If the most recent version of the comment has been removed, + // don't show the history. This is for consistency with the web + // UI, which also prevents users from retrieving the content of + // removed comments. + $content = array( + 'raw' => '', + ); + } else { + $content = array( + 'raw' => (string)$comment->getContent(), + ); + } + + $comment_data[] = array( + 'id' => (int)$comment->getID(), + 'phid' => (string)$comment->getPHID(), + 'version' => (int)$comment->getCommentVersion(), + 'authorPHID' => (string)$comment->getAuthorPHID(), + 'dateCreated' => (int)$comment->getDateCreated(), + 'dateModified' => (int)$comment->getDateModified(), + 'removed' => (bool)$comment->getIsDeleted(), + 'content' => $content, + ); + } + } + + $fields = array(); + + if (!$fields) { + $fields = (object)$fields; + } + + $data[] = array( + 'id' => (int)$xaction->getID(), + 'phid' => (string)$xaction->getPHID(), + 'authorPHID' => (string)$xaction->getAuthorPHID(), + 'objectPHID' => (string)$xaction->getObjectPHID(), + 'dateCreated' => (int)$xaction->getDateCreated(), + 'dateModified' => (int)$xaction->getDateModified(), + 'comments' => $comment_data, + 'fields' => $fields, + ); + } + + $results = array( + 'data' => $data, + ); + + return $this->addPagerResults($results, $pager); + } +}