[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/ponder/controller/ -> PonderQuestionViewController.php (source)

   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  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1