diff --git a/src/applications/ponder/controller/PonderVoteSaveController.php b/src/applications/ponder/controller/PonderVoteSaveController.php index 24ef3c4c55..d4169f9f4b 100644 --- a/src/applications/ponder/controller/PonderVoteSaveController.php +++ b/src/applications/ponder/controller/PonderVoteSaveController.php @@ -1,44 +1,44 @@ <?php final class PonderVoteSaveController extends PonderController { private $kind; public function willProcessRequest(array $data) { $this->kind = $data['kind']; } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $newvote = $request->getInt("vote"); $phid = $request->getStr("phid"); if (1 < $newvote || $newvote < -1) { return new Aphront400Response(); } $target = null; if ($this->kind == "question") { $target = PonderQuestionQuery::loadSingleByPHID($user, $phid); } else if ($this->kind == "answer") { $target = id(new PonderAnswerQuery()) ->setViewer($user) - ->withPHID($phid) + ->withPHIDs(array($phid)) ->executeOne(); } if (!$target) { return new Aphront404Response(); } $editor = id(new PonderVoteEditor()) ->setVotable($target) ->setActor($user) ->setVote($newvote) ->saveVote(); return id(new AphrontAjaxResponse())->setContent("."); } } diff --git a/src/applications/ponder/query/PonderAnswerQuery.php b/src/applications/ponder/query/PonderAnswerQuery.php index 608c3c62e5..ed0c6f926f 100644 --- a/src/applications/ponder/query/PonderAnswerQuery.php +++ b/src/applications/ponder/query/PonderAnswerQuery.php @@ -1,95 +1,104 @@ <?php final class PonderAnswerQuery extends PhabricatorOffsetPagedQuery { - private $id; - private $phid; - private $authorPHID; - private $orderNewest; + private $ids; + private $phids; + private $authorPHIDs; + private $questionIDs; private $viewer; public function setViewer(PhabricatorUser $viewer) { $this->viewer = $viewer; return $this; } public function getViewer() { return $this->viewer; } public function executeOne() { return head($this->execute()); } - public function withID($qid) { - $this->id = $qid; + public function withIDs(array $ids) { + $this->ids = $ids; return $this; } - public function withPHID($phid) { - $this->phid = $phid; + public function withPHIDs(array $phids) { + $this->phids = $phids; return $this; } - public function withAuthorPHID($phid) { - $this->authorPHID = $phid; + public function withAuthorPHIDs(array $phids) { + $this->authorPHIDs = $phids; return $this; } - public function orderByNewest($usethis) { - $this->orderNewest = $usethis; + public function withQuestionIDs(array $ids) { + $this->questionIDs = $ids; return $this; } private function buildWhereClause($conn_r) { $where = array(); - if ($this->id) { - $where[] = qsprintf($conn_r, '(id = %d)', $this->id); + + if ($this->ids) { + $where[] = qsprintf( + $conn_r, + 'id IN (%Ld)', + $this->ids); } - if ($this->phid) { - $where[] = qsprintf($conn_r, '(phid = %s)', $this->phid); + + if ($this->phids) { + $where[] = qsprintf( + $conn_r, + 'phid IN (%Ls)', + $this->phids); } - if ($this->authorPHID) { - $where[] = qsprintf($conn_r, '(authorPHID = %s)', $this->authorPHID); + + if ($this->authorPHIDs) { + $where[] = qsprintf( + $conn_r, + 'authorPHID IN (%Ls)', + $this->authorPHIDs); } return $this->formatWhereClause($where); } private function buildOrderByClause($conn_r) { - $order = array(); - if ($this->orderNewest) { - $order[] = qsprintf($conn_r, 'id DESC'); - } - - if (count($order) == 0) { - $order[] = qsprintf($conn_r, 'id ASC'); - } - - return ($order ? 'ORDER BY ' . implode(', ', $order) : ''); + return 'ORDER BY id ASC'; } public function execute() { $answer = new PonderAnswer(); $conn_r = $answer->establishConnection('r'); - $select = qsprintf( + $data = queryfx_all( $conn_r, - 'SELECT r.* FROM %T r', - $answer->getTableName()); - - $where = $this->buildWhereClause($conn_r); - $order_by = $this->buildOrderByClause($conn_r); - $limit = $this->buildLimitClause($conn_r); + 'SELECT a.* FROM %T a %Q %Q %Q', + $answer->getTableName(), + $this->buildWhereClause($conn_r), + $this->buildOrderByClause($conn_r), + $this->buildLimitClause($conn_r)); + + $answers = $answer->loadAllFromArray($data); + + if ($answers) { + $questions = id(new PonderQuestionQuery()) + ->setViewer($this->getViewer()) + ->withIDs(mpull($answers, 'getQuestionID')) + ->execute(); + + foreach ($answers as $answer) { + $question = idx($questions, $answer->getQuestionID()); + $answer->attachQuestion($question); + } + } - return $answer->loadAllFromArray( - queryfx_all( - $conn_r, - '%Q %Q %Q %Q', - $select, - $where, - $order_by, - $limit)); + return $answers; } } diff --git a/src/applications/ponder/storage/PonderAnswer.php b/src/applications/ponder/storage/PonderAnswer.php index fd4b0ad988..ba6b1f24da 100644 --- a/src/applications/ponder/storage/PonderAnswer.php +++ b/src/applications/ponder/storage/PonderAnswer.php @@ -1,109 +1,114 @@ <?php final class PonderAnswer extends PonderDAO implements PhabricatorMarkupInterface, PonderVotableInterface { const MARKUP_FIELD_CONTENT = 'markup:content'; protected $phid; protected $authorPHID; protected $questionID; protected $content; protected $contentSource; protected $voteCount; private $vote; - private $question = null; + private $question = self::ATTACHABLE; private $comments; + // TODO: Get rid of this method. public function setQuestion($question) { + return $this->attachQuestion($question); + } + + public function attachQuestion(PonderQuestion $question = null) { $this->question = $question; return $this; } public function getQuestion() { - return $this->question; + return $this->assertAttached($this->question); } public function setUserVote($vote) { $this->vote = $vote['data']; if (!$this->vote) { $this->vote = PonderVote::VOTE_NONE; } return $this; } public function getUserVote() { return $this->vote; } public function setComments($comments) { $this->comments = $comments; return $this; } public function getComments() { return $this->comments; } public function getConfiguration() { return array( self::CONFIG_AUX_PHID => true, ) + parent::getConfiguration(); } public function generatePHID() { return PhabricatorPHID::generateNewPHID( PhabricatorPHIDConstants::PHID_TYPE_ANSW); } public function setContentSource(PhabricatorContentSource $content_source) { $this->contentSource = $content_source->serialize(); return $this; } public function getContentSource() { return PhabricatorContentSource::newFromSerialized($this->contentSource); } public function getMarkupField() { return self::MARKUP_FIELD_CONTENT; } // Markup interface public function getMarkupFieldKey($field) { $hash = PhabricatorHash::digest($this->getMarkupText($field)); $id = $this->getID(); return "ponder:A{$id}:{$field}:{$hash}"; } public function getMarkupText($field) { return $this->getContent(); } public function newMarkupEngine($field) { return PhabricatorMarkupEngine::newPonderMarkupEngine(); } public function didMarkupText( $field, $output, PhutilMarkupEngine $engine) { return $output; } public function shouldUseMarkupCache($field) { return (bool)$this->getID(); } // votable interface public function getUserVoteEdgeType() { return PhabricatorEdgeConfig::TYPE_VOTING_USER_HAS_ANSWER; } public function getVotablePHID() { return $this->getPHID(); } }