mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-02 02:40:58 +01:00
Use ApplicationSearch in Ponder
Summary: Ref T2625. Also modernize some other things: - Fix double-"subscribers". - Use byline and more standard date. - Modernize some of the use of crumbs and navigation. - Delete some dead / uncalled code. Test Plan: {F50669} Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T3578, T2625 Differential Revision: https://secure.phabricator.com/D6486
This commit is contained in:
parent
21d5992a58
commit
85798368be
10 changed files with 245 additions and 227 deletions
|
@ -1839,7 +1839,6 @@ phutil_register_library_map(array(
|
||||||
'PonderConstants' => 'applications/ponder/PonderConstants.php',
|
'PonderConstants' => 'applications/ponder/PonderConstants.php',
|
||||||
'PonderController' => 'applications/ponder/controller/PonderController.php',
|
'PonderController' => 'applications/ponder/controller/PonderController.php',
|
||||||
'PonderDAO' => 'applications/ponder/storage/PonderDAO.php',
|
'PonderDAO' => 'applications/ponder/storage/PonderDAO.php',
|
||||||
'PonderFeedController' => 'applications/ponder/controller/PonderFeedController.php',
|
|
||||||
'PonderMail' => 'applications/ponder/mail/PonderMail.php',
|
'PonderMail' => 'applications/ponder/mail/PonderMail.php',
|
||||||
'PonderMentionMail' => 'applications/ponder/mail/PonderMentionMail.php',
|
'PonderMentionMail' => 'applications/ponder/mail/PonderMentionMail.php',
|
||||||
'PonderPostBodyView' => 'applications/ponder/view/PonderPostBodyView.php',
|
'PonderPostBodyView' => 'applications/ponder/view/PonderPostBodyView.php',
|
||||||
|
@ -1847,9 +1846,11 @@ phutil_register_library_map(array(
|
||||||
'PonderQuestionAskController' => 'applications/ponder/controller/PonderQuestionAskController.php',
|
'PonderQuestionAskController' => 'applications/ponder/controller/PonderQuestionAskController.php',
|
||||||
'PonderQuestionDetailView' => 'applications/ponder/view/PonderQuestionDetailView.php',
|
'PonderQuestionDetailView' => 'applications/ponder/view/PonderQuestionDetailView.php',
|
||||||
'PonderQuestionEditor' => 'applications/ponder/editor/PonderQuestionEditor.php',
|
'PonderQuestionEditor' => 'applications/ponder/editor/PonderQuestionEditor.php',
|
||||||
|
'PonderQuestionListController' => 'applications/ponder/controller/PonderQuestionListController.php',
|
||||||
'PonderQuestionMailReceiver' => 'applications/ponder/mail/PonderQuestionMailReceiver.php',
|
'PonderQuestionMailReceiver' => 'applications/ponder/mail/PonderQuestionMailReceiver.php',
|
||||||
'PonderQuestionPreviewController' => 'applications/ponder/controller/PonderQuestionPreviewController.php',
|
'PonderQuestionPreviewController' => 'applications/ponder/controller/PonderQuestionPreviewController.php',
|
||||||
'PonderQuestionQuery' => 'applications/ponder/query/PonderQuestionQuery.php',
|
'PonderQuestionQuery' => 'applications/ponder/query/PonderQuestionQuery.php',
|
||||||
|
'PonderQuestionSearchEngine' => 'applications/ponder/query/PonderQuestionSearchEngine.php',
|
||||||
'PonderQuestionSummaryView' => 'applications/ponder/view/PonderQuestionSummaryView.php',
|
'PonderQuestionSummaryView' => 'applications/ponder/view/PonderQuestionSummaryView.php',
|
||||||
'PonderQuestionViewController' => 'applications/ponder/controller/PonderQuestionViewController.php',
|
'PonderQuestionViewController' => 'applications/ponder/controller/PonderQuestionViewController.php',
|
||||||
'PonderRemarkupRule' => 'applications/ponder/remarkup/PonderRemarkupRule.php',
|
'PonderRemarkupRule' => 'applications/ponder/remarkup/PonderRemarkupRule.php',
|
||||||
|
@ -3866,7 +3867,6 @@ phutil_register_library_map(array(
|
||||||
'PonderCommentSaveController' => 'PonderController',
|
'PonderCommentSaveController' => 'PonderController',
|
||||||
'PonderController' => 'PhabricatorController',
|
'PonderController' => 'PhabricatorController',
|
||||||
'PonderDAO' => 'PhabricatorLiskDAO',
|
'PonderDAO' => 'PhabricatorLiskDAO',
|
||||||
'PonderFeedController' => 'PonderController',
|
|
||||||
'PonderMail' => 'PhabricatorMail',
|
'PonderMail' => 'PhabricatorMail',
|
||||||
'PonderMentionMail' => 'PonderMail',
|
'PonderMentionMail' => 'PonderMail',
|
||||||
'PonderPostBodyView' => 'AphrontView',
|
'PonderPostBodyView' => 'AphrontView',
|
||||||
|
@ -3882,9 +3882,15 @@ phutil_register_library_map(array(
|
||||||
'PonderQuestionAskController' => 'PonderController',
|
'PonderQuestionAskController' => 'PonderController',
|
||||||
'PonderQuestionDetailView' => 'AphrontView',
|
'PonderQuestionDetailView' => 'AphrontView',
|
||||||
'PonderQuestionEditor' => 'PhabricatorEditor',
|
'PonderQuestionEditor' => 'PhabricatorEditor',
|
||||||
|
'PonderQuestionListController' =>
|
||||||
|
array(
|
||||||
|
0 => 'PonderController',
|
||||||
|
1 => 'PhabricatorApplicationSearchResultsControllerInterface',
|
||||||
|
),
|
||||||
'PonderQuestionMailReceiver' => 'PhabricatorObjectMailReceiver',
|
'PonderQuestionMailReceiver' => 'PhabricatorObjectMailReceiver',
|
||||||
'PonderQuestionPreviewController' => 'PonderController',
|
'PonderQuestionPreviewController' => 'PonderController',
|
||||||
'PonderQuestionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PonderQuestionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PonderQuestionSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||||
'PonderQuestionSummaryView' => 'AphrontView',
|
'PonderQuestionSummaryView' => 'AphrontView',
|
||||||
'PonderQuestionViewController' => 'PonderController',
|
'PonderQuestionViewController' => 'PonderController',
|
||||||
'PonderRemarkupRule' => 'PhabricatorRemarkupRuleObject',
|
'PonderRemarkupRule' => 'PhabricatorRemarkupRuleObject',
|
||||||
|
|
|
@ -49,9 +49,7 @@ final class PhabricatorApplicationPonder extends PhabricatorApplication {
|
||||||
return array(
|
return array(
|
||||||
'/Q(?P<id>[1-9]\d*)' => 'PonderQuestionViewController',
|
'/Q(?P<id>[1-9]\d*)' => 'PonderQuestionViewController',
|
||||||
'/ponder/' => array(
|
'/ponder/' => array(
|
||||||
'(?P<page>feed/)?' => 'PonderFeedController',
|
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PonderQuestionListController',
|
||||||
'(?P<page>questions)/' => 'PonderFeedController',
|
|
||||||
'(?P<page>answers)/' => 'PonderFeedController',
|
|
||||||
'answer/add/' => 'PonderAnswerSaveController',
|
'answer/add/' => 'PonderAnswerSaveController',
|
||||||
'answer/preview/' => 'PonderAnswerPreviewController',
|
'answer/preview/' => 'PonderAnswerPreviewController',
|
||||||
'question/ask/' => 'PonderQuestionAskController',
|
'question/ask/' => 'PonderQuestionAskController',
|
||||||
|
|
|
@ -2,30 +2,19 @@
|
||||||
|
|
||||||
abstract class PonderController extends PhabricatorController {
|
abstract class PonderController extends PhabricatorController {
|
||||||
|
|
||||||
public function buildStandardPageResponse($view, array $data) {
|
protected function buildSideNavView() {
|
||||||
|
$user = $this->getRequest()->getUser();
|
||||||
|
|
||||||
$page = $this->buildStandardPageView();
|
$nav = new AphrontSideNavFilterView();
|
||||||
$page->setApplicationName(pht('Ponder!'));
|
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||||
$page->setBaseURI('/ponder/');
|
|
||||||
$page->setTitle(idx($data, 'title'));
|
|
||||||
$page->setGlyph("\xE2\x97\xB3");
|
|
||||||
$page->appendChild($view);
|
|
||||||
$page->setSearchDefaultScope(PhabricatorSearchScope::SCOPE_QUESTIONS);
|
|
||||||
|
|
||||||
$response = new AphrontWebpageResponse();
|
id(new PonderQuestionSearchEngine())
|
||||||
return $response->setContent($page->render());
|
->setViewer($user)
|
||||||
}
|
->addNavigationItems($nav->getMenu());
|
||||||
|
|
||||||
protected function buildSideNavView(PonderQuestion $question = null) {
|
$nav->selectFilter(null);
|
||||||
$side_nav = new AphrontSideNavFilterView();
|
|
||||||
$side_nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
|
||||||
|
|
||||||
$side_nav->addLabel(pht('Questions'));
|
return $nav;
|
||||||
$side_nav->addFilter('feed', pht('All Questions'));
|
|
||||||
$side_nav->addFilter('questions', pht('Your Questions'));
|
|
||||||
$side_nav->addFilter('answers', pht('Your Answers'));
|
|
||||||
|
|
||||||
return $side_nav;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildApplicationCrumbs() {
|
public function buildApplicationCrumbs() {
|
||||||
|
@ -33,8 +22,8 @@ abstract class PonderController extends PhabricatorController {
|
||||||
$crumbs
|
$crumbs
|
||||||
->addAction(
|
->addAction(
|
||||||
id(new PHUIListItemView())
|
id(new PHUIListItemView())
|
||||||
->setName(pht('New Question'))
|
->setName(pht('Create Question'))
|
||||||
->setHref('/ponder/question/ask')
|
->setHref('/ponder/question/ask/')
|
||||||
->setIcon('create'));
|
->setIcon('create'));
|
||||||
|
|
||||||
return $crumbs;
|
return $crumbs;
|
||||||
|
|
|
@ -1,119 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class PonderFeedController extends PonderController {
|
|
||||||
private $page;
|
|
||||||
private $answerOffset;
|
|
||||||
|
|
||||||
const PROFILE_ANSWER_PAGE_SIZE = 10;
|
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
|
||||||
$this->page = idx($data, 'page');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processRequest() {
|
|
||||||
$request = $this->getRequest();
|
|
||||||
$user = $request->getUser();
|
|
||||||
$this->answerOffset = $request->getInt('aoff');
|
|
||||||
|
|
||||||
$pages = array(
|
|
||||||
'feed' => pht('All Questions'),
|
|
||||||
'questions' => pht('Your Questions'),
|
|
||||||
'answers' => pht('Your Answers'),
|
|
||||||
);
|
|
||||||
|
|
||||||
$side_nav = $this->buildSideNavView();
|
|
||||||
$this->page = $side_nav->selectFilter($this->page, 'feed');
|
|
||||||
$title = $pages[$this->page];
|
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs($this->buildSideNavView());
|
|
||||||
$crumbs->addCrumb(
|
|
||||||
id(new PhabricatorCrumbView())
|
|
||||||
->setName($title)
|
|
||||||
->setHref($this->getApplicationURI()));
|
|
||||||
$side_nav->setCrumbs($crumbs);
|
|
||||||
|
|
||||||
switch ($this->page) {
|
|
||||||
case 'feed':
|
|
||||||
case 'questions':
|
|
||||||
$pager = new AphrontPagerView();
|
|
||||||
$pager->setOffset($request->getStr('offset'));
|
|
||||||
$pager->setURI($request->getRequestURI(), 'offset');
|
|
||||||
|
|
||||||
$query = id(new PonderQuestionQuery())
|
|
||||||
->setViewer($user);
|
|
||||||
|
|
||||||
if ($this->page == 'feed') {
|
|
||||||
$query
|
|
||||||
->setOrder(PonderQuestionQuery::ORDER_HOTTEST);
|
|
||||||
} else {
|
|
||||||
$query
|
|
||||||
->setOrder(PonderQuestionQuery::ORDER_CREATED)
|
|
||||||
->withAuthorPHIDs(array($user->getPHID()));
|
|
||||||
}
|
|
||||||
|
|
||||||
$questions = $query->executeWithOffsetPager($pager);
|
|
||||||
|
|
||||||
$this->loadHandles(mpull($questions, 'getAuthorPHID'));
|
|
||||||
|
|
||||||
$view = $this->buildQuestionListView($questions);
|
|
||||||
$view->setPager($pager);
|
|
||||||
|
|
||||||
$side_nav->appendChild($view);
|
|
||||||
break;
|
|
||||||
case 'answers':
|
|
||||||
$answers = PonderAnswerQuery::loadByAuthorWithQuestions(
|
|
||||||
$user,
|
|
||||||
$user->getPHID(),
|
|
||||||
$this->answerOffset,
|
|
||||||
self::PROFILE_ANSWER_PAGE_SIZE + 1);
|
|
||||||
|
|
||||||
$side_nav->appendChild(
|
|
||||||
id(new PonderUserProfileView())
|
|
||||||
->setUser($user)
|
|
||||||
->setAnswers($answers)
|
|
||||||
->setAnswerOffset($this->answerOffset)
|
|
||||||
->setPageSize(self::PROFILE_ANSWER_PAGE_SIZE)
|
|
||||||
->setURI(new PhutilURI("/ponder/profile/"), "aoff"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
|
||||||
$side_nav,
|
|
||||||
array(
|
|
||||||
'device' => true,
|
|
||||||
'title' => $title,
|
|
||||||
'dust' => true,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function buildQuestionListView(array $questions) {
|
|
||||||
assert_instances_of($questions, 'PonderQuestion');
|
|
||||||
$user = $this->getRequest()->getUser();
|
|
||||||
|
|
||||||
$view = new PhabricatorObjectItemListView();
|
|
||||||
$view->setUser($user);
|
|
||||||
$view->setNoDataString(pht('No matching questions.'));
|
|
||||||
foreach ($questions as $question) {
|
|
||||||
$item = new PhabricatorObjectItemView();
|
|
||||||
$item->setObjectName('Q'.$question->getID());
|
|
||||||
$item->setHeader($question->getTitle());
|
|
||||||
$item->setHref('/Q'.$question->getID());
|
|
||||||
$item->setObject($question);
|
|
||||||
|
|
||||||
$item->addAttribute(
|
|
||||||
pht(
|
|
||||||
'Asked by %s on %s',
|
|
||||||
$this->getHandle($question->getAuthorPHID())->renderLink(),
|
|
||||||
phabricator_date($question->getDateCreated(), $user)));
|
|
||||||
|
|
||||||
$item->addAttribute(
|
|
||||||
pht('%d Answer(s)', $question->getAnswerCount()));
|
|
||||||
|
|
||||||
$view->addItem($item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $view;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -52,8 +52,6 @@ final class PonderQuestionAskController extends PonderController {
|
||||||
->setErrors($errors);
|
->setErrors($errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
$header = id(new PhabricatorHeaderView())->setHeader(pht('Ask Question'));
|
|
||||||
|
|
||||||
$form = id(new AphrontFormView())
|
$form = id(new AphrontFormView())
|
||||||
->setUser($user)
|
->setUser($user)
|
||||||
->setFlexible(true)
|
->setFlexible(true)
|
||||||
|
@ -72,7 +70,8 @@ final class PonderQuestionAskController extends PonderController {
|
||||||
->setUser($user))
|
->setUser($user))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormSubmitControl())
|
id(new AphrontFormSubmitControl())
|
||||||
->setValue(pht('Ask Away!')));
|
->addCancelButton($this->getApplicationURI())
|
||||||
|
->setValue(pht('Ask Away!')));
|
||||||
|
|
||||||
$preview = hsprintf(
|
$preview = hsprintf(
|
||||||
'<div class="aphront-panel-flush">'.
|
'<div class="aphront-panel-flush">'.
|
||||||
|
@ -91,19 +90,18 @@ final class PonderQuestionAskController extends PonderController {
|
||||||
'question_id' => null
|
'question_id' => null
|
||||||
));
|
));
|
||||||
|
|
||||||
$nav = $this->buildSideNavView($question);
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
$nav->selectFilter($question->getID() ? null : 'question/ask');
|
$crumbs->addCrumb(
|
||||||
|
id(new PhabricatorCrumbView())
|
||||||
|
->setName(pht('Ask Question')));
|
||||||
|
|
||||||
$nav->appendChild(
|
return $this->buildApplicationPage(
|
||||||
array(
|
array(
|
||||||
$header,
|
$crumbs,
|
||||||
$error_view,
|
$error_view,
|
||||||
$form,
|
$form,
|
||||||
$preview,
|
$preview,
|
||||||
));
|
),
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
|
||||||
$nav,
|
|
||||||
array(
|
array(
|
||||||
'device' => true,
|
'device' => true,
|
||||||
'dust' => true,
|
'dust' => true,
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PonderQuestionListController extends PonderController
|
||||||
|
implements PhabricatorApplicationSearchResultsControllerInterface {
|
||||||
|
|
||||||
|
private $queryKey;
|
||||||
|
|
||||||
|
public function shouldAllowPublic() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->queryKey = idx($data, 'queryKey');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$controller = id(new PhabricatorApplicationSearchController($request))
|
||||||
|
->setQueryKey($this->queryKey)
|
||||||
|
->setSearchEngine(new PonderQuestionSearchEngine())
|
||||||
|
->setNavigation($this->buildSideNavView());
|
||||||
|
|
||||||
|
return $this->delegateToController($controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderResultsList(
|
||||||
|
array $questions,
|
||||||
|
PhabricatorSavedQuery $query) {
|
||||||
|
assert_instances_of($questions, 'PonderQuestion');
|
||||||
|
$viewer = $this->getRequest()->getUser();
|
||||||
|
|
||||||
|
$phids = array();
|
||||||
|
$phids[] = mpull($questions, 'getAuthorPHID');
|
||||||
|
$phids = array_mergev($phids);
|
||||||
|
|
||||||
|
$handles = $this->loadViewerHandles($phids);
|
||||||
|
|
||||||
|
|
||||||
|
$view = id(new PhabricatorObjectItemListView())
|
||||||
|
->setUser($viewer);
|
||||||
|
|
||||||
|
foreach ($questions as $question) {
|
||||||
|
$item = new PhabricatorObjectItemView();
|
||||||
|
$item->setObjectName('Q'.$question->getID());
|
||||||
|
$item->setHeader($question->getTitle());
|
||||||
|
$item->setHref('/Q'.$question->getID());
|
||||||
|
$item->setObject($question);
|
||||||
|
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -36,10 +36,7 @@ final class PonderQuestionViewController extends PonderController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$subscribers = PhabricatorSubscribersQuery::loadSubscribersForPHID(
|
$object_phids = array_merge($object_phids);
|
||||||
$question->getPHID());
|
|
||||||
|
|
||||||
$object_phids = array_merge($object_phids, $subscribers);
|
|
||||||
|
|
||||||
$this->loadHandles($object_phids);
|
$this->loadHandles($object_phids);
|
||||||
$handles = $this->getLoadedHandles();
|
$handles = $this->getLoadedHandles();
|
||||||
|
@ -67,7 +64,7 @@ final class PonderQuestionViewController extends PonderController {
|
||||||
->setHeader($question->getTitle());
|
->setHeader($question->getTitle());
|
||||||
|
|
||||||
$actions = $this->buildActionListView($question);
|
$actions = $this->buildActionListView($question);
|
||||||
$properties = $this->buildPropertyListView($question, $subscribers);
|
$properties = $this->buildPropertyListView($question);
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs($this->buildSideNavView());
|
$crumbs = $this->buildApplicationCrumbs($this->buildSideNavView());
|
||||||
$crumbs->setActionList($actions);
|
$crumbs->setActionList($actions);
|
||||||
|
@ -76,8 +73,7 @@ final class PonderQuestionViewController extends PonderController {
|
||||||
->setName('Q'.$this->questionID)
|
->setName('Q'.$this->questionID)
|
||||||
->setHref('/Q'.$this->questionID));
|
->setHref('/Q'.$this->questionID));
|
||||||
|
|
||||||
$nav = $this->buildSideNavView($question);
|
return $this->buildApplicationPage(
|
||||||
$nav->appendChild(
|
|
||||||
array(
|
array(
|
||||||
$crumbs,
|
$crumbs,
|
||||||
$header,
|
$header,
|
||||||
|
@ -86,12 +82,7 @@ final class PonderQuestionViewController extends PonderController {
|
||||||
$detail_panel,
|
$detail_panel,
|
||||||
$responses_panel,
|
$responses_panel,
|
||||||
$answer_add_panel
|
$answer_add_panel
|
||||||
));
|
),
|
||||||
$nav->selectFilter(null);
|
|
||||||
|
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
|
||||||
$nav,
|
|
||||||
array(
|
array(
|
||||||
'device' => true,
|
'device' => true,
|
||||||
'title' => 'Q'.$question->getID().' '.$question->getTitle(),
|
'title' => 'Q'.$question->getID().' '.$question->getTitle(),
|
||||||
|
@ -108,8 +99,7 @@ final class PonderQuestionViewController extends PonderController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildPropertyListView(
|
private function buildPropertyListView(
|
||||||
PonderQuestion $question,
|
PonderQuestion $question) {
|
||||||
array $subscribers) {
|
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
$viewer = $this->getRequest()->getUser();
|
||||||
$view = id(new PhabricatorPropertyListView())
|
$view = id(new PhabricatorPropertyListView())
|
||||||
|
@ -123,14 +113,6 @@ final class PonderQuestionViewController extends PonderController {
|
||||||
pht('Created'),
|
pht('Created'),
|
||||||
phabricator_datetime($question->getDateCreated(), $viewer));
|
phabricator_datetime($question->getDateCreated(), $viewer));
|
||||||
|
|
||||||
if ($subscribers) {
|
|
||||||
$subscribers = $this->renderHandlesForPHIDs($subscribers);
|
|
||||||
}
|
|
||||||
|
|
||||||
$view->addProperty(
|
|
||||||
pht('Subscribers'),
|
|
||||||
nonempty($subscribers, phutil_tag('em', array(), pht('None'))));
|
|
||||||
|
|
||||||
return $view;
|
return $view;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,39 +27,6 @@ final class PonderAnswerQuery extends PhabricatorOffsetPagedQuery {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function loadByAuthorWithQuestions(
|
|
||||||
$viewer,
|
|
||||||
$phid,
|
|
||||||
$offset,
|
|
||||||
$count) {
|
|
||||||
|
|
||||||
if (!$viewer) {
|
|
||||||
throw new Exception("Must set viewer when calling loadByAuthor...");
|
|
||||||
}
|
|
||||||
|
|
||||||
$answers = id(new PonderAnswerQuery())
|
|
||||||
->withAuthorPHID($phid)
|
|
||||||
->orderByNewest(true)
|
|
||||||
->setOffset($offset)
|
|
||||||
->setLimit($count)
|
|
||||||
->execute();
|
|
||||||
|
|
||||||
$answerset = new LiskDAOSet();
|
|
||||||
foreach ($answers as $answer) {
|
|
||||||
$answerset->addToSet($answer);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($answers as $answer) {
|
|
||||||
$question = $answer->loadOneRelative(
|
|
||||||
new PonderQuestion(),
|
|
||||||
'id',
|
|
||||||
'getQuestionID');
|
|
||||||
$answer->setQuestion($question);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $answers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function loadByAuthor($viewer, $author_phid, $offset, $count) {
|
public static function loadByAuthor($viewer, $author_phid, $offset, $count) {
|
||||||
if (!$viewer) {
|
if (!$viewer) {
|
||||||
throw new Exception("Must set viewer when calling loadByAuthor");
|
throw new Exception("Must set viewer when calling loadByAuthor");
|
||||||
|
|
|
@ -9,6 +9,7 @@ final class PonderQuestionQuery
|
||||||
private $ids;
|
private $ids;
|
||||||
private $phids;
|
private $phids;
|
||||||
private $authorPHIDs;
|
private $authorPHIDs;
|
||||||
|
private $answererPHIDs;
|
||||||
private $order = self::ORDER_CREATED;
|
private $order = self::ORDER_CREATED;
|
||||||
|
|
||||||
public function withIDs(array $ids) {
|
public function withIDs(array $ids) {
|
||||||
|
@ -26,6 +27,11 @@ final class PonderQuestionQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withAnswererPHIDs(array $phids) {
|
||||||
|
$this->answererPHIDs = $phids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function setOrder($order) {
|
public function setOrder($order) {
|
||||||
$this->order = $order;
|
$this->order = $order;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -57,15 +63,24 @@ final class PonderQuestionQuery
|
||||||
$where = array();
|
$where = array();
|
||||||
|
|
||||||
if ($this->ids) {
|
if ($this->ids) {
|
||||||
$where[] = qsprintf($conn_r, 'q.id IN (%Ld)', $this->ids);
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'q.id IN (%Ld)',
|
||||||
|
$this->ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->phids) {
|
if ($this->phids) {
|
||||||
$where[] = qsprintf($conn_r, 'q.phid IN (%Ls)', $this->phids);
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'q.phid IN (%Ls)',
|
||||||
|
$this->phids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->authorPHIDs) {
|
if ($this->authorPHIDs) {
|
||||||
$where[] = qsprintf($conn_r, 'q.authorPHID IN (%Ls)', $this->authorPHIDs);
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'q.authorPHID IN (%Ls)',
|
||||||
|
$this->authorPHIDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
$where[] = $this->buildPagingClause($conn_r);
|
$where[] = $this->buildPagingClause($conn_r);
|
||||||
|
@ -88,19 +103,31 @@ final class PonderQuestionQuery
|
||||||
$question = new PonderQuestion();
|
$question = new PonderQuestion();
|
||||||
$conn_r = $question->establishConnection('r');
|
$conn_r = $question->establishConnection('r');
|
||||||
|
|
||||||
$where = $this->buildWhereClause($conn_r);
|
$data = queryfx_all(
|
||||||
$order_by = $this->buildOrderByClause($conn_r);
|
$conn_r,
|
||||||
$limit = $this->buildLimitClause($conn_r);
|
'SELECT q.* FROM %T q %Q %Q %Q %Q',
|
||||||
|
$question->getTableName(),
|
||||||
|
$this->buildJoinsClause($conn_r),
|
||||||
|
$this->buildWhereClause($conn_r),
|
||||||
|
$this->buildOrderByClause($conn_r),
|
||||||
|
$this->buildLimitClause($conn_r));
|
||||||
|
|
||||||
return $question->loadAllFromArray(
|
return $question->loadAllFromArray($data);
|
||||||
queryfx_all(
|
|
||||||
$conn_r,
|
|
||||||
'SELECT q.* FROM %T q %Q %Q %Q',
|
|
||||||
$question->getTableName(),
|
|
||||||
$where,
|
|
||||||
$order_by,
|
|
||||||
$limit));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function buildJoinsClause(AphrontDatabaseConnection $conn_r) {
|
||||||
|
$joins = array();
|
||||||
|
|
||||||
|
if ($this->answererPHIDs) {
|
||||||
|
$answer_table = new PonderAnswer();
|
||||||
|
$joins[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'JOIN %T a ON a.questionID = q.id AND a.authorPHID IN (%Ls)',
|
||||||
|
$answer_table->getTableName(),
|
||||||
|
$this->answererPHIDs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode(' ', $joins);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
105
src/applications/ponder/query/PonderQuestionSearchEngine.php
Normal file
105
src/applications/ponder/query/PonderQuestionSearchEngine.php
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PonderQuestionSearchEngine
|
||||||
|
extends PhabricatorApplicationSearchEngine {
|
||||||
|
|
||||||
|
public function buildSavedQueryFromRequest(AphrontRequest $request) {
|
||||||
|
$saved = new PhabricatorSavedQuery();
|
||||||
|
|
||||||
|
$saved->setParameter(
|
||||||
|
'authorPHIDs',
|
||||||
|
array_values($request->getArr('authors')));
|
||||||
|
|
||||||
|
$saved->setParameter(
|
||||||
|
'answererPHIDs',
|
||||||
|
array_values($request->getArr('answerers')));
|
||||||
|
|
||||||
|
return $saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
|
||||||
|
$query = id(new PonderQuestionQuery());
|
||||||
|
|
||||||
|
$author_phids = $saved->getParameter('authorPHIDs');
|
||||||
|
if ($author_phids) {
|
||||||
|
$query->withAuthorPHIDs($author_phids);
|
||||||
|
}
|
||||||
|
|
||||||
|
$answerer_phids = $saved->getParameter('answererPHIDs');
|
||||||
|
if ($answerer_phids) {
|
||||||
|
$query->withAnswererPHIDs($answerer_phids);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildSearchForm(
|
||||||
|
AphrontFormView $form,
|
||||||
|
PhabricatorSavedQuery $saved_query) {
|
||||||
|
|
||||||
|
$author_phids = $saved_query->getParameter('authorPHIDs', array());
|
||||||
|
$answerer_phids = $saved_query->getParameter('answererPHIDs', array());
|
||||||
|
|
||||||
|
$phids = array_merge($author_phids, $answerer_phids);
|
||||||
|
$handles = id(new PhabricatorObjectHandleData($phids))
|
||||||
|
->setViewer($this->requireViewer())
|
||||||
|
->loadHandles();
|
||||||
|
$tokens = mpull($handles, 'getFullName', 'getPHID');
|
||||||
|
|
||||||
|
$author_tokens = array_select_keys($tokens, $author_phids);
|
||||||
|
$answerer_tokens = array_select_keys($tokens, $answerer_phids);
|
||||||
|
|
||||||
|
$form
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTokenizerControl())
|
||||||
|
->setDatasource('/typeahead/common/users/')
|
||||||
|
->setName('authors')
|
||||||
|
->setLabel(pht('Authors'))
|
||||||
|
->setValue($author_tokens))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTokenizerControl())
|
||||||
|
->setDatasource('/typeahead/common/users/')
|
||||||
|
->setName('answerers')
|
||||||
|
->setLabel(pht('Answered By'))
|
||||||
|
->setValue($answerer_tokens));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getURI($path) {
|
||||||
|
return '/ponder/'.$path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBuiltinQueryNames() {
|
||||||
|
$names = array(
|
||||||
|
'all' => pht('All Questions'),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($this->requireViewer()->isLoggedIn()) {
|
||||||
|
$names['authored'] = pht('Authored');
|
||||||
|
$names['answered'] = pht('Answered');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $names;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildSavedQueryFromBuiltin($query_key) {
|
||||||
|
|
||||||
|
$query = $this->newSavedQuery();
|
||||||
|
$query->setQueryKey($query_key);
|
||||||
|
|
||||||
|
switch ($query_key) {
|
||||||
|
case 'all':
|
||||||
|
return $query;
|
||||||
|
case 'authored':
|
||||||
|
return $query->setParameter(
|
||||||
|
'authorPHIDs',
|
||||||
|
array($this->requireViewer()->getPHID()));
|
||||||
|
case 'answered':
|
||||||
|
return $query->setParameter(
|
||||||
|
'answererPHIDs',
|
||||||
|
array($this->requireViewer()->getPHID()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::buildSavedQueryFromBuiltin($query_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue