2012-08-10 19:44:04 +02:00
|
|
|
<?php
|
|
|
|
|
2012-12-12 03:03:16 +01:00
|
|
|
final class PonderQuestionQuery
|
|
|
|
extends PhabricatorCursorPagedPolicyAwareQuery {
|
2012-08-10 19:44:04 +02:00
|
|
|
|
2012-10-01 05:09:51 +02:00
|
|
|
const ORDER_CREATED = 'order-created';
|
|
|
|
const ORDER_HOTTEST = 'order-hottest';
|
2012-08-10 19:44:04 +02:00
|
|
|
|
2012-10-01 05:09:51 +02:00
|
|
|
private $ids;
|
|
|
|
private $phids;
|
|
|
|
private $authorPHIDs;
|
2013-07-18 21:40:51 +02:00
|
|
|
private $answererPHIDs;
|
2012-10-01 05:09:51 +02:00
|
|
|
private $order = self::ORDER_CREATED;
|
2012-08-10 19:44:04 +02:00
|
|
|
|
2013-07-28 03:37:17 +02:00
|
|
|
private $status = 'status-any';
|
|
|
|
const STATUS_ANY = 'status-any';
|
|
|
|
const STATUS_OPEN = 'status-open';
|
|
|
|
const STATUS_CLOSED = 'status-closed';
|
|
|
|
|
2013-07-29 00:59:53 +02:00
|
|
|
private $needAnswers;
|
2013-07-29 04:28:00 +02:00
|
|
|
private $needViewerVotes;
|
2013-07-29 00:59:53 +02:00
|
|
|
|
2012-10-01 05:09:51 +02:00
|
|
|
public function withIDs(array $ids) {
|
|
|
|
$this->ids = $ids;
|
2012-08-10 19:44:04 +02:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2012-10-01 05:09:51 +02:00
|
|
|
public function withPHIDs(array $phids) {
|
2012-08-10 19:44:04 +02:00
|
|
|
$this->phids = $phids;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2012-10-01 05:09:51 +02:00
|
|
|
public function withAuthorPHIDs(array $phids) {
|
|
|
|
$this->authorPHIDs = $phids;
|
2012-08-10 19:44:04 +02:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2013-07-28 03:37:17 +02:00
|
|
|
public function withStatus($status) {
|
|
|
|
$this->status = $status;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2013-07-18 21:40:51 +02:00
|
|
|
public function withAnswererPHIDs(array $phids) {
|
|
|
|
$this->answererPHIDs = $phids;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2013-07-29 00:59:53 +02:00
|
|
|
public function needAnswers($need_answers) {
|
|
|
|
$this->needAnswers = $need_answers;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2013-07-29 04:28:00 +02:00
|
|
|
public function needViewerVotes($need_viewer_votes) {
|
|
|
|
$this->needViewerVotes = $need_viewer_votes;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2012-10-01 05:09:51 +02:00
|
|
|
public function setOrder($order) {
|
|
|
|
$this->order = $order;
|
2012-08-10 19:44:04 +02:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2012-10-01 05:09:51 +02:00
|
|
|
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
|
2012-08-10 19:44:04 +02:00
|
|
|
$where = array();
|
2012-10-01 05:09:51 +02:00
|
|
|
|
|
|
|
if ($this->ids) {
|
2013-07-18 21:40:51 +02:00
|
|
|
$where[] = qsprintf(
|
|
|
|
$conn_r,
|
|
|
|
'q.id IN (%Ld)',
|
|
|
|
$this->ids);
|
2012-08-10 19:44:04 +02:00
|
|
|
}
|
2012-10-01 05:09:51 +02:00
|
|
|
|
2012-08-10 19:44:04 +02:00
|
|
|
if ($this->phids) {
|
2013-07-18 21:40:51 +02:00
|
|
|
$where[] = qsprintf(
|
|
|
|
$conn_r,
|
|
|
|
'q.phid IN (%Ls)',
|
|
|
|
$this->phids);
|
2012-08-10 19:44:04 +02:00
|
|
|
}
|
2012-10-01 05:09:51 +02:00
|
|
|
|
|
|
|
if ($this->authorPHIDs) {
|
2013-07-18 21:40:51 +02:00
|
|
|
$where[] = qsprintf(
|
|
|
|
$conn_r,
|
|
|
|
'q.authorPHID IN (%Ls)',
|
|
|
|
$this->authorPHIDs);
|
2012-08-10 19:44:04 +02:00
|
|
|
}
|
|
|
|
|
2013-07-28 03:37:17 +02:00
|
|
|
if ($this->status) {
|
|
|
|
switch ($this->status) {
|
|
|
|
case self::STATUS_ANY:
|
|
|
|
break;
|
|
|
|
case self::STATUS_OPEN:
|
|
|
|
$where[] = qsprintf(
|
|
|
|
$conn_r,
|
|
|
|
'q.status = %d',
|
|
|
|
PonderQuestionStatus::STATUS_OPEN);
|
|
|
|
break;
|
|
|
|
case self::STATUS_CLOSED:
|
|
|
|
$where[] = qsprintf(
|
|
|
|
$conn_r,
|
|
|
|
'q.status = %d',
|
|
|
|
PonderQuestionStatus::STATUS_CLOSED);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw new Exception("Unknown status query '{$this->status}'!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-12 03:03:16 +01:00
|
|
|
$where[] = $this->buildPagingClause($conn_r);
|
|
|
|
|
2012-10-01 05:09:51 +02:00
|
|
|
return $this->formatWhereClause($where);
|
2012-08-10 19:44:04 +02:00
|
|
|
}
|
|
|
|
|
2012-10-01 05:09:51 +02:00
|
|
|
private function buildOrderByClause(AphrontDatabaseConnection $conn_r) {
|
|
|
|
switch ($this->order) {
|
|
|
|
case self::ORDER_HOTTEST:
|
|
|
|
return qsprintf($conn_r, 'ORDER BY q.heat DESC, q.id DESC');
|
|
|
|
case self::ORDER_CREATED:
|
|
|
|
return qsprintf($conn_r, 'ORDER BY q.id DESC');
|
|
|
|
default:
|
|
|
|
throw new Exception("Unknown order '{$this->order}'!");
|
2012-08-10 19:44:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-01 20:28:02 +01:00
|
|
|
protected function loadPage() {
|
2012-08-10 19:44:04 +02:00
|
|
|
$question = new PonderQuestion();
|
|
|
|
$conn_r = $question->establishConnection('r');
|
|
|
|
|
2013-07-18 21:40:51 +02:00
|
|
|
$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->buildOrderByClause($conn_r),
|
|
|
|
$this->buildLimitClause($conn_r));
|
2012-08-10 19:44:04 +02:00
|
|
|
|
2013-07-18 21:40:51 +02:00
|
|
|
return $question->loadAllFromArray($data);
|
2012-08-10 19:44:04 +02:00
|
|
|
}
|
|
|
|
|
2013-07-29 00:59:53 +02:00
|
|
|
public function willFilterPage(array $questions) {
|
|
|
|
if ($this->needAnswers) {
|
2013-07-29 04:28:00 +02:00
|
|
|
$aquery = id(new PonderAnswerQuery())
|
2013-07-29 00:59:53 +02:00
|
|
|
->setViewer($this->getViewer())
|
2013-07-29 04:28:00 +02:00
|
|
|
->withQuestionIDs(mpull($questions, 'getID'));
|
|
|
|
|
|
|
|
if ($this->needViewerVotes) {
|
|
|
|
$aquery->needViewerVotes($this->needViewerVotes);
|
|
|
|
}
|
|
|
|
|
|
|
|
$answers = $aquery->execute();
|
2013-07-29 00:59:53 +02:00
|
|
|
$answers = mgroup($answers, 'getQuestionID');
|
|
|
|
|
|
|
|
foreach ($questions as $question) {
|
|
|
|
$question->attachAnswers(idx($answers, $question->getID(), array()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-29 04:28:00 +02:00
|
|
|
if ($this->needViewerVotes) {
|
|
|
|
$viewer_phid = $this->getViewer()->getPHID();
|
|
|
|
|
|
|
|
$etype = PhabricatorEdgeConfig::TYPE_QUESTION_HAS_VOTING_USER;
|
|
|
|
$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));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-29 00:59:53 +02:00
|
|
|
return $questions;
|
|
|
|
}
|
|
|
|
|
2013-07-18 21:40:51 +02:00
|
|
|
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);
|
|
|
|
}
|
2012-08-10 19:44:04 +02:00
|
|
|
|
|
|
|
}
|