diff --git a/src/applications/ponder/controller/PonderAnswerCommentController.php b/src/applications/ponder/controller/PonderAnswerCommentController.php index 711908c6ed..5531177586 100644 --- a/src/applications/ponder/controller/PonderAnswerCommentController.php +++ b/src/applications/ponder/controller/PonderAnswerCommentController.php @@ -1,70 +1,64 @@ id = $data['id']; - } - - public function processRequest() { - $request = $this->getRequest(); - $viewer = $request->getUser(); + public function handleRequest(AphrontRequest $request) { + $viewer = $request->getViewer(); + $id = $request->getURIData('id'); if (!$request->isFormPost()) { return new Aphront400Response(); } $answer = id(new PonderAnswerQuery()) ->setViewer($viewer) - ->withIDs(array($this->id)) + ->withIDs(array($id)) ->executeOne(); if (!$answer) { return new Aphront404Response(); } $is_preview = $request->isPreviewRequest(); // $draft = PhabricatorDraft::buildFromRequest($request); $qid = $answer->getQuestion()->getID(); $aid = $answer->getID(); $view_uri = "/Q{$qid}#A{$aid}"; $xactions = array(); $xactions[] = id(new PonderAnswerTransaction()) ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) ->attachComment( id(new PonderAnswerTransactionComment()) ->setContent($request->getStr('comment'))); $editor = id(new PonderAnswerEditor()) ->setActor($viewer) ->setContinueOnNoEffect($request->isContinueRequest()) ->setContentSourceFromRequest($request) ->setIsPreview($is_preview); try { $xactions = $editor->applyTransactions($answer, $xactions); } catch (PhabricatorApplicationTransactionNoEffectException $ex) { return id(new PhabricatorApplicationTransactionNoEffectResponse()) ->setCancelURI($view_uri) ->setException($ex); } // if ($draft) { // $draft->replaceOrDelete(); // } if ($request->isAjax() && $is_preview) { return id(new PhabricatorApplicationTransactionResponse()) ->setViewer($viewer) ->setTransactions($xactions) ->setIsPreview($is_preview); } else { return id(new AphrontRedirectResponse()) ->setURI($view_uri); } } } diff --git a/src/applications/ponder/controller/PonderAnswerEditController.php b/src/applications/ponder/controller/PonderAnswerEditController.php index 80273bb053..328eed1f91 100644 --- a/src/applications/ponder/controller/PonderAnswerEditController.php +++ b/src/applications/ponder/controller/PonderAnswerEditController.php @@ -1,110 +1,104 @@ id = $data['id']; - } - - public function processRequest() { - $request = $this->getRequest(); - $viewer = $request->getUser(); + public function handleRequest(AphrontRequest $request) { + $viewer = $request->getViewer(); + $id = $request->getURIData('id'); $answer = id(new PonderAnswerQuery()) ->setViewer($viewer) - ->withIDs(array($this->id)) + ->withIDs(array($id)) ->requireCapabilities( array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, )) ->executeOne(); if (!$answer) { return new Aphront404Response(); } $v_content = $answer->getContent(); $e_content = true; $question = $answer->getQuestion(); $qid = $question->getID(); $answer_uri = $answer->getURI(); $errors = array(); if ($request->isFormPost()) { $v_content = $request->getStr('content'); if (!strlen($v_content)) { $errors[] = pht('You must provide some substance in your answer.'); $e_content = pht('Required'); } if (!$errors) { $xactions = array(); $xactions[] = id(new PonderAnswerTransaction()) ->setTransactionType(PonderAnswerTransaction::TYPE_CONTENT) ->setNewValue($v_content); $editor = id(new PonderAnswerEditor()) ->setActor($viewer) ->setContentSourceFromRequest($request) ->setContinueOnNoEffect(true); $editor->applyTransactions($answer, $xactions); return id(new AphrontRedirectResponse()) ->setURI($answer_uri); } } $answer_content_id = celerity_generate_unique_node_id(); $form = id(new AphrontFormView()) ->setUser($viewer) ->appendChild( id(new AphrontFormStaticControl()) ->setLabel(pht('Question')) ->setValue($question->getTitle())) ->appendChild( id(new PhabricatorRemarkupControl()) ->setUser($viewer) ->setLabel(pht('Answer')) ->setName('content') ->setID($answer_content_id) ->setValue($v_content) ->setError($e_content)) ->appendChild( id(new AphrontFormSubmitControl()) ->setValue(pht('Update Answer')) ->addCancelButton($answer_uri)); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb("Q{$qid}", $answer_uri); $crumbs->addTextCrumb(pht('Edit Answer')); $form_box = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Edit Answer')) ->setFormErrors($errors) ->setForm($form); $preview = id(new PHUIRemarkupPreviewPanel()) ->setHeader(pht('Answer Preview')) ->setControlID($answer_content_id) ->setPreviewURI($this->getApplicationURI('preview/')); return $this->buildApplicationPage( array( $crumbs, $form_box, $preview, ), array( 'title' => pht('Edit Answer'), )); } } diff --git a/src/applications/ponder/controller/PonderAnswerHistoryController.php b/src/applications/ponder/controller/PonderAnswerHistoryController.php index 931c090e02..31296aeaf6 100644 --- a/src/applications/ponder/controller/PonderAnswerHistoryController.php +++ b/src/applications/ponder/controller/PonderAnswerHistoryController.php @@ -1,47 +1,41 @@ id = $data['id']; - } - - public function processRequest() { - $request = $this->getRequest(); - $viewer = $request->getUser(); + public function handleRequest(AphrontRequest $request) { + $viewer = $request->getViewer(); + $id = $request->getURIData('id'); $answer = id(new PonderAnswerQuery()) ->setViewer($viewer) - ->withIDs(array($this->id)) + ->withIDs(array($id)) ->executeOne(); if (!$answer) { return new Aphront404Response(); } $timeline = $this->buildTransactionTimeline( $answer, new PonderAnswerTransactionQuery()); $timeline->setShouldTerminate(true); $qid = $answer->getQuestion()->getID(); $aid = $answer->getID(); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb("Q{$qid}", "/Q{$qid}"); $crumbs->addTextCrumb("A{$aid}", "/Q{$qid}#{$aid}"); $crumbs->addTextCrumb(pht('History')); return $this->buildApplicationPage( array( $crumbs, $timeline, ), array( 'title' => pht('Answer History'), )); } } diff --git a/src/applications/ponder/controller/PonderAnswerSaveController.php b/src/applications/ponder/controller/PonderAnswerSaveController.php index 53e9367edd..2e2b965c3b 100644 --- a/src/applications/ponder/controller/PonderAnswerSaveController.php +++ b/src/applications/ponder/controller/PonderAnswerSaveController.php @@ -1,68 +1,67 @@ getRequest(); - $viewer = $request->getUser(); + public function handleRequest(AphrontRequest $request) { + $viewer = $request->getViewer(); if (!$request->isFormPost()) { return new Aphront400Response(); } $question_id = $request->getInt('question_id'); $question = id(new PonderQuestionQuery()) ->setViewer($viewer) ->withIDs(array($question_id)) ->needAnswers(true) ->executeOne(); if (!$question) { return new Aphront404Response(); } $answer = $request->getStr('answer'); if (!strlen(trim($answer))) { $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 = id(new PonderAnswer()) ->setAuthorPHID($viewer->getPHID()) ->setQuestionID($question->getID()) ->setContent($answer) ->setVoteCount(0) ->setContentSource($content_source); $xactions = array(); $xactions[] = id(new PonderQuestionTransaction()) ->setTransactionType(PonderQuestionTransaction::TYPE_ANSWERS) ->setNewValue( array( '+' => array( array('answer' => $res), ), )); $editor = id(new PonderQuestionEditor()) ->setActor($viewer) ->setContentSourceFromRequest($request); $editor->applyTransactions($question, $xactions); return id(new AphrontRedirectResponse())->setURI( id(new PhutilURI('/Q'.$question->getID()))); } } diff --git a/src/applications/ponder/controller/PonderQuestionCommentController.php b/src/applications/ponder/controller/PonderQuestionCommentController.php index f4d56db622..4834d8040c 100644 --- a/src/applications/ponder/controller/PonderQuestionCommentController.php +++ b/src/applications/ponder/controller/PonderQuestionCommentController.php @@ -1,69 +1,63 @@ id = $data['id']; - } - - public function processRequest() { - $request = $this->getRequest(); - $viewer = $request->getUser(); + public function handleRequest(AphrontRequest $request) { + $viewer = $request->getViewer(); + $id = $request->getURIData('id'); if (!$request->isFormPost()) { return new Aphront400Response(); } $question = id(new PonderQuestionQuery()) ->setViewer($viewer) - ->withIDs(array($this->id)) + ->withIDs(array($id)) ->executeOne(); if (!$question) { return new Aphront404Response(); } $is_preview = $request->isPreviewRequest(); // $draft = PhabricatorDraft::buildFromRequest($request); $qid = $question->getID(); $view_uri = "/Q{$qid}"; $xactions = array(); $xactions[] = id(new PonderQuestionTransaction()) ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) ->attachComment( id(new PonderQuestionTransactionComment()) ->setContent($request->getStr('comment'))); $editor = id(new PonderQuestionEditor()) ->setActor($viewer) ->setContinueOnNoEffect($request->isContinueRequest()) ->setContentSourceFromRequest($request) ->setIsPreview($is_preview); try { $xactions = $editor->applyTransactions($question, $xactions); } catch (PhabricatorApplicationTransactionNoEffectException $ex) { return id(new PhabricatorApplicationTransactionNoEffectResponse()) ->setCancelURI($view_uri) ->setException($ex); } // if ($draft) { // $draft->replaceOrDelete(); // } if ($request->isAjax() && $is_preview) { return id(new PhabricatorApplicationTransactionResponse()) ->setViewer($viewer) ->setTransactions($xactions) ->setIsPreview($is_preview); } else { return id(new AphrontRedirectResponse()) ->setURI($view_uri); } } } diff --git a/src/applications/ponder/controller/PonderQuestionEditController.php b/src/applications/ponder/controller/PonderQuestionEditController.php index 331c605eae..36c723445d 100644 --- a/src/applications/ponder/controller/PonderQuestionEditController.php +++ b/src/applications/ponder/controller/PonderQuestionEditController.php @@ -1,151 +1,145 @@ getViewer(); + $id = $request->getURIData('id'); - public function willProcessRequest(array $data) { - $this->id = idx($data, 'id'); - } - - public function processRequest() { - $request = $this->getRequest(); - $user = $request->getUser(); - - if ($this->id) { + if ($id) { $question = id(new PonderQuestionQuery()) ->setViewer($user) - ->withIDs(array($this->id)) + ->withIDs(array($id)) ->requireCapabilities( array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, )) ->executeOne(); if (!$question) { return new Aphront404Response(); } $v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs( $question->getPHID(), PhabricatorProjectObjectHasProjectEdgeType::EDGECONST); $v_projects = array_reverse($v_projects); } else { $question = id(new PonderQuestion()) ->setStatus(PonderQuestionStatus::STATUS_OPEN) ->setAuthorPHID($user->getPHID()) ->setVoteCount(0) ->setAnswerCount(0) ->setHeat(0.0); $v_projects = array(); } $v_title = $question->getTitle(); $v_content = $question->getContent(); $errors = array(); $e_title = true; if ($request->isFormPost()) { $v_title = $request->getStr('title'); $v_content = $request->getStr('content'); $v_projects = $request->getArr('projects'); $len = phutil_utf8_strlen($v_title); if ($len < 1) { $errors[] = pht('Title must not be empty.'); $e_title = pht('Required'); } else if ($len > 255) { $errors[] = pht('Title is too long.'); $e_title = pht('Too Long'); } if (!$errors) { $template = id(new PonderQuestionTransaction()); $xactions = array(); $xactions[] = id(clone $template) ->setTransactionType(PonderQuestionTransaction::TYPE_TITLE) ->setNewValue($v_title); $xactions[] = id(clone $template) ->setTransactionType(PonderQuestionTransaction::TYPE_CONTENT) ->setNewValue($v_content); $proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST; $xactions[] = id(new PonderQuestionTransaction()) ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) ->setMetadataValue('edge:type', $proj_edge_type) ->setNewValue(array('=' => array_fuse($v_projects))); $editor = id(new PonderQuestionEditor()) ->setActor($user) ->setContentSourceFromRequest($request) ->setContinueOnNoEffect(true); $editor->applyTransactions($question, $xactions); return id(new AphrontRedirectResponse()) ->setURI('/Q'.$question->getID()); } } $form = id(new AphrontFormView()) ->setUser($user) ->appendChild( id(new AphrontFormTextControl()) ->setLabel(pht('Question')) ->setName('title') ->setValue($v_title) ->setError($e_title)) ->appendChild( id(new PhabricatorRemarkupControl()) ->setUser($user) ->setName('content') ->setID('content') ->setValue($v_content) ->setLabel(pht('Description')) ->setUser($user)); $form->appendControl( id(new AphrontFormTokenizerControl()) ->setLabel(pht('Projects')) ->setName('projects') ->setValue($v_projects) ->setDatasource(new PhabricatorProjectDatasource())); $form ->appendChild( id(new AphrontFormSubmitControl()) ->addCancelButton($this->getApplicationURI()) ->setValue(pht('Ask Away!'))); $preview = id(new PHUIRemarkupPreviewPanel()) ->setHeader(pht('Question Preview')) ->setControlID('content') ->setPreviewURI($this->getApplicationURI('preview/')); $form_box = id(new PHUIObjectBoxView()) ->setHeaderText(pht('Ask New Question')) ->setFormErrors($errors) ->setForm($form); $crumbs = $this->buildApplicationCrumbs(); $id = $question->getID(); if ($id) { $crumbs->addTextCrumb("Q{$id}", "/Q{$id}"); $crumbs->addTextCrumb(pht('Edit')); } else { $crumbs->addTextCrumb(pht('Ask Question')); } return $this->buildApplicationPage( array( $crumbs, $form_box, $preview, ), array( 'title' => pht('Ask New Question'), )); } } diff --git a/src/applications/ponder/controller/PonderQuestionHistoryController.php b/src/applications/ponder/controller/PonderQuestionHistoryController.php index 253dbcc26c..3d62a7fcb6 100644 --- a/src/applications/ponder/controller/PonderQuestionHistoryController.php +++ b/src/applications/ponder/controller/PonderQuestionHistoryController.php @@ -1,44 +1,38 @@ id = $data['id']; - } - - public function processRequest() { - $request = $this->getRequest(); - $viewer = $request->getUser(); + public function handleRequest(AphrontRequest $request) { + $viewer = $request->getViewer(); + $id = $request->getURIData('id'); $question = id(new PonderQuestionQuery()) ->setViewer($viewer) - ->withIDs(array($this->id)) + ->withIDs(array($id)) ->executeOne(); if (!$question) { return new Aphront404Response(); } $timeline = $this->buildTransactionTimeline( $question, new PonderQuestionTransactionQuery()); $timeline->setShouldTerminate(true); $qid = $question->getID(); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb("Q{$qid}", "/Q{$qid}"); $crumbs->addTextCrumb(pht('History')); return $this->buildApplicationPage( array( $crumbs, $timeline, ), array( 'title' => pht('Question History'), )); } } diff --git a/src/applications/ponder/controller/PonderQuestionListController.php b/src/applications/ponder/controller/PonderQuestionListController.php index bf6329241c..f7953cd737 100644 --- a/src/applications/ponder/controller/PonderQuestionListController.php +++ b/src/applications/ponder/controller/PonderQuestionListController.php @@ -1,24 +1,20 @@ queryKey = idx($data, 'queryKey'); - } + public function handleRequest(AphrontRequest $request) { + $query_key = $request->getURIData('queryKey'); - public function processRequest() { $controller = id(new PhabricatorApplicationSearchController()) - ->setQueryKey($this->queryKey) + ->setQueryKey($query_key) ->setSearchEngine(new PonderQuestionSearchEngine()) ->setNavigation($this->buildSideNavView()); return $this->delegateToController($controller); } } diff --git a/src/applications/ponder/controller/PonderQuestionStatusController.php b/src/applications/ponder/controller/PonderQuestionStatusController.php index 99473ce3cf..db2d971c92 100644 --- a/src/applications/ponder/controller/PonderQuestionStatusController.php +++ b/src/applications/ponder/controller/PonderQuestionStatusController.php @@ -1,56 +1,49 @@ status = idx($data, 'status'); - $this->id = idx($data, 'id'); - } - - public function processRequest() { - $request = $this->getRequest(); - $viewer = $request->getUser(); + public function handleRequest(AphrontRequest $request) { + $viewer = $request->getViewer(); + $id = $request->getURIData('id'); + $status = $request->getURIData('status'); $question = id(new PonderQuestionQuery()) ->setViewer($viewer) - ->withIDs(array($this->id)) + ->withIDs(array($id)) ->requireCapabilities( array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, )) ->executeOne(); if (!$question) { return new Aphront404Response(); } - switch ($this->status) { + switch ($status) { case 'open': $status = PonderQuestionStatus::STATUS_OPEN; break; case 'close': $status = PonderQuestionStatus::STATUS_CLOSED; break; default: return new Aphront400Response(); } $xactions = array(); $xactions[] = id(new PonderQuestionTransaction()) ->setTransactionType(PonderQuestionTransaction::TYPE_STATUS) ->setNewValue($status); $editor = id(new PonderQuestionEditor()) ->setActor($viewer) ->setContentSourceFromRequest($request); $editor->applyTransactions($question, $xactions); return id(new AphrontRedirectResponse())->setURI('/Q'.$question->getID()); } } diff --git a/src/applications/ponder/controller/PonderQuestionViewController.php b/src/applications/ponder/controller/PonderQuestionViewController.php index 21f4627636..d2b5a53826 100644 --- a/src/applications/ponder/controller/PonderQuestionViewController.php +++ b/src/applications/ponder/controller/PonderQuestionViewController.php @@ -1,405 +1,398 @@ questionID = $data['id']; - } - - public function processRequest() { - - $request = $this->getRequest(); - $user = $request->getUser(); + public function handleRequest(AphrontRequest $request) { + $user = $request->getViewer(); + $id = $request->getURIData('id'); $question = id(new PonderQuestionQuery()) ->setViewer($user) - ->withIDs(array($this->questionID)) + ->withIDs(array($id)) ->needAnswers(true) ->needViewerVotes(true) ->executeOne(); if (!$question) { return new Aphront404Response(); } $question->attachVotes($user->getPHID()); $question_xactions = $this->buildQuestionTransactions($question); $answers = $this->buildAnswers($question->getAnswers()); $authors = mpull($question->getAnswers(), null, 'getAuthorPHID'); if (isset($authors[$user->getPHID()])) { $answer_add_panel = id(new PHUIInfoView()) ->setSeverity(PHUIInfoView::SEVERITY_NODATA) ->appendChild( pht( 'You have already answered this question. You can not answer '. 'twice, but you can edit your existing answer.')); } else { $answer_add_panel = new PonderAddAnswerView(); $answer_add_panel ->setQuestion($question) ->setUser($user) ->setActionURI('/ponder/answer/add/'); } $header = id(new PHUIHeaderView()) ->setHeader($question->getTitle()); if ($question->getStatus() == PonderQuestionStatus::STATUS_OPEN) { $header->setStatus('fa-square-o', 'bluegrey', pht('Open')); } else { $header->setStatus('fa-check-square-o', 'dark', pht('Closed')); } $actions = $this->buildActionListView($question); $properties = $this->buildPropertyListView($question, $actions); $object_box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView()); - $crumbs->addTextCrumb('Q'.$this->questionID, '/Q'.$this->questionID); + $crumbs->addTextCrumb('Q'.$id, '/Q'.$id); return $this->buildApplicationPage( array( $crumbs, $object_box, $question_xactions, $answers, $answer_add_panel, ), array( 'title' => 'Q'.$question->getID().' '.$question->getTitle(), 'pageObjects' => array_merge( array($question->getPHID()), mpull($question->getAnswers(), 'getPHID')), )); } 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('fa-pencil') ->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 = 'fa-check-square-o'; $href = 'close'; } else { $name = pht('Reopen Question'); $icon = 'fa-square-o'; $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}/"))); $view->addAction( id(new PhabricatorActionView()) ->setIcon('fa-list') ->setName(pht('View History')) ->setHref($this->getApplicationURI("/question/history/{$id}/"))); return $view; } private function buildPropertyListView( PonderQuestion $question, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($question) ->setActionList($actions); $view->addProperty( pht('Status'), PonderQuestionStatus::getQuestionStatusFullName($question->getStatus())); $view->addProperty( pht('Author'), $viewer->renderHandle($question->getAuthorPHID())); $view->addProperty( pht('Created'), phabricator_datetime($question->getDateCreated(), $viewer)); $view->invokeWillRenderEvent(); $votable = id(new PonderVotableView()) ->setPHID($question->getPHID()) ->setURI($this->getApplicationURI('vote/')) ->setCount($question->getVoteCount()) ->setVote($question->getUserVote()); $view->addSectionHeader(pht('Question')); $view->addTextContent( array( $votable, phutil_tag( 'div', array( 'class' => 'phabricator-remarkup', ), PhabricatorMarkupEngine::renderOneObject( $question, $question->getMarkupField(), $viewer)), )); return $view; } private function buildQuestionTransactions(PonderQuestion $question) { $viewer = $this->getViewer(); $id = $question->getID(); $timeline = $this->buildTransactionTimeline( $question, id(new PonderQuestionTransactionQuery()) ->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT))); $xactions = $timeline->getTransactions(); $add_comment = id(new PhabricatorApplicationTransactionCommentView()) ->setUser($viewer) ->setObjectPHID($question->getPHID()) ->setShowPreview(false) ->setHeaderText(pht('Question Comment')) ->setAction($this->getApplicationURI("/question/comment/{$id}/")) ->setSubmitButtonName(pht('Comment')); return $this->wrapComments( count($xactions), array( $timeline, $add_comment, )); } /** * This is fairly non-standard; building N timelines at once (N = number of * answers) is tricky business. * * TODO - re-factor this to ajax in one answer panel at a time in a more * standard fashion. This is necessary to scale this application. */ private function buildAnswers(array $answers) { $request = $this->getRequest(); $viewer = $request->getUser(); $out = array(); $xactions = id(new PonderAnswerTransactionQuery()) ->setViewer($viewer) ->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT)) ->withObjectPHIDs(mpull($answers, '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(); $xaction_groups = mgroup($xactions, 'getObjectPHID'); foreach ($answers as $answer) { $author_phid = $answer->getAuthorPHID(); $xactions = idx($xaction_groups, $answer->getPHID(), array()); $id = $answer->getID(); $out[] = phutil_tag('br'); $out[] = phutil_tag('br'); $out[] = id(new PhabricatorAnchorView()) ->setAnchorName("A$id"); $header = id(new PHUIHeaderView()) ->setHeader($viewer->renderHandle($author_phid)); $actions = $this->buildAnswerActions($answer); $properties = $this->buildAnswerProperties($answer, $actions); $object_box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); $out[] = $object_box; $details = array(); $details[] = id(new PhabricatorApplicationTransactionView()) ->setUser($viewer) ->setObjectPHID($answer->getPHID()) ->setTransactions($xactions) ->setMarkupEngine($engine); $form = id(new PhabricatorApplicationTransactionCommentView()) ->setUser($viewer) ->setObjectPHID($answer->getPHID()) ->setShowPreview(false) ->setHeaderText(pht('Answer Comment')) ->setAction($this->getApplicationURI("/answer/comment/{$id}/")) ->setSubmitButtonName(pht('Comment')); $details[] = $form; $out[] = $this->wrapComments( count($xactions), $details); } $out[] = phutil_tag('br'); $out[] = phutil_tag('br'); return $out; } private function buildAnswerActions(PonderAnswer $answer) { $request = $this->getRequest(); $viewer = $request->getUser(); $id = $answer->getID(); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $answer, PhabricatorPolicyCapability::CAN_EDIT); $view = id(new PhabricatorActionListView()) ->setUser($request->getUser()) ->setObject($answer) ->setObjectURI($request->getRequestURI()); $view->addAction( id(new PhabricatorActionView()) ->setIcon('fa-pencil') ->setName(pht('Edit Answer')) ->setHref($this->getApplicationURI("/answer/edit/{$id}/")) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); $view->addAction( id(new PhabricatorActionView()) ->setIcon('fa-list') ->setName(pht('View History')) ->setHref($this->getApplicationURI("/answer/history/{$id}/"))); return $view; } private function buildAnswerProperties( PonderAnswer $answer, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $view = id(new PHUIPropertyListView()) ->setUser($viewer) ->setObject($answer) ->setActionList($actions); $view->addProperty( pht('Created'), phabricator_datetime($answer->getDateCreated(), $viewer)); $view->invokeWillRenderEvent(); $votable = id(new PonderVotableView()) ->setPHID($answer->getPHID()) ->setURI($this->getApplicationURI('vote/')) ->setCount($answer->getVoteCount()) ->setVote($answer->getUserVote()); $view->addSectionHeader(pht('Answer')); $view->addTextContent( array( $votable, phutil_tag( 'div', array( 'class' => 'phabricator-remarkup', ), PhabricatorMarkupEngine::renderOneObject( $answer, $answer->getMarkupField(), $viewer)), )); return $view; } private function wrapComments($n, $stuff) { if ($n == 0) { $text = pht('Add a Comment'); } else { $text = pht('Show %s Comments', new PhutilNumber($n)); } $show_id = celerity_generate_unique_node_id(); $hide_id = celerity_generate_unique_node_id(); Javelin::initBehavior('phabricator-reveal-content'); require_celerity_resource('ponder-comment-table-css'); $show = phutil_tag( 'div', array( 'id' => $show_id, 'class' => 'ponder-show-comments', ), javelin_tag( 'a', array( 'href' => '#', 'sigil' => 'reveal-content', 'meta' => array( 'showIDs' => array($hide_id), 'hideIDs' => array($show_id), ), ), $text)); $hide = phutil_tag( 'div', array( 'id' => $hide_id, 'style' => 'display: none', ), $stuff); return array($show, $hide); } } diff --git a/src/applications/ponder/controller/PonderVoteSaveController.php b/src/applications/ponder/controller/PonderVoteSaveController.php index 8b5dd39505..12aa4dfb15 100644 --- a/src/applications/ponder/controller/PonderVoteSaveController.php +++ b/src/applications/ponder/controller/PonderVoteSaveController.php @@ -1,33 +1,32 @@ getRequest(); - $viewer = $request->getUser(); + public function handleRequest(AphrontRequest $request) { + $viewer = $request->getViewer(); $phid = $request->getStr('phid'); $newvote = $request->getInt('vote'); if (1 < $newvote || $newvote < -1) { return new Aphront400Response(); } $target = null; $object = id(new PhabricatorObjectQuery()) ->setViewer($viewer) ->withPHIDs(array($phid)) ->executeOne(); if (!$object) { return new Aphront404Response(); } $editor = id(new PonderVoteEditor()) ->setVotable($object) ->setActor($viewer) ->setVote($newvote) ->saveVote(); return id(new AphrontAjaxResponse())->setContent(array()); } }