diff --git a/src/applications/ponder/controller/PonderAnswerPreviewController.php b/src/applications/ponder/controller/PonderAnswerPreviewController.php index 3b46580444..68f400dd0e 100644 --- a/src/applications/ponder/controller/PonderAnswerPreviewController.php +++ b/src/applications/ponder/controller/PonderAnswerPreviewController.php @@ -1,38 +1,40 @@ getRequest(); - $user = $request->getUser(); + $viewer = $request->getUser(); $question_id = $request->getInt('question_id'); - $question = PonderQuestionQuery::loadSingle($user, $question_id); + $question = id(new PonderQuestionQuery()) + ->setViewer($viewer) + ->withIDs(array($question_id)) + ->executeOne(); if (!$question) { return new Aphront404Response(); } - $author_phid = $user->getPHID(); + $author_phid = $viewer->getPHID(); $object_phids = array($author_phid); $handles = $this->loadViewerHandles($object_phids); $answer = new PonderAnswer(); $answer->setContent($request->getStr('content')); $answer->setAuthorPHID($author_phid); $view = new PonderPostBodyView(); $view ->setQuestion($question) ->setTarget($answer) ->setPreview(true) - ->setUser($user) + ->setUser($viewer) ->setHandles($handles) ->setAction(PonderLiterals::LITERAL_ANSWERED); return id(new AphrontAjaxResponse()) ->setContent($view->render()); } } diff --git a/src/applications/ponder/controller/PonderAnswerSaveController.php b/src/applications/ponder/controller/PonderAnswerSaveController.php index ce137b7628..97cadbe3cb 100644 --- a/src/applications/ponder/controller/PonderAnswerSaveController.php +++ b/src/applications/ponder/controller/PonderAnswerSaveController.php @@ -1,57 +1,59 @@ getRequest(); + $viewer = $request->getUser(); + if (!$request->isFormPost()) { return new Aphront400Response(); } - $user = $request->getUser(); $question_id = $request->getInt('question_id'); - $question = PonderQuestionQuery::loadSingle($user, $question_id); - + $question = id(new PonderQuestionQuery()) + ->setViewer($viewer) + ->withIDs(array($question_id)) + ->executeOne(); if (!$question) { return new Aphront404Response(); } $answer = $request->getStr('answer'); - // Only want answers with some non whitespace content if (!strlen(trim($answer))) { - $dialog = new AphrontDialogView(); - $dialog->setUser($request->getUser()); - $dialog->setTitle(pht('Empty Answer')); - $dialog->appendChild( - phutil_tag('p', array(), pht( - 'Your answer must not be empty.'))); - $dialog->addCancelButton('/Q'.$question_id); + $dialog = id(new AphrontDialogView()) + ->setUser($viewer) + ->setTitle(pht('Empty Answer')) + ->appendChild( + phutil_tag('p', array(), pht( + 'Your answer must not be empty.'))) + ->addCancelButton('/Q'.$question_id); return id(new AphrontDialogResponse())->setDialog($dialog); } $content_source = PhabricatorContentSource::newForSource( PhabricatorContentSource::SOURCE_WEB, array( 'ip' => $request->getRemoteAddr(), )); $res = new PonderAnswer(); $res ->setContent($answer) - ->setAuthorPHID($user->getPHID()) + ->setAuthorPHID($viewer->getPHID()) ->setVoteCount(0) ->setQuestionID($question_id) ->setContentSource($content_source); id(new PonderAnswerEditor()) - ->setActor($user) + ->setActor($viewer) ->setQuestion($question) ->setAnswer($res) ->saveAnswer(); return id(new AphrontRedirectResponse())->setURI( id(new PhutilURI('/Q'. $question->getID()))); } } diff --git a/src/applications/ponder/controller/PonderCommentSaveController.php b/src/applications/ponder/controller/PonderCommentSaveController.php index 45c2539101..a3af847977 100644 --- a/src/applications/ponder/controller/PonderCommentSaveController.php +++ b/src/applications/ponder/controller/PonderCommentSaveController.php @@ -1,60 +1,62 @@ getRequest(); if (!$request->isFormPost()) { return new Aphront400Response(); } $user = $request->getUser(); $question_id = $request->getInt('question_id'); - $question = PonderQuestionQuery::loadSingle($user, $question_id); - + $question = id(new PonderQuestionQuery()) + ->setViewer($user) + ->withIDs(array($question_id)) + ->executeOne(); if (!$question) { return new Aphront404Response(); } $question->attachRelated(); $target = $request->getStr('target'); $objects = id(new PhabricatorObjectHandleData(array($target))) ->setViewer($user) ->loadHandles(); if (!$objects) { return new Aphront404Response(); } $content = $request->getStr('content'); if (!strlen(trim($content))) { $dialog = new AphrontDialogView(); $dialog->setUser($request->getUser()); $dialog->setTitle(pht('Empty Comment')); $dialog->appendChild(phutil_tag('p', array(), pht( 'Your comment must not be empty.'))); $dialog->addCancelButton('/Q'.$question_id); return id(new AphrontDialogResponse())->setDialog($dialog); } $res = new PonderComment(); $res ->setContent($content) ->setAuthorPHID($user->getPHID()) ->setTargetPHID($target); id(new PonderCommentEditor()) ->setQuestion($question) ->setComment($res) ->setTargetPHID($target) ->setActor($user) ->save(); return id(new AphrontRedirectResponse()) ->setURI( id(new PhutilURI('/Q'. $question->getID()))); } } diff --git a/src/applications/ponder/controller/PonderQuestionViewController.php b/src/applications/ponder/controller/PonderQuestionViewController.php index 089dafc5de..f230db1818 100644 --- a/src/applications/ponder/controller/PonderQuestionViewController.php +++ b/src/applications/ponder/controller/PonderQuestionViewController.php @@ -1,196 +1,199 @@ questionID = $data['id']; } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); - $question = PonderQuestionQuery::loadSingle($user, $this->questionID); + $question = id(new PonderQuestionQuery()) + ->setViewer($user) + ->withIDs(array($this->questionID)) + ->executeOne(); if (!$question) { return new Aphront404Response(); } $question->attachRelated(); $question->attachVotes($user->getPHID()); $object_phids = array($user->getPHID(), $question->getAuthorPHID()); $answers = $question->getAnswers(); $comments = $question->getComments(); foreach ($comments as $comment) { $object_phids[] = $comment->getAuthorPHID(); } foreach ($answers as $answer) { $object_phids[] = $answer->getAuthorPHID(); $comments = $answer->getComments(); foreach ($comments as $comment) { $object_phids[] = $comment->getAuthorPHID(); } } $object_phids = array_merge($object_phids); $this->loadHandles($object_phids); $handles = $this->getLoadedHandles(); $question_xactions = $this->buildQuestionTransactions($question); $responses_panel = new PonderAnswerListView(); $responses_panel ->setQuestion($question) ->setHandles($handles) ->setUser($user) ->setAnswers($answers); $answer_add_panel = new PonderAddAnswerView(); $answer_add_panel ->setQuestion($question) ->setUser($user) ->setActionURI("/ponder/answer/add/"); $header = id(new PhabricatorHeaderView()) ->setHeader($question->getTitle()); $actions = $this->buildActionListView($question); $properties = $this->buildPropertyListView($question); $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView()); $crumbs->setActionList($actions); $crumbs->addCrumb( id(new PhabricatorCrumbView()) ->setName('Q'.$this->questionID) ->setHref('/Q'.$this->questionID)); return $this->buildApplicationPage( array( $crumbs, $header, $actions, $properties, $question_xactions, $responses_panel, $answer_add_panel ), array( 'device' => true, 'title' => 'Q'.$question->getID().' '.$question->getTitle(), 'dust' => true, )); } private function buildActionListView(PonderQuestion $question) { $request = $this->getRequest(); $viewer = $request->getUser(); $id = $question->getID(); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $question, PhabricatorPolicyCapability::CAN_EDIT); $view = id(new PhabricatorActionListView()) ->setUser($request->getUser()) ->setObject($question) ->setObjectURI($request->getRequestURI()); $view->addAction( id(new PhabricatorActionView()) ->setIcon('edit') ->setName(pht('Edit Question')) ->setHref($this->getApplicationURI("/question/edit/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); if ($question->getStatus() == PonderQuestionStatus::STATUS_OPEN) { $name = pht("Close Question"); $icon = "delete"; $href = "close"; } else { $name = pht("Reopen Question"); $icon = "enable"; $href = "open"; } $view->addAction( id(new PhabricatorActionView()) ->setName($name) ->setIcon($icon) ->setRenderAsForm($can_edit) ->setWorkflow(!$can_edit) ->setDisabled(!$can_edit) ->setHref($this->getApplicationURI("/question/{$href}/{$id}/"))); return $view; } private function buildPropertyListView( PonderQuestion $question) { $viewer = $this->getRequest()->getUser(); $view = id(new PhabricatorPropertyListView()) ->setUser($viewer) ->setObject($question); $view->addProperty( pht('Status'), PonderQuestionStatus::getQuestionStatusFullName($question->getStatus())); $view->addProperty( pht('Author'), $this->getHandle($question->getAuthorPHID())->renderLink()); $view->addProperty( pht('Created'), phabricator_datetime($question->getDateCreated(), $viewer)); $view->invokeWillRenderEvent(); $view->addTextContent( PhabricatorMarkupEngine::renderOneObject( $question, $question->getMarkupField(), $viewer)); return $view; } private function buildQuestionTransactions(PonderQuestion $question) { $viewer = $this->getRequest()->getUser(); $xactions = id(new PonderQuestionTransactionQuery()) ->setViewer($viewer) ->withObjectPHIDs(array($question->getPHID())) ->execute(); $engine = id(new PhabricatorMarkupEngine()) ->setViewer($viewer); foreach ($xactions as $xaction) { if ($xaction->getComment()) { $engine->addObject( $xaction->getComment(), PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); } } $engine->process(); $timeline = id(new PhabricatorApplicationTransactionView()) ->setUser($viewer) ->setTransactions($xactions) ->setMarkupEngine($engine); // TODO: Add comment form. return $timeline; } } diff --git a/src/applications/ponder/controller/PonderVoteSaveController.php b/src/applications/ponder/controller/PonderVoteSaveController.php index d4169f9f4b..2d1e39d9dd 100644 --- a/src/applications/ponder/controller/PonderVoteSaveController.php +++ b/src/applications/ponder/controller/PonderVoteSaveController.php @@ -1,44 +1,47 @@ 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); + $target = id(new PonderQuestionQuery()) + ->setViewer($user) + ->withPHIDs(array($phid)) + ->executeOne(); } else if ($this->kind == "answer") { $target = id(new PonderAnswerQuery()) ->setViewer($user) ->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/PonderQuestionQuery.php b/src/applications/ponder/query/PonderQuestionQuery.php index 1fd093821c..ce671fa9f6 100644 --- a/src/applications/ponder/query/PonderQuestionQuery.php +++ b/src/applications/ponder/query/PonderQuestionQuery.php @@ -1,164 +1,142 @@ ids = $ids; return $this; } public function withPHIDs(array $phids) { $this->phids = $phids; return $this; } public function withAuthorPHIDs(array $phids) { $this->authorPHIDs = $phids; return $this; } public function withStatus($status) { $this->status = $status; return $this; } public function withAnswererPHIDs(array $phids) { $this->answererPHIDs = $phids; return $this; } public function setOrder($order) { $this->order = $order; return $this; } - public static function loadSingle($viewer, $id) { - if (!$viewer) { - throw new Exception("Must set viewer when calling loadSingle"); - } - - return idx(id(new PonderQuestionQuery()) - ->setViewer($viewer) - ->withIDs(array($id)) - ->execute(), $id); - } - - public static function loadSingleByPHID($viewer, $phid) { - if (!$viewer) { - throw new Exception("Must set viewer when calling loadSingle"); - } - - return array_shift(id(new PonderQuestionQuery()) - ->withPHIDs(array($phid)) - ->setViewer($viewer) - ->execute()); - } - private function buildWhereClause(AphrontDatabaseConnection $conn_r) { $where = array(); if ($this->ids) { $where[] = qsprintf( $conn_r, 'q.id IN (%Ld)', $this->ids); } if ($this->phids) { $where[] = qsprintf( $conn_r, 'q.phid IN (%Ls)', $this->phids); } if ($this->authorPHIDs) { $where[] = qsprintf( $conn_r, 'q.authorPHID IN (%Ls)', $this->authorPHIDs); } if ($this->status) { switch ($this->status) { case self::STATUS_ANY: break; case self::STATUS_OPEN: $where[] = qsprintf( $conn_r, 'q.status = %d', PonderQuestionStatus::STATUS_OPEN); break; case self::STATUS_CLOSED: $where[] = qsprintf( $conn_r, 'q.status = %d', PonderQuestionStatus::STATUS_CLOSED); break; default: throw new Exception("Unknown status query '{$this->status}'!"); } } $where[] = $this->buildPagingClause($conn_r); return $this->formatWhereClause($where); } private function buildOrderByClause(AphrontDatabaseConnection $conn_r) { switch ($this->order) { case self::ORDER_HOTTEST: return qsprintf($conn_r, 'ORDER BY q.heat DESC, q.id DESC'); case self::ORDER_CREATED: return qsprintf($conn_r, 'ORDER BY q.id DESC'); default: throw new Exception("Unknown order '{$this->order}'!"); } } protected function loadPage() { $question = new PonderQuestion(); $conn_r = $question->establishConnection('r'); $data = queryfx_all( $conn_r, 'SELECT q.* FROM %T q %Q %Q %Q %Q', $question->getTableName(), $this->buildJoinsClause($conn_r), $this->buildWhereClause($conn_r), $this->buildOrderByClause($conn_r), $this->buildLimitClause($conn_r)); return $question->loadAllFromArray($data); } private function buildJoinsClause(AphrontDatabaseConnection $conn_r) { $joins = array(); if ($this->answererPHIDs) { $answer_table = new PonderAnswer(); $joins[] = qsprintf( $conn_r, 'JOIN %T a ON a.questionID = q.id AND a.authorPHID IN (%Ls)', $answer_table->getTableName(), $this->answererPHIDs); } return implode(' ', $joins); } }