protected function renderResultList(array $questions, PhabricatorSavedQuery $query, array $handles)
 {
     assert_instances_of($questions, 'PonderQuestion');
     $viewer = $this->requireViewer();
     $view = id(new PHUIObjectItemListView())->setUser($viewer);
     foreach ($questions as $question) {
         $color = PonderQuestionStatus::getQuestionStatusTagColor($question->getStatus());
         $icon = PonderQuestionStatus::getQuestionStatusIcon($question->getStatus());
         $full_status = PonderQuestionStatus::getQuestionStatusFullName($question->getStatus());
         $item = new PHUIObjectItemView();
         $item->setObjectName('Q' . $question->getID());
         $item->setHeader($question->getTitle());
         $item->setHref('/Q' . $question->getID());
         $item->setObject($question);
         $item->setStatusIcon($icon . ' ' . $color, $full_status);
         $created_date = phabricator_date($question->getDateCreated(), $viewer);
         $item->addIcon('none', $created_date);
         $item->addByline(pht('Asked by %s', $handles[$question->getAuthorPHID()]->renderLink()));
         $item->addAttribute(pht('%d Answer(s)', $question->getAnswerCount()));
         $view->addItem($item);
     }
     $result = new PhabricatorApplicationSearchResultView();
     $result->setObjectList($view);
     $result->setNoDataString(pht('No questions found.'));
     return $result;
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $id = $request->getURIData('id');
     $question = id(new PonderQuestionQuery())->setViewer($viewer)->withIDs(array($id))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
     if (!$question) {
         return new Aphront404Response();
     }
     $view_uri = '/Q' . $question->getID();
     $v_status = $question->getStatus();
     if ($request->isFormPost()) {
         $v_status = $request->getStr('status');
         $xactions = array();
         $xactions[] = id(new PonderQuestionTransaction())->setTransactionType(PonderQuestionTransaction::TYPE_STATUS)->setNewValue($v_status);
         $editor = id(new PonderQuestionEditor())->setActor($viewer)->setContentSourceFromRequest($request);
         $editor->applyTransactions($question, $xactions);
         return id(new AphrontRedirectResponse())->setURI($view_uri);
     }
     $radio = id(new AphrontFormRadioButtonControl())->setLabel(pht('Status'))->setName('status')->setValue($v_status);
     foreach (PonderQuestionStatus::getQuestionStatusMap() as $value => $name) {
         $description = PonderQuestionStatus::getQuestionStatusDescription($value);
         $radio->addButton($value, $name, $description);
     }
     $form = id(new AphrontFormView())->setUser($viewer)->appendChild($radio);
     return $this->newDialog()->setTitle(pht('Change Question Status'))->appendChild($form->buildLayoutView())->addSubmitButton(pht('Submit'))->addCancelButton($view_uri);
 }
 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;
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $id = $request->getURIData('id');
     $question = id(new PonderQuestionQuery())->setViewer($viewer)->withIDs(array($id))->needAnswers(true)->needProjectPHIDs(true)->executeOne();
     if (!$question) {
         return new Aphront404Response();
     }
     $answers = $this->buildAnswers($question);
     $answer_add_panel = id(new PonderAddAnswerView())->setQuestion($question)->setUser($viewer)->setActionURI('/ponder/answer/add/');
     $header = new PHUIHeaderView();
     $header->setHeader($question->getTitle());
     $header->setUser($viewer);
     $header->setPolicyObject($question);
     if ($question->getStatus() == PonderQuestionStatus::STATUS_OPEN) {
         $header->setStatus('fa-square-o', 'bluegrey', pht('Open'));
     } else {
         $text = PonderQuestionStatus::getQuestionStatusFullName($question->getStatus());
         $icon = PonderQuestionStatus::getQuestionStatusIcon($question->getStatus());
         $header->setStatus($icon, 'dark', $text);
     }
     $actions = $this->buildActionListView($question);
     $properties = $this->buildPropertyListView($question, $actions);
     $sidebar = $this->buildSidebar($question);
     $content_id = celerity_generate_unique_node_id();
     $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'));
     $comment_view = phutil_tag('div', array('id' => $content_id, 'style' => 'display: none;'), array($timeline, $add_comment));
     $footer = id(new PonderFooterView())->setContentID($content_id)->setCount(count($xactions));
     $object_box = id(new PHUIObjectBoxView())->setHeader($header)->addPropertyList($properties)->appendChild($footer);
     if ($viewer->getPHID() == $question->getAuthorPHID()) {
         $status = $question->getStatus();
         $answers_list = $question->getAnswers();
         if ($answers_list && $status == PonderQuestionStatus::STATUS_OPEN) {
             $info_view = id(new PHUIInfoView())->setSeverity(PHUIInfoView::SEVERITY_WARNING)->appendChild(pht('If this question has been resolved, please consider closing
           the question and marking the answer as helpful.'));
             $object_box->setInfoView($info_view);
         }
     }
     $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView());
     $crumbs->addTextCrumb('Q' . $id, '/Q' . $id);
     $answer_wiki = null;
     if ($question->getAnswerWiki()) {
         $answer = phutil_tag_div('mlt mlb msr msl', $question->getAnswerWiki());
         $answer_wiki = id(new PHUIObjectBoxView())->setHeaderText(pht('Answer Summary'))->setColor(PHUIObjectBoxView::COLOR_BLUE)->appendChild($answer);
     }
     $ponder_view = id(new PHUITwoColumnView())->setMainColumn(array($object_box, $comment_view, $answer_wiki, $answers, $answer_add_panel))->setSideColumn($sidebar)->addClass('ponder-question-view');
     return $this->buildApplicationPage(array($crumbs, $ponder_view), array('title' => 'Q' . $question->getID() . ' ' . $question->getTitle(), 'pageObjects' => array_merge(array($question->getPHID()), mpull($question->getAnswers(), 'getPHID'))));
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $id = $request->getURIData('id');
     $question = id(new PonderQuestionQuery())->setViewer($viewer)->withIDs(array($id))->needAnswers(true)->needProjectPHIDs(true)->executeOne();
     if (!$question) {
         return new Aphront404Response();
     }
     $answers = $this->buildAnswers($question);
     $answer_add_panel = id(new PonderAddAnswerView())->setQuestion($question)->setUser($viewer)->setActionURI('/ponder/answer/add/');
     $header = new PHUIHeaderView();
     $header->setHeader($question->getTitle());
     $header->setUser($viewer);
     $header->setPolicyObject($question);
     $header->setHeaderIcon('fa-university');
     if ($question->getStatus() == PonderQuestionStatus::STATUS_OPEN) {
         $header->setStatus('fa-square-o', 'bluegrey', pht('Open'));
     } else {
         $text = PonderQuestionStatus::getQuestionStatusFullName($question->getStatus());
         $icon = PonderQuestionStatus::getQuestionStatusIcon($question->getStatus());
         $header->setStatus($icon, 'dark', $text);
     }
     $properties = $this->buildPropertyListView($question);
     $actions = $this->buildActionListView($question);
     $details = $this->buildPropertySectionView($question);
     $can_edit = PhabricatorPolicyFilter::hasCapability($viewer, $question, PhabricatorPolicyCapability::CAN_EDIT);
     $content_id = celerity_generate_unique_node_id();
     $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)->setAction($this->getApplicationURI("/question/comment/{$id}/"))->setSubmitButtonName(pht('Comment'));
     $add_comment = phutil_tag_div('ponder-question-add-comment-view', $add_comment);
     $comment_view = phutil_tag('div', array('id' => $content_id, 'style' => 'display: none;'), array($timeline, $add_comment));
     $footer = id(new PonderFooterView())->setContentID($content_id)->setCount(count($xactions));
     $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView());
     $crumbs->addTextCrumb('Q' . $id, '/Q' . $id);
     $crumbs->setBorder(true);
     $subheader = $this->buildSubheaderView($question);
     $answer_wiki = null;
     if ($question->getAnswerWiki()) {
         $wiki = new PHUIRemarkupView($viewer, $question->getAnswerWiki());
         $answer_wiki = id(new PHUIObjectBoxView())->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->setHeaderText(pht('ANSWER SUMMARY'))->appendChild($wiki)->addClass('ponder-answer-wiki');
     }
     require_celerity_resource('ponder-view-css');
     $ponder_content = phutil_tag('div', array('class' => 'ponder-question-content'), array($answer_wiki, $footer, $comment_view, $answers, $answer_add_panel));
     $ponder_view = id(new PHUITwoColumnView())->setHeader($header)->setSubheader($subheader)->setMainColumn($ponder_content)->setPropertyList($properties)->addPropertySection(pht('DETAILS'), $details)->setActionList($actions)->addClass('ponder-question-view');
     $page_objects = array_merge(array($question->getPHID()), mpull($question->getAnswers(), 'getPHID'));
     return $this->newPage()->setTitle('Q' . $question->getID() . ' ' . $question->getTitle())->setCrumbs($crumbs)->setPageObjectPHIDs($page_objects)->appendChild(array($ponder_view));
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $id = $request->getURIData('id');
     $question = id(new PonderQuestionQuery())->setViewer($viewer)->withIDs(array($id))->needAnswers(true)->needProjectPHIDs(true)->executeOne();
     if (!$question) {
         return new Aphront404Response();
     }
     $answers = $this->buildAnswers($question->getAnswers());
     $authors = mpull($question->getAnswers(), null, 'getAuthorPHID');
     if (isset($authors[$viewer->getPHID()])) {
         $answer_add_panel = id(new PHUIInfoView())->setSeverity(PHUIInfoView::SEVERITY_NOTICE)->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($viewer)->setActionURI('/ponder/answer/add/');
     }
     $header = new PHUIHeaderView();
     $header->setHeader($question->getTitle());
     $header->setUser($viewer);
     $header->setPolicyObject($question);
     if ($question->getStatus() == PonderQuestionStatus::STATUS_OPEN) {
         $header->setStatus('fa-square-o', 'bluegrey', pht('Open'));
     } else {
         $text = PonderQuestionStatus::getQuestionStatusFullName($question->getStatus());
         $icon = PonderQuestionStatus::getQuestionStatusIcon($question->getStatus());
         $header->setStatus($icon, 'dark', $text);
     }
     $actions = $this->buildActionListView($question);
     $properties = $this->buildPropertyListView($question, $actions);
     $sidebar = $this->buildSidebar($question);
     $content_id = celerity_generate_unique_node_id();
     $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'));
     $comment_view = phutil_tag('div', array('id' => $content_id, 'style' => 'display: none;'), array($timeline, $add_comment));
     $footer = id(new PonderFooterView())->setContentID($content_id)->setCount(count($xactions));
     $object_box = id(new PHUIObjectBoxView())->setHeader($header)->addPropertyList($properties)->appendChild($footer);
     $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView());
     $crumbs->addTextCrumb('Q' . $id, '/Q' . $id);
     $ponder_view = id(new PHUITwoColumnView())->setMainColumn(array($object_box, $comment_view, $answers, $answer_add_panel))->setSideColumn($sidebar)->addClass('ponder-question-view');
     return $this->buildApplicationPage(array($crumbs, $ponder_view), array('title' => 'Q' . $question->getID() . ' ' . $question->getTitle(), 'pageObjects' => array_merge(array($question->getPHID()), mpull($question->getAnswers(), 'getPHID'))));
 }
 public function getColor()
 {
     $old = $this->getOldValue();
     $new = $this->getNewValue();
     switch ($this->getTransactionType()) {
         case self::TYPE_TITLE:
         case self::TYPE_CONTENT:
         case self::TYPE_ANSWERWIKI:
             return PhabricatorTransactions::COLOR_BLUE;
         case self::TYPE_ANSWERS:
             return PhabricatorTransactions::COLOR_GREEN;
         case self::TYPE_STATUS:
             return PonderQuestionStatus::getQuestionStatusTagColor($new);
     }
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $id = $request->getURIData('id');
     if ($id) {
         $question = id(new PonderQuestionQuery())->setViewer($viewer)->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);
         $is_new = false;
     } else {
         $is_new = true;
         $question = PonderQuestion::initializeNewQuestion($viewer);
         $v_projects = array();
     }
     $v_title = $question->getTitle();
     $v_content = $question->getContent();
     $v_wiki = $question->getAnswerWiki();
     $v_view = $question->getViewPolicy();
     $v_space = $question->getSpacePHID();
     $v_status = $question->getStatus();
     $errors = array();
     $e_title = true;
     if ($request->isFormPost()) {
         $v_title = $request->getStr('title');
         $v_content = $request->getStr('content');
         $v_wiki = $request->getStr('answerWiki');
         $v_projects = $request->getArr('projects');
         $v_view = $request->getStr('viewPolicy');
         $v_space = $request->getStr('spacePHID');
         $v_status = $request->getStr('status');
         $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);
             $xactions[] = id(clone $template)->setTransactionType(PonderQuestionTransaction::TYPE_ANSWERWIKI)->setNewValue($v_wiki);
             if (!$is_new) {
                 $xactions[] = id(clone $template)->setTransactionType(PonderQuestionTransaction::TYPE_STATUS)->setNewValue($v_status);
             }
             $xactions[] = id(clone $template)->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)->setNewValue($v_view);
             $xactions[] = id(clone $template)->setTransactionType(PhabricatorTransactions::TYPE_SPACE)->setNewValue($v_space);
             $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($viewer)->setContentSourceFromRequest($request)->setContinueOnNoEffect(true);
             $editor->applyTransactions($question, $xactions);
             return id(new AphrontRedirectResponse())->setURI('/Q' . $question->getID());
         }
     }
     $policies = id(new PhabricatorPolicyQuery())->setViewer($viewer)->setObject($question)->execute();
     $form = id(new AphrontFormView())->setUser($viewer)->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Question'))->setName('title')->setValue($v_title)->setError($e_title))->appendChild(id(new PhabricatorRemarkupControl())->setUser($viewer)->setName('content')->setID('content')->setValue($v_content)->setLabel(pht('Question Details'))->setUser($viewer))->appendChild(id(new PhabricatorRemarkupControl())->setUser($viewer)->setName('answerWiki')->setID('answerWiki')->setValue($v_wiki)->setLabel(pht('Answer Summary'))->setUser($viewer))->appendControl(id(new AphrontFormPolicyControl())->setName('viewPolicy')->setPolicyObject($question)->setSpacePHID($v_space)->setPolicies($policies)->setValue($v_view)->setCapability(PhabricatorPolicyCapability::CAN_VIEW));
     if (!$is_new) {
         $form->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Status'))->setName('status')->setValue($v_status)->setOptions(PonderQuestionStatus::getQuestionStatusMap()));
     }
     $form->appendControl(id(new AphrontFormTokenizerControl())->setLabel(pht('Tags'))->setName('projects')->setValue($v_projects)->setDatasource(new PhabricatorProjectDatasource()));
     $form->appendChild(id(new AphrontFormSubmitControl())->addCancelButton($this->getApplicationURI())->setValue(pht('Submit')));
     $preview = id(new PHUIRemarkupPreviewPanel())->setHeader(pht('Question Preview'))->setControlID('content')->setPreviewURI($this->getApplicationURI('preview/'));
     $answer_preview = id(new PHUIRemarkupPreviewPanel())->setHeader(pht('Answer Summary Preview'))->setControlID('answerWiki')->setPreviewURI($this->getApplicationURI('preview/'));
     $crumbs = $this->buildApplicationCrumbs();
     $id = $question->getID();
     if ($id) {
         $crumbs->addTextCrumb("Q{$id}", "/Q{$id}");
         $crumbs->addTextCrumb(pht('Edit'));
         $title = pht('Edit Question');
         $header = id(new PHUIHeaderView())->setHeader($title)->setHeaderIcon('fa-pencil');
     } else {
         $crumbs->addTextCrumb(pht('Ask Question'));
         $title = pht('Ask New Question');
         $header = id(new PHUIHeaderView())->setHeader($title)->setHeaderIcon('fa-plus-square');
     }
     $crumbs->setBorder(true);
     $box = id(new PHUIObjectBoxView())->setHeaderText(pht('Question'))->setFormErrors($errors)->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->setForm($form);
     $view = id(new PHUITwoColumnView())->setHeader($header)->setFooter(array($box, $preview, $answer_preview));
     return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->appendChild($view);
 }
 protected function renderResultList(array $questions, PhabricatorSavedQuery $query, array $handles)
 {
     assert_instances_of($questions, 'PonderQuestion');
     $viewer = $this->requireViewer();
     $proj_phids = array();
     foreach ($questions as $question) {
         foreach ($question->getProjectPHIDs() as $project_phid) {
             $proj_phids[] = $project_phid;
         }
     }
     $proj_handles = id(new PhabricatorHandleQuery())->setViewer($viewer)->withPHIDs($proj_phids)->execute();
     $view = id(new PHUIObjectItemListView())->setUser($viewer);
     foreach ($questions as $question) {
         $color = PonderQuestionStatus::getQuestionStatusTagColor($question->getStatus());
         $icon = PonderQuestionStatus::getQuestionStatusIcon($question->getStatus());
         $full_status = PonderQuestionStatus::getQuestionStatusFullName($question->getStatus());
         $item = new PHUIObjectItemView();
         $item->setObjectName('Q' . $question->getID());
         $item->setHeader($question->getTitle());
         $item->setHref('/Q' . $question->getID());
         $item->setObject($question);
         $item->setStatusIcon($icon . ' ' . $color, $full_status);
         $project_handles = array_select_keys($proj_handles, $question->getProjectPHIDs());
         $created_date = phabricator_date($question->getDateCreated(), $viewer);
         $item->addIcon('none', $created_date);
         $item->addByline(pht('Asked by %s', $handles[$question->getAuthorPHID()]->renderLink()));
         $item->addAttribute(pht('%s Answer(s)', new PhutilNumber($question->getAnswerCount())));
         if ($project_handles) {
             $item->addAttribute(id(new PHUIHandleTagListView())->setLimit(4)->setSlim(true)->setHandles($project_handles));
         }
         $view->addItem($item);
     }
     $result = new PhabricatorApplicationSearchResultView();
     $result->setObjectList($view);
     $result->setNoDataString(pht('No questions found.'));
     return $result;
 }
 protected function renderResultList(array $questions, PhabricatorSavedQuery $query, array $handles)
 {
     assert_instances_of($questions, 'PonderQuestion');
     $viewer = $this->requireViewer();
     $view = id(new PHUIObjectItemListView())->setUser($viewer);
     foreach ($questions as $question) {
         $item = new PHUIObjectItemView();
         $item->setObjectName('Q' . $question->getID());
         $item->setHeader($question->getTitle());
         $item->setHref('/Q' . $question->getID());
         $item->setObject($question);
         $item->setBarColor(PonderQuestionStatus::getQuestionStatusTagColor($question->getStatus()));
         $created_date = phabricator_date($question->getDateCreated(), $viewer);
         $item->addIcon('none', $created_date);
         $item->addByline(pht('Asked by %s', $handles[$question->getAuthorPHID()]->renderLink()));
         $item->addAttribute(pht('%d Answer(s)', $question->getAnswerCount()));
         $view->addItem($item);
     }
     return $view;
 }