Changeset View
Changeset View
Standalone View
Standalone View
src/applications/ponder/controller/PonderQuestionViewController.php
<?php | <?php | ||||
final class PonderQuestionViewController extends PonderController { | final class PonderQuestionViewController extends PonderController { | ||||
public function handleRequest(AphrontRequest $request) { | public function handleRequest(AphrontRequest $request) { | ||||
$user = $request->getViewer(); | $viewer = $request->getViewer(); | ||||
$id = $request->getURIData('id'); | $id = $request->getURIData('id'); | ||||
$question = id(new PonderQuestionQuery()) | $question = id(new PonderQuestionQuery()) | ||||
->setViewer($user) | ->setViewer($viewer) | ||||
->withIDs(array($id)) | ->withIDs(array($id)) | ||||
->needAnswers(true) | ->needAnswers(true) | ||||
->needViewerVotes(true) | ->needViewerVotes(true) | ||||
->executeOne(); | ->executeOne(); | ||||
if (!$question) { | if (!$question) { | ||||
return new Aphront404Response(); | return new Aphront404Response(); | ||||
} | } | ||||
$question->attachVotes($user->getPHID()); | $question->attachVotes($viewer->getPHID()); | ||||
$question_xactions = $this->buildQuestionTransactions($question); | $question_xactions = $this->buildQuestionTransactions($question); | ||||
$answers = $this->buildAnswers($question->getAnswers()); | $answers = $this->buildAnswers($question->getAnswers()); | ||||
$authors = mpull($question->getAnswers(), null, 'getAuthorPHID'); | $authors = mpull($question->getAnswers(), null, 'getAuthorPHID'); | ||||
if (isset($authors[$user->getPHID()])) { | if (isset($authors[$viewer->getPHID()])) { | ||||
$answer_add_panel = id(new PHUIInfoView()) | $answer_add_panel = id(new PHUIInfoView()) | ||||
->setSeverity(PHUIInfoView::SEVERITY_NODATA) | ->setSeverity(PHUIInfoView::SEVERITY_NOTICE) | ||||
->appendChild( | ->appendChild( | ||||
pht( | pht( | ||||
'You have already answered this question. You can not answer '. | 'You have already answered this question. You can not answer '. | ||||
'twice, but you can edit your existing answer.')); | 'twice, but you can edit your existing answer.')); | ||||
} else { | } else { | ||||
$answer_add_panel = new PonderAddAnswerView(); | $answer_add_panel = new PonderAddAnswerView(); | ||||
$answer_add_panel | $answer_add_panel | ||||
->setQuestion($question) | ->setQuestion($question) | ||||
->setUser($user) | ->setUser($viewer) | ||||
->setActionURI('/ponder/answer/add/'); | ->setActionURI('/ponder/answer/add/'); | ||||
} | } | ||||
$header = id(new PHUIHeaderView()) | $header = new PHUIHeaderView(); | ||||
->setHeader($question->getTitle()) | $header->setHeader($question->getTitle()); | ||||
->setUser($user) | $header->setUser($viewer); | ||||
->setPolicyObject($question); | $header->setPolicyObject($question); | ||||
if ($question->getStatus() == PonderQuestionStatus::STATUS_OPEN) { | if ($question->getStatus() == PonderQuestionStatus::STATUS_OPEN) { | ||||
$header->setStatus('fa-square-o', 'bluegrey', pht('Open')); | $header->setStatus('fa-square-o', 'bluegrey', pht('Open')); | ||||
} else { | } else { | ||||
$header->setStatus('fa-check-square-o', 'dark', pht('Closed')); | $header->setStatus('fa-check-square-o', 'dark', pht('Closed')); | ||||
} | } | ||||
$actions = $this->buildActionListView($question); | $actions = $this->buildActionListView($question); | ||||
$properties = $this->buildPropertyListView($question, $actions); | $properties = $this->buildPropertyListView($question, $actions); | ||||
$object_box = id(new PHUIObjectBoxView()) | $object_box = id(new PHUIObjectBoxView()) | ||||
->setHeader($header) | ->setHeader($header) | ||||
->addPropertyList($properties); | ->addPropertyList($properties); | ||||
$crumbs = $this->buildApplicationCrumbs($this->buildSideNavView()); | $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView()); | ||||
$crumbs->addTextCrumb('Q'.$id, '/Q'.$id); | $crumbs->addTextCrumb('Q'.$id, '/Q'.$id); | ||||
return $this->buildApplicationPage( | $ponder_view = phutil_tag( | ||||
'div', | |||||
array( | |||||
'class' => 'ponder-question-view', | |||||
), | |||||
array( | array( | ||||
$crumbs, | $crumbs, | ||||
$object_box, | $object_box, | ||||
$question_xactions, | $question_xactions, | ||||
$answers, | $answers, | ||||
$answer_add_panel, | $answer_add_panel, | ||||
)); | |||||
return $this->buildApplicationPage( | |||||
array( | |||||
$ponder_view, | |||||
), | ), | ||||
array( | array( | ||||
'title' => 'Q'.$question->getID().' '.$question->getTitle(), | 'title' => 'Q'.$question->getID().' '.$question->getTitle(), | ||||
'pageObjects' => array_merge( | 'pageObjects' => array_merge( | ||||
array($question->getPHID()), | array($question->getPHID()), | ||||
mpull($question->getAnswers(), 'getPHID')), | mpull($question->getAnswers(), 'getPHID')), | ||||
)); | )); | ||||
} | } | ||||
private function buildActionListView(PonderQuestion $question) { | private function buildActionListView(PonderQuestion $question) { | ||||
$viewer = $this->getViewer(); | |||||
$request = $this->getRequest(); | $request = $this->getRequest(); | ||||
$viewer = $request->getUser(); | |||||
$id = $question->getID(); | $id = $question->getID(); | ||||
$can_edit = PhabricatorPolicyFilter::hasCapability( | $can_edit = PhabricatorPolicyFilter::hasCapability( | ||||
$viewer, | $viewer, | ||||
$question, | $question, | ||||
PhabricatorPolicyCapability::CAN_EDIT); | PhabricatorPolicyCapability::CAN_EDIT); | ||||
$view = id(new PhabricatorActionListView()) | $view = id(new PhabricatorActionListView()) | ||||
->setUser($request->getUser()) | ->setUser($viewer) | ||||
->setObject($question) | ->setObject($question) | ||||
->setObjectURI($request->getRequestURI()); | ->setObjectURI($request->getRequestURI()); | ||||
$view->addAction( | $view->addAction( | ||||
id(new PhabricatorActionView()) | id(new PhabricatorActionView()) | ||||
->setIcon('fa-pencil') | ->setIcon('fa-pencil') | ||||
->setName(pht('Edit Question')) | ->setName(pht('Edit Question')) | ||||
->setHref($this->getApplicationURI("/question/edit/{$id}/")) | ->setHref($this->getApplicationURI("/question/edit/{$id}/")) | ||||
Show All 27 Lines | private function buildActionListView(PonderQuestion $question) { | ||||
return $view; | return $view; | ||||
} | } | ||||
private function buildPropertyListView( | private function buildPropertyListView( | ||||
PonderQuestion $question, | PonderQuestion $question, | ||||
PhabricatorActionListView $actions) { | PhabricatorActionListView $actions) { | ||||
$viewer = $this->getRequest()->getUser(); | $viewer = $this->getViewer(); | ||||
$view = id(new PHUIPropertyListView()) | $view = id(new PHUIPropertyListView()) | ||||
->setUser($viewer) | ->setUser($viewer) | ||||
->setObject($question) | ->setObject($question) | ||||
->setActionList($actions); | ->setActionList($actions); | ||||
$view->addProperty( | $view->addProperty( | ||||
pht('Status'), | |||||
PonderQuestionStatus::getQuestionStatusFullName($question->getStatus())); | |||||
$view->addProperty( | |||||
pht('Author'), | pht('Author'), | ||||
$viewer->renderHandle($question->getAuthorPHID())); | $viewer->renderHandle($question->getAuthorPHID())); | ||||
$view->addProperty( | $view->addProperty( | ||||
pht('Created'), | pht('Created'), | ||||
phabricator_datetime($question->getDateCreated(), $viewer)); | phabricator_datetime($question->getDateCreated(), $viewer)); | ||||
$view->invokeWillRenderEvent(); | $view->invokeWillRenderEvent(); | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | final class PonderQuestionViewController extends PonderController { | ||||
/** | /** | ||||
* This is fairly non-standard; building N timelines at once (N = number of | * This is fairly non-standard; building N timelines at once (N = number of | ||||
* answers) is tricky business. | * answers) is tricky business. | ||||
* | * | ||||
* TODO - re-factor this to ajax in one answer panel at a time in a more | * 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. | * standard fashion. This is necessary to scale this application. | ||||
*/ | */ | ||||
private function buildAnswers(array $answers) { | private function buildAnswers(array $answers) { | ||||
$request = $this->getRequest(); | $viewer = $this->getViewer(); | ||||
$viewer = $request->getUser(); | |||||
$out = array(); | $out = array(); | ||||
$xactions = id(new PonderAnswerTransactionQuery()) | $xactions = id(new PonderAnswerTransactionQuery()) | ||||
->setViewer($viewer) | ->setViewer($viewer) | ||||
->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT)) | ->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT)) | ||||
->withObjectPHIDs(mpull($answers, 'getPHID')) | ->withObjectPHIDs(mpull($answers, 'getPHID')) | ||||
->execute(); | ->execute(); | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | private function buildAnswers(array $answers) { | ||||
$out[] = phutil_tag('br'); | $out[] = phutil_tag('br'); | ||||
$out[] = phutil_tag('br'); | $out[] = phutil_tag('br'); | ||||
return $out; | return $out; | ||||
} | } | ||||
private function buildAnswerActions(PonderAnswer $answer) { | private function buildAnswerActions(PonderAnswer $answer) { | ||||
$viewer = $this->getViewer(); | |||||
$request = $this->getRequest(); | $request = $this->getRequest(); | ||||
$viewer = $request->getUser(); | |||||
$id = $answer->getID(); | $id = $answer->getID(); | ||||
$can_edit = PhabricatorPolicyFilter::hasCapability( | $can_edit = PhabricatorPolicyFilter::hasCapability( | ||||
$viewer, | $viewer, | ||||
$answer, | $answer, | ||||
PhabricatorPolicyCapability::CAN_EDIT); | PhabricatorPolicyCapability::CAN_EDIT); | ||||
$view = id(new PhabricatorActionListView()) | $view = id(new PhabricatorActionListView()) | ||||
->setUser($request->getUser()) | ->setUser($viewer) | ||||
->setObject($answer) | ->setObject($answer) | ||||
->setObjectURI($request->getRequestURI()); | ->setObjectURI($request->getRequestURI()); | ||||
$view->addAction( | $view->addAction( | ||||
id(new PhabricatorActionView()) | id(new PhabricatorActionView()) | ||||
->setIcon('fa-pencil') | ->setIcon('fa-pencil') | ||||
->setName(pht('Edit Answer')) | ->setName(pht('Edit Answer')) | ||||
->setHref($this->getApplicationURI("/answer/edit/{$id}/")) | ->setHref($this->getApplicationURI("/answer/edit/{$id}/")) | ||||
->setDisabled(!$can_edit) | ->setDisabled(!$can_edit) | ||||
->setWorkflow(!$can_edit)); | ->setWorkflow(!$can_edit)); | ||||
$view->addAction( | $view->addAction( | ||||
id(new PhabricatorActionView()) | id(new PhabricatorActionView()) | ||||
->setIcon('fa-list') | ->setIcon('fa-list') | ||||
->setName(pht('View History')) | ->setName(pht('View History')) | ||||
->setHref($this->getApplicationURI("/answer/history/{$id}/"))); | ->setHref($this->getApplicationURI("/answer/history/{$id}/"))); | ||||
return $view; | return $view; | ||||
} | } | ||||
private function buildAnswerProperties( | private function buildAnswerProperties( | ||||
PonderAnswer $answer, | PonderAnswer $answer, | ||||
PhabricatorActionListView $actions) { | PhabricatorActionListView $actions) { | ||||
$viewer = $this->getRequest()->getUser(); | $viewer = $this->getViewer(); | ||||
$view = id(new PHUIPropertyListView()) | $view = id(new PHUIPropertyListView()) | ||||
->setUser($viewer) | ->setUser($viewer) | ||||
->setObject($answer) | ->setObject($answer) | ||||
->setActionList($actions); | ->setActionList($actions); | ||||
$view->addProperty( | $view->addProperty( | ||||
pht('Created'), | pht('Created'), | ||||
phabricator_datetime($answer->getDateCreated(), $viewer)); | phabricator_datetime($answer->getDateCreated(), $viewer)); | ||||
Show All 30 Lines | private function wrapComments($n, $stuff) { | ||||
} else { | } else { | ||||
$text = pht('Show %s Comments', new PhutilNumber($n)); | $text = pht('Show %s Comments', new PhutilNumber($n)); | ||||
} | } | ||||
$show_id = celerity_generate_unique_node_id(); | $show_id = celerity_generate_unique_node_id(); | ||||
$hide_id = celerity_generate_unique_node_id(); | $hide_id = celerity_generate_unique_node_id(); | ||||
Javelin::initBehavior('phabricator-reveal-content'); | Javelin::initBehavior('phabricator-reveal-content'); | ||||
require_celerity_resource('ponder-comment-table-css'); | require_celerity_resource('ponder-view-css'); | ||||
$show = phutil_tag( | $show = phutil_tag( | ||||
'div', | 'div', | ||||
array( | array( | ||||
'id' => $show_id, | 'id' => $show_id, | ||||
'class' => 'ponder-show-comments', | 'class' => 'ponder-show-comments', | ||||
), | ), | ||||
javelin_tag( | javelin_tag( | ||||
'a', | 'a', | ||||
array( | array( | ||||
'href' => '#', | 'href' => '#', | ||||
'sigil' => 'reveal-content', | 'sigil' => 'reveal-content', | ||||
'meta' => array( | 'meta' => array( | ||||
'showIDs' => array($hide_id), | 'showIDs' => array($hide_id), | ||||
'hideIDs' => array($show_id), | 'hideIDs' => array($show_id), | ||||
), | ), | ||||
), | ), | ||||
$text)); | $text)); | ||||
$hide = phutil_tag( | $hide = phutil_tag( | ||||
'div', | 'div', | ||||
array( | array( | ||||
'class' => 'ponder-comments-view', | |||||
'id' => $hide_id, | 'id' => $hide_id, | ||||
'style' => 'display: none', | 'style' => 'display: none', | ||||
), | ), | ||||
$stuff); | $stuff); | ||||
return array($show, $hide); | return array($show, $hide); | ||||
} | } | ||||
} | } |