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; }