public static function indexQuestion(PonderQuestion $question) { // note: we assume someone's already called attachrelated on $question $doc = new PhabricatorSearchAbstractDocument(); $doc->setPHID($question->getPHID()); $doc->setDocumentType(PhabricatorPHIDConstants::PHID_TYPE_QUES); $doc->setDocumentTitle($question->getTitle()); $doc->setDocumentCreated($question->getDateCreated()); $doc->setDocumentModified($question->getDateModified()); $doc->addField(PhabricatorSearchField::FIELD_BODY, $question->getContent()); $doc->addRelationship(PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR, $question->getAuthorPHID(), PhabricatorPHIDConstants::PHID_TYPE_USER, $question->getDateCreated()); $comments = $question->getComments(); foreach ($comments as $curcomment) { $doc->addField(PhabricatorSearchField::FIELD_COMMENT, $curcomment->getContent()); } $answers = $question->getAnswers(); foreach ($answers as $curanswer) { if (strlen($curanswer->getContent())) { $doc->addField(PhabricatorSearchField::FIELD_COMMENT, $curanswer->getContent()); } $answer_comments = $curanswer->getComments(); foreach ($answer_comments as $curcomment) { $doc->addField(PhabricatorSearchField::FIELD_COMMENT, $curcomment->getContent()); } } self::reindexAbstractDocument($doc); }
protected function loadPage() { $question = new PonderQuestion(); $conn_r = $question->establishConnection('r'); $data = queryfx_all($conn_r, 'SELECT q.* FROM %T q %Q %Q %Q %Q', $question->getTableName(), $this->buildJoinsClause($conn_r), $this->buildWhereClause($conn_r), $this->buildOrderClause($conn_r), $this->buildLimitClause($conn_r)); return $question->loadAllFromArray($data); }
private function buildQuestionTransactions(PonderQuestion $question) { $viewer = $this->getViewer(); $id = $question->getID(); $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')); return $this->wrapComments(count($xactions), array($timeline, $add_comment)); }
public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $author_phid = $user->getPHID(); $object_phids = array($author_phid); $handles = id(new PhabricatorObjectHandleData($object_phids))->loadHandles(); $question = new PonderQuestion(); $question->setContent($request->getStr('content')); $question->setAuthorPHID($author_phid); $view = new PonderCommentBodyView(); $view->setQuestion($question)->setTarget($question)->setPreview(true)->setUser($user)->setHandles($handles)->setAction(self::VERB_ASKED); return id(new AphrontAjaxResponse())->setContent($view->render()); }
private function buildPropertyListView(PonderQuestion $question, array $subscribers) { $viewer = $this->getRequest()->getUser(); $view = new PhabricatorPropertyListView(); $view->addProperty(pht('Author'), $this->getHandle($question->getAuthorPHID())->renderLink()); $view->addProperty(pht('Created'), phabricator_datetime($question->getDateCreated(), $viewer)); if ($subscribers) { foreach ($subscribers as $key => $subscriber) { $subscribers[$key] = $this->getHandle($subscriber)->renderLink(); } $subscribers = implode(', ', $subscribers); } $view->addProperty(pht('Subscribers'), nonempty($subscribers, '<em>' . pht('None') . '</em>')); return $view; }
private function buildQuestionTransactions(PonderQuestion $question) { $viewer = $this->getRequest()->getUser(); $id = $question->getID(); $xactions = id(new PonderQuestionTransactionQuery())->setViewer($viewer)->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT))->withObjectPHIDs(array($question->getPHID()))->execute(); $engine = id(new PhabricatorMarkupEngine())->setViewer($viewer); foreach ($xactions as $xaction) { if ($xaction->getComment()) { $engine->addObject($xaction->getComment(), PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); } } $engine->process(); $timeline = id(new PhabricatorApplicationTransactionView())->setUser($viewer)->setObjectPHID($question->getPHID())->setTransactions($xactions)->setMarkupEngine($engine); $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')); return $this->wrapComments(count($xactions), array($timeline, $add_comment)); }
protected function buildSideNavView(PonderQuestion $question = null) { $side_nav = new AphrontSideNavFilterView(); $side_nav->setBaseURI(new PhutilURI($this->getApplicationURI())); if ($question && $question->getID()) { $side_nav->addFilter(null, 'Q' . $question->getID(), 'Q' . $question->getID()); $side_nav->addSpacer(); } $side_nav->addLabel('Create'); $side_nav->addFilter('question/ask', 'Ask a Question'); $side_nav->addSpacer(); $side_nav->addLabel('Questions'); $side_nav->addFilter('feed', 'All Questions'); $side_nav->addSpacer(); $side_nav->addLabel('User'); $side_nav->addFilter('questions', 'Your Questions'); $side_nav->addFilter('answers', 'Your Answers'); return $side_nav; }
protected function processReceivedMail(PhabricatorMetaMTAReceivedMail $mail, PhabricatorUser $sender) { $title = $mail->getSubject(); if (!strlen($title)) { $title = pht('New Question'); } $xactions = array(); $xactions[] = id(new PonderQuestionTransaction())->setTransactionType(PonderQuestionTransaction::TYPE_TITLE)->setNewValue($title); $xactions[] = id(new PonderQuestionTransaction())->setTransactionType(PonderQuestionTransaction::TYPE_CONTENT)->setNewValue($mail->getCleanTextBody()); $question = PonderQuestion::initializeNewQuestion($sender); $content_source = $mail->newContentSource(); $editor = id(new PonderQuestionEditor())->setActor($sender)->setContentSource($content_source)->setContinueOnNoEffect(true); $xactions = $editor->applyTransactions($question, $xactions); $mail->setRelatedPHID($question->getPHID()); }
public static function indexQuestion(PonderQuestion $question) { $doc = new PhabricatorSearchAbstractDocument(); $doc->setPHID($question->getPHID()); $doc->setDocumentType(PhabricatorPHIDConstants::PHID_TYPE_QUES); $doc->setDocumentTitle($question->getTitle()); $doc->setDocumentCreated($question->getDateCreated()); $doc->setDocumentModified($question->getDateModified()); $doc->addField(PhabricatorSearchField::FIELD_BODY, $question->getContent()); $doc->addRelationship(PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR, $question->getAuthorPHID(), PhabricatorPHIDConstants::PHID_TYPE_USER, $question->getDateCreated()); $answers = $question->getAnswers(); $touches = array(); foreach ($answers as $comment) { if (strlen($comment->getContent())) { $doc->addField(PhabricatorSearchField::FIELD_COMMENT, $comment->getContent()); } $author = $comment->getAuthorPHID(); $touches[$author] = $comment->getDateCreated(); } self::reindexAbstractDocument($doc); }
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); }
public function execute() { $question = new PonderQuestion(); $conn_r = $question->establishConnection('r'); $where = $this->buildWhereClause($conn_r); $order_by = $this->buildOrderByClause($conn_r); $limit = $this->buildLimitClause($conn_r); return $question->loadAllFromArray(queryfx_all($conn_r, 'SELECT q.* FROM %T q %Q %Q %Q', $question->getTableName(), $where, $order_by, $limit)); }
private function buildSidebar(PonderQuestion $question) { $viewer = $this->getViewer(); $status = $question->getStatus(); $id = $question->getID(); $questions = id(new PonderQuestionQuery())->setViewer($viewer)->withStatuses(array($status))->withEdgeLogicPHIDs(PhabricatorProjectObjectHasProjectEdgeType::EDGECONST, PhabricatorQueryConstraint::OPERATOR_OR, $question->getProjectPHIDs())->setLimit(10)->execute(); $list = id(new PHUIObjectItemListView())->setUser($viewer)->setNoDataString(pht('No similar questions found.')); foreach ($questions as $question) { if ($id == $question->getID()) { continue; } $item = new PHUIObjectItemView(); $item->setObjectName('Q' . $question->getID()); $item->setHeader($question->getTitle()); $item->setHref('/Q' . $question->getID()); $item->setObject($question); $item->addAttribute(pht('%d Answer(s)', $question->getAnswerCount())); $list->addItem($item); } $box = id(new PHUIObjectBoxView())->setHeaderText(pht('Similar Questions'))->setObjectList($list); return $box; }
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); } else { $question = PonderQuestion::initializeNewQuestion($viewer); $v_projects = array(); } $v_title = $question->getTitle(); $v_content = $question->getContent(); $v_view = $question->getViewPolicy(); $v_edit = $question->getEditPolicy(); $errors = array(); $e_title = true; if ($request->isFormPost()) { $v_title = $request->getStr('title'); $v_content = $request->getStr('content'); $v_projects = $request->getArr('projects'); $v_view = $request->getStr('viewPolicy'); $v_edit = $request->getStr('editPolicy'); $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(PhabricatorTransactions::TYPE_VIEW_POLICY)->setNewValue($v_view); $xactions[] = id(clone $template)->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)->setNewValue($v_edit); $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('Description'))->setUser($viewer))->appendControl(id(new AphrontFormPolicyControl())->setName('viewPolicy')->setPolicyObject($question)->setPolicies($policies)->setValue($v_view)->setCapability(PhabricatorPolicyCapability::CAN_VIEW))->appendControl(id(new AphrontFormPolicyControl())->setName('editPolicy')->setPolicyObject($question)->setPolicies($policies)->setValue($v_edit)->setCapability(PhabricatorPolicyCapability::CAN_EDIT)); $form->appendControl(id(new AphrontFormTokenizerControl())->setLabel(pht('Projects'))->setName('projects')->setValue($v_projects)->setDatasource(new PhabricatorProjectDatasource())); $form->appendChild(id(new AphrontFormSubmitControl())->addCancelButton($this->getApplicationURI())->setValue(pht('Ask Away!'))); $preview = id(new PHUIRemarkupPreviewPanel())->setHeader(pht('Question Preview'))->setControlID('content')->setPreviewURI($this->getApplicationURI('preview/')); $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Ask New Question'))->setFormErrors($errors)->setForm($form); $crumbs = $this->buildApplicationCrumbs(); $id = $question->getID(); if ($id) { $crumbs->addTextCrumb("Q{$id}", "/Q{$id}"); $crumbs->addTextCrumb(pht('Edit')); } else { $crumbs->addTextCrumb(pht('Ask Question')); } return $this->buildApplicationPage(array($crumbs, $form_box, $preview), array('title' => pht('Ask New Question'))); }
<?php echo pht('Populating Questions with mail keys...') . "\n"; $table = new PonderQuestion(); $table->openTransaction(); foreach (new LiskMigrationIterator($table) as $question) { $id = $question->getID(); echo pht('Question %d: ', $id); if (!$question->getMailKey()) { queryfx($question->establishConnection('w'), 'UPDATE %T SET mailKey = %s WHERE id = %d', $question->getTableName(), Filesystem::readRandomCharacters(20), $id); echo pht('Generated Key') . "\n"; } else { echo "-\n"; } } $table->saveTransaction(); echo pht('Done.') . "\n";
/** * This is fairly non-standard; building N timelines at once (N = number of * answers) is tricky business. * * 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. */ private function buildAnswers(PonderQuestion $question) { $viewer = $this->getViewer(); $answers = $question->getAnswers(); if ($answers) { $author_phids = mpull($answers, 'getAuthorPHID'); $handles = $this->loadViewerHandles($author_phids); $view = array(); foreach ($answers as $answer) { $id = $answer->getID(); $handle = $handles[$answer->getAuthorPHID()]; $timeline = $this->buildTransactionTimeline($answer, id(new PonderAnswerTransactionQuery())->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT))); $xactions = $timeline->getTransactions(); $view[] = id(new PonderAnswerView())->setUser($viewer)->setAnswer($answer)->setTransactions($xactions)->setTimeline($timeline)->setHandle($handle); } $header = id(new PHUIHeaderView())->setHeader('Answers'); return id(new PHUIBoxView())->addClass('ponder-answer-section')->appendChild($header)->appendChild($view); } return null; }