[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class PonderQuestionViewController extends PonderController { 4 5 private $questionID; 6 7 public function willProcessRequest(array $data) { 8 $this->questionID = $data['id']; 9 } 10 11 public function processRequest() { 12 13 $request = $this->getRequest(); 14 $user = $request->getUser(); 15 16 $question = id(new PonderQuestionQuery()) 17 ->setViewer($user) 18 ->withIDs(array($this->questionID)) 19 ->needAnswers(true) 20 ->needViewerVotes(true) 21 ->executeOne(); 22 if (!$question) { 23 return new Aphront404Response(); 24 } 25 26 $question->attachVotes($user->getPHID()); 27 28 $question_xactions = $this->buildQuestionTransactions($question); 29 $answers = $this->buildAnswers($question->getAnswers()); 30 31 $authors = mpull($question->getAnswers(), null, 'getAuthorPHID'); 32 if (isset($authors[$user->getPHID()])) { 33 $answer_add_panel = id(new AphrontErrorView()) 34 ->setSeverity(AphrontErrorView::SEVERITY_NODATA) 35 ->appendChild( 36 pht( 37 'You have already answered this question. You can not answer '. 38 'twice, but you can edit your existing answer.')); 39 } else { 40 $answer_add_panel = new PonderAddAnswerView(); 41 $answer_add_panel 42 ->setQuestion($question) 43 ->setUser($user) 44 ->setActionURI('/ponder/answer/add/'); 45 } 46 47 $header = id(new PHUIHeaderView()) 48 ->setHeader($question->getTitle()); 49 50 $actions = $this->buildActionListView($question); 51 $properties = $this->buildPropertyListView($question, $actions); 52 53 $object_box = id(new PHUIObjectBoxView()) 54 ->setHeader($header) 55 ->addPropertyList($properties); 56 57 $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView()); 58 $crumbs->setActionList($actions); 59 $crumbs->addTextCrumb('Q'.$this->questionID, '/Q'.$this->questionID); 60 61 return $this->buildApplicationPage( 62 array( 63 $crumbs, 64 $object_box, 65 $question_xactions, 66 $answers, 67 $answer_add_panel, 68 ), 69 array( 70 'title' => 'Q'.$question->getID().' '.$question->getTitle(), 71 'pageObjects' => array_merge( 72 array($question->getPHID()), 73 mpull($question->getAnswers(), 'getPHID')), 74 )); 75 } 76 77 private function buildActionListView(PonderQuestion $question) { 78 $request = $this->getRequest(); 79 $viewer = $request->getUser(); 80 81 $id = $question->getID(); 82 83 $can_edit = PhabricatorPolicyFilter::hasCapability( 84 $viewer, 85 $question, 86 PhabricatorPolicyCapability::CAN_EDIT); 87 88 $view = id(new PhabricatorActionListView()) 89 ->setUser($request->getUser()) 90 ->setObject($question) 91 ->setObjectURI($request->getRequestURI()); 92 93 $view->addAction( 94 id(new PhabricatorActionView()) 95 ->setIcon('fa-pencil') 96 ->setName(pht('Edit Question')) 97 ->setHref($this->getApplicationURI("/question/edit/{$id}/")) 98 ->setDisabled(!$can_edit) 99 ->setWorkflow(!$can_edit)); 100 101 if ($question->getStatus() == PonderQuestionStatus::STATUS_OPEN) { 102 $name = pht('Close Question'); 103 $icon = 'fa-times'; 104 $href = 'close'; 105 } else { 106 $name = pht('Reopen Question'); 107 $icon = 'fa-check-circle-o'; 108 $href = 'open'; 109 } 110 111 $view->addAction( 112 id(new PhabricatorActionView()) 113 ->setName($name) 114 ->setIcon($icon) 115 ->setRenderAsForm($can_edit) 116 ->setWorkflow(!$can_edit) 117 ->setDisabled(!$can_edit) 118 ->setHref($this->getApplicationURI("/question/{$href}/{$id}/"))); 119 120 $view->addAction( 121 id(new PhabricatorActionView()) 122 ->setIcon('fa-list') 123 ->setName(pht('View History')) 124 ->setHref($this->getApplicationURI("/question/history/{$id}/"))); 125 126 return $view; 127 } 128 129 private function buildPropertyListView( 130 PonderQuestion $question, 131 PhabricatorActionListView $actions) { 132 133 $viewer = $this->getRequest()->getUser(); 134 $view = id(new PHUIPropertyListView()) 135 ->setUser($viewer) 136 ->setObject($question) 137 ->setActionList($actions); 138 139 $this->loadHandles(array($question->getAuthorPHID())); 140 141 $view->addProperty( 142 pht('Status'), 143 PonderQuestionStatus::getQuestionStatusFullName($question->getStatus())); 144 145 $view->addProperty( 146 pht('Author'), 147 $this->getHandle($question->getAuthorPHID())->renderLink()); 148 149 $view->addProperty( 150 pht('Created'), 151 phabricator_datetime($question->getDateCreated(), $viewer)); 152 153 $view->invokeWillRenderEvent(); 154 155 $votable = id(new PonderVotableView()) 156 ->setPHID($question->getPHID()) 157 ->setURI($this->getApplicationURI('vote/')) 158 ->setCount($question->getVoteCount()) 159 ->setVote($question->getUserVote()); 160 161 $view->addSectionHeader(pht('Question')); 162 $view->addTextContent( 163 array( 164 $votable, 165 phutil_tag( 166 'div', 167 array( 168 'class' => 'phabricator-remarkup', 169 ), 170 PhabricatorMarkupEngine::renderOneObject( 171 $question, 172 $question->getMarkupField(), 173 $viewer)), 174 )); 175 176 177 return $view; 178 } 179 180 private function buildQuestionTransactions(PonderQuestion $question) { 181 $viewer = $this->getRequest()->getUser(); 182 $id = $question->getID(); 183 184 $xactions = id(new PonderQuestionTransactionQuery()) 185 ->setViewer($viewer) 186 ->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT)) 187 ->withObjectPHIDs(array($question->getPHID())) 188 ->execute(); 189 190 $engine = id(new PhabricatorMarkupEngine()) 191 ->setViewer($viewer); 192 foreach ($xactions as $xaction) { 193 if ($xaction->getComment()) { 194 $engine->addObject( 195 $xaction->getComment(), 196 PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); 197 } 198 } 199 $engine->process(); 200 201 $timeline = id(new PhabricatorApplicationTransactionView()) 202 ->setUser($viewer) 203 ->setObjectPHID($question->getPHID()) 204 ->setTransactions($xactions) 205 ->setMarkupEngine($engine); 206 207 $add_comment = id(new PhabricatorApplicationTransactionCommentView()) 208 ->setUser($viewer) 209 ->setObjectPHID($question->getPHID()) 210 ->setShowPreview(false) 211 ->setHeaderText(pht('Question Comment')) 212 ->setAction($this->getApplicationURI("/question/comment/{$id}/")) 213 ->setSubmitButtonName(pht('Comment')); 214 215 return $this->wrapComments( 216 count($xactions), 217 array( 218 $timeline, 219 $add_comment, 220 )); 221 } 222 223 private function buildAnswers(array $answers) { 224 $request = $this->getRequest(); 225 $viewer = $request->getUser(); 226 227 $out = array(); 228 229 $phids = mpull($answers, 'getAuthorPHID'); 230 $this->loadHandles($phids); 231 232 $xactions = id(new PonderAnswerTransactionQuery()) 233 ->setViewer($viewer) 234 ->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT)) 235 ->withObjectPHIDs(mpull($answers, 'getPHID')) 236 ->execute(); 237 238 $engine = id(new PhabricatorMarkupEngine()) 239 ->setViewer($viewer); 240 foreach ($xactions as $xaction) { 241 if ($xaction->getComment()) { 242 $engine->addObject( 243 $xaction->getComment(), 244 PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); 245 } 246 } 247 $engine->process(); 248 249 $xaction_groups = mgroup($xactions, 'getObjectPHID'); 250 251 foreach ($answers as $answer) { 252 $author_phid = $answer->getAuthorPHID(); 253 $xactions = idx($xaction_groups, $answer->getPHID(), array()); 254 $id = $answer->getID(); 255 256 $out[] = phutil_tag('br'); 257 $out[] = phutil_tag('br'); 258 $out[] = id(new PhabricatorAnchorView()) 259 ->setAnchorName("A$id"); 260 $header = id(new PHUIHeaderView()) 261 ->setHeader($this->getHandle($author_phid)->getFullName()); 262 263 $actions = $this->buildAnswerActions($answer); 264 $properties = $this->buildAnswerProperties($answer, $actions); 265 266 $object_box = id(new PHUIObjectBoxView()) 267 ->setHeader($header) 268 ->addPropertyList($properties); 269 270 $out[] = $object_box; 271 $details = array(); 272 273 $details[] = id(new PhabricatorApplicationTransactionView()) 274 ->setUser($viewer) 275 ->setObjectPHID($answer->getPHID()) 276 ->setTransactions($xactions) 277 ->setMarkupEngine($engine); 278 279 $form = id(new PhabricatorApplicationTransactionCommentView()) 280 ->setUser($viewer) 281 ->setObjectPHID($answer->getPHID()) 282 ->setShowPreview(false) 283 ->setHeaderText(pht('Answer Comment')) 284 ->setAction($this->getApplicationURI("/answer/comment/{$id}/")) 285 ->setSubmitButtonName(pht('Comment')); 286 287 $details[] = $form; 288 289 $out[] = $this->wrapComments( 290 count($xactions), 291 $details); 292 } 293 294 $out[] = phutil_tag('br'); 295 $out[] = phutil_tag('br'); 296 297 return $out; 298 } 299 300 private function buildAnswerActions(PonderAnswer $answer) { 301 $request = $this->getRequest(); 302 $viewer = $request->getUser(); 303 304 $id = $answer->getID(); 305 306 $can_edit = PhabricatorPolicyFilter::hasCapability( 307 $viewer, 308 $answer, 309 PhabricatorPolicyCapability::CAN_EDIT); 310 311 $view = id(new PhabricatorActionListView()) 312 ->setUser($request->getUser()) 313 ->setObject($answer) 314 ->setObjectURI($request->getRequestURI()); 315 316 $view->addAction( 317 id(new PhabricatorActionView()) 318 ->setIcon('fa-pencil') 319 ->setName(pht('Edit Answer')) 320 ->setHref($this->getApplicationURI("/answer/edit/{$id}/")) 321 ->setDisabled(!$can_edit) 322 ->setWorkflow(!$can_edit)); 323 324 $view->addAction( 325 id(new PhabricatorActionView()) 326 ->setIcon('fa-list') 327 ->setName(pht('View History')) 328 ->setHref($this->getApplicationURI("/answer/history/{$id}/"))); 329 330 return $view; 331 } 332 333 private function buildAnswerProperties( 334 PonderAnswer $answer, 335 PhabricatorActionListView $actions) { 336 337 $viewer = $this->getRequest()->getUser(); 338 $view = id(new PHUIPropertyListView()) 339 ->setUser($viewer) 340 ->setObject($answer) 341 ->setActionList($actions); 342 343 $view->addProperty( 344 pht('Created'), 345 phabricator_datetime($answer->getDateCreated(), $viewer)); 346 347 $view->invokeWillRenderEvent(); 348 349 $votable = id(new PonderVotableView()) 350 ->setPHID($answer->getPHID()) 351 ->setURI($this->getApplicationURI('vote/')) 352 ->setCount($answer->getVoteCount()) 353 ->setVote($answer->getUserVote()); 354 355 $view->addSectionHeader(pht('Answer')); 356 $view->addTextContent( 357 array( 358 $votable, 359 phutil_tag( 360 'div', 361 array( 362 'class' => 'phabricator-remarkup', 363 ), 364 PhabricatorMarkupEngine::renderOneObject( 365 $answer, 366 $answer->getMarkupField(), 367 $viewer)), 368 )); 369 370 return $view; 371 } 372 373 private function wrapComments($n, $stuff) { 374 if ($n == 0) { 375 $text = pht('Add a Comment'); 376 } else { 377 $text = pht('Show %s Comments', new PhutilNumber($n)); 378 } 379 380 $show_id = celerity_generate_unique_node_id(); 381 $hide_id = celerity_generate_unique_node_id(); 382 383 Javelin::initBehavior('phabricator-reveal-content'); 384 require_celerity_resource('ponder-comment-table-css'); 385 386 $show = phutil_tag( 387 'div', 388 array( 389 'id' => $show_id, 390 'class' => 'ponder-show-comments', 391 ), 392 javelin_tag( 393 'a', 394 array( 395 'href' => '#', 396 'sigil' => 'reveal-content', 397 'meta' => array( 398 'showIDs' => array($hide_id), 399 'hideIDs' => array($show_id), 400 ), 401 ), 402 $text)); 403 404 $hide = phutil_tag( 405 'div', 406 array( 407 'id' => $hide_id, 408 'style' => 'display: none', 409 ), 410 $stuff); 411 412 return array($show, $hide); 413 } 414 415 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |