diff --git a/src/applications/ponder/query/PonderAnswerQuery.php b/src/applications/ponder/query/PonderAnswerQuery.php index 0fe61bc9e1..be9c42c5ea 100644 --- a/src/applications/ponder/query/PonderAnswerQuery.php +++ b/src/applications/ponder/query/PonderAnswerQuery.php @@ -1,125 +1,116 @@ ids = $ids; return $this; } public function withPHIDs(array $phids) { $this->phids = $phids; return $this; } public function withAuthorPHIDs(array $phids) { $this->authorPHIDs = $phids; return $this; } public function withQuestionIDs(array $ids) { $this->questionIDs = $ids; return $this; } public function needViewerVotes($need_viewer_votes) { $this->needViewerVotes = $need_viewer_votes; return $this; } - protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { - $where = array(); + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { + $where = parent::buildWhereClauseParts($conn); - if ($this->ids) { + if ($this->ids !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'id IN (%Ld)', $this->ids); } - if ($this->phids) { + if ($this->phids !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'phid IN (%Ls)', $this->phids); } - if ($this->authorPHIDs) { + if ($this->authorPHIDs !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'authorPHID IN (%Ls)', $this->authorPHIDs); } - $where[] = $this->buildPagingClause($conn_r); + return $where; + } - return $this->formatWhereClause($where); + public function newResultObject() { + return new PonderAnswer(); } protected function loadPage() { - $answer = new PonderAnswer(); - $conn_r = $answer->establishConnection('r'); - - $data = queryfx_all( - $conn_r, - 'SELECT a.* FROM %T a %Q %Q %Q', - $answer->getTableName(), - $this->buildWhereClause($conn_r), - $this->buildOrderClause($conn_r), - $this->buildLimitClause($conn_r)); - - return $answer->loadAllFromArray($data); + return $this->loadStandardPage(new PonderAnswer()); } protected function willFilterPage(array $answers) { $questions = id(new PonderQuestionQuery()) ->setViewer($this->getViewer()) ->withIDs(mpull($answers, 'getQuestionID')) ->execute(); foreach ($answers as $key => $answer) { $question = idx($questions, $answer->getQuestionID()); if (!$question) { unset($answers[$key]); continue; } $answer->attachQuestion($question); } if ($this->needViewerVotes) { $viewer_phid = $this->getViewer()->getPHID(); $etype = PonderAnswerHasVotingUserEdgeType::EDGECONST; $edges = id(new PhabricatorEdgeQuery()) ->withSourcePHIDs(mpull($answers, 'getPHID')) ->withDestinationPHIDs(array($viewer_phid)) ->withEdgeTypes(array($etype)) ->needEdgeData(true) ->execute(); foreach ($answers as $answer) { $user_edge = idx( $edges[$answer->getPHID()][$etype], $viewer_phid, array()); $answer->attachUserVote($viewer_phid, idx($user_edge, 'data', 0)); } } return $answers; } public function getQueryApplicationClass() { return 'PhabricatorPonderApplication'; } } diff --git a/src/applications/ponder/query/PonderQuestionQuery.php b/src/applications/ponder/query/PonderQuestionQuery.php index b63ba60def..78bc42a7d3 100644 --- a/src/applications/ponder/query/PonderQuestionQuery.php +++ b/src/applications/ponder/query/PonderQuestionQuery.php @@ -1,182 +1,177 @@ ids = $ids; return $this; } public function withPHIDs(array $phids) { $this->phids = $phids; return $this; } public function withAuthorPHIDs(array $phids) { $this->authorPHIDs = $phids; return $this; } public function withStatus($status) { $this->status = $status; return $this; } public function withAnswererPHIDs(array $phids) { $this->answererPHIDs = $phids; return $this; } public function needAnswers($need_answers) { $this->needAnswers = $need_answers; return $this; } public function needViewerVotes($need_viewer_votes) { $this->needViewerVotes = $need_viewer_votes; return $this; } - protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { - $where = array(); + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { + $where = parent::buildWhereClauseParts($conn); - if ($this->ids) { + if ($this->ids !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'q.id IN (%Ld)', $this->ids); } - if ($this->phids) { + if ($this->phids !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'q.phid IN (%Ls)', $this->phids); } - if ($this->authorPHIDs) { + if ($this->authorPHIDs !== null) { $where[] = qsprintf( - $conn_r, + $conn, 'q.authorPHID IN (%Ls)', $this->authorPHIDs); } - if ($this->status) { + if ($this->status !== null) { switch ($this->status) { case self::STATUS_ANY: break; case self::STATUS_OPEN: $where[] = qsprintf( - $conn_r, + $conn, 'q.status = %d', PonderQuestionStatus::STATUS_OPEN); break; case self::STATUS_CLOSED: $where[] = qsprintf( - $conn_r, + $conn, 'q.status = %d', PonderQuestionStatus::STATUS_CLOSED); break; default: throw new Exception(pht("Unknown status query '%s'!", $this->status)); } } - $where[] = $this->buildPagingClause($conn_r); + return $where; + } - return $this->formatWhereClause($where); + public function newResultObject() { + return new PonderQuestion(); } 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); + return $this->loadStandardPage(new PonderQuestion()); } protected function willFilterPage(array $questions) { if ($this->needAnswers) { $aquery = id(new PonderAnswerQuery()) ->setViewer($this->getViewer()) ->setOrderVector(array('-id')) ->withQuestionIDs(mpull($questions, 'getID')); if ($this->needViewerVotes) { $aquery->needViewerVotes($this->needViewerVotes); } $answers = $aquery->execute(); $answers = mgroup($answers, 'getQuestionID'); foreach ($questions as $question) { $question_answers = idx($answers, $question->getID(), array()); $question->attachAnswers(mpull($question_answers, null, 'getPHID')); } } if ($this->needViewerVotes) { $viewer_phid = $this->getViewer()->getPHID(); $etype = PonderQuestionHasVotingUserEdgeType::EDGECONST; $edges = id(new PhabricatorEdgeQuery()) ->withSourcePHIDs(mpull($questions, 'getPHID')) ->withDestinationPHIDs(array($viewer_phid)) ->withEdgeTypes(array($etype)) ->needEdgeData(true) ->execute(); foreach ($questions as $question) { $user_edge = idx( $edges[$question->getPHID()][$etype], $viewer_phid, array()); $question->attachUserVote($viewer_phid, idx($user_edge, 'data', 0)); } } return $questions; } 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); } + protected function getPrimaryTableAlias() { + return 'q'; + } + public function getQueryApplicationClass() { return 'PhabricatorPonderApplication'; } } diff --git a/src/applications/ponder/query/PonderQuestionSearchEngine.php b/src/applications/ponder/query/PonderQuestionSearchEngine.php index 18a2a80e1a..885e39bbf9 100644 --- a/src/applications/ponder/query/PonderQuestionSearchEngine.php +++ b/src/applications/ponder/query/PonderQuestionSearchEngine.php @@ -1,180 +1,152 @@ setParameter( - 'authorPHIDs', - $this->readUsersFromRequest($request, 'authors')); - - $saved->setParameter( - 'answererPHIDs', - $this->readUsersFromRequest($request, 'answerers')); - - $saved->setParameter('status', $request->getStr('status')); - - return $saved; + public function newQuery() { + return new PonderQuestionQuery(); } - public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { - $query = id(new PonderQuestionQuery()); + protected function buildQueryFromParameters(array $map) { + $query = $this->newQuery(); - $author_phids = $saved->getParameter('authorPHIDs'); - if ($author_phids) { - $query->withAuthorPHIDs($author_phids); + if ($map['authorPHIDs']) { + $query->withAuthorPHIDs($map['authorPHIDs']); } - $answerer_phids = $saved->getParameter('answererPHIDs'); - if ($answerer_phids) { - $query->withAnswererPHIDs($answerer_phids); + if ($map['answerers']) { + $query->withAnswererPHIDs($map['answerers']); } - $status = $saved->getParameter('status'); + $status = $map['status']; if ($status != null) { switch ($status) { case 0: $query->withStatus(PonderQuestionQuery::STATUS_OPEN); break; case 1: $query->withStatus(PonderQuestionQuery::STATUS_CLOSED); break; } } return $query; } - public function buildSearchForm( - AphrontFormView $form, - PhabricatorSavedQuery $saved_query) { - - $author_phids = $saved_query->getParameter('authorPHIDs', array()); - $answerer_phids = $saved_query->getParameter('answererPHIDs', array()); - $status = $saved_query->getParameter( - 'status', PonderQuestionStatus::STATUS_OPEN); - - $form - ->appendControl( - id(new AphrontFormTokenizerControl()) - ->setDatasource(new PhabricatorPeopleDatasource()) - ->setName('authors') - ->setLabel(pht('Authors')) - ->setValue($author_phids)) - ->appendControl( - id(new AphrontFormTokenizerControl()) - ->setDatasource(new PhabricatorPeopleDatasource()) - ->setName('answerers') - ->setLabel(pht('Answered By')) - ->setValue($answerer_phids)) - ->appendChild( - id(new AphrontFormSelectControl()) - ->setLabel(pht('Status')) - ->setName('status') - ->setValue($status) - ->setOptions(PonderQuestionStatus::getQuestionStatusMap())); + protected function buildCustomSearchFields() { + return array( + id(new PhabricatorUsersSearchField()) + ->setKey('authorPHIDs') + ->setAliases(array('authors')) + ->setLabel(pht('Authors')), + id(new PhabricatorUsersSearchField()) + ->setKey('answerers') + ->setAliases(array('answerers')) + ->setLabel(pht('Answered By')), + id(new PhabricatorSearchSelectField()) + ->setLabel(pht('Status')) + ->setKey('status') + ->setOptions(PonderQuestionStatus::getQuestionStatusMap()), + ); } protected function getURI($path) { return '/ponder/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'open' => pht('Open Questions'), '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 'open': return $query->setParameter('status', PonderQuestionQuery::STATUS_OPEN); 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); } protected function getRequiredHandlePHIDsForResultList( array $questions, PhabricatorSavedQuery $query) { return mpull($questions, 'getAuthorPHID'); } 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; } }