[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/ponder/query/ -> PonderQuestionQuery.php (source)

   1  <?php
   2  
   3  final class PonderQuestionQuery
   4    extends PhabricatorCursorPagedPolicyAwareQuery {
   5  
   6    const ORDER_CREATED = 'order-created';
   7    const ORDER_HOTTEST = 'order-hottest';
   8  
   9    private $ids;
  10    private $phids;
  11    private $authorPHIDs;
  12    private $answererPHIDs;
  13    private $order = self::ORDER_CREATED;
  14  
  15    private $status = 'status-any';
  16    const STATUS_ANY      = 'status-any';
  17    const STATUS_OPEN     = 'status-open';
  18    const STATUS_CLOSED   = 'status-closed';
  19  
  20    private $needAnswers;
  21    private $needViewerVotes;
  22  
  23    public function withIDs(array $ids) {
  24      $this->ids = $ids;
  25      return $this;
  26    }
  27  
  28    public function withPHIDs(array $phids) {
  29      $this->phids = $phids;
  30      return $this;
  31    }
  32  
  33    public function withAuthorPHIDs(array $phids) {
  34      $this->authorPHIDs = $phids;
  35      return $this;
  36    }
  37  
  38    public function withStatus($status) {
  39      $this->status = $status;
  40      return $this;
  41    }
  42  
  43    public function withAnswererPHIDs(array $phids) {
  44      $this->answererPHIDs = $phids;
  45      return $this;
  46    }
  47  
  48    public function needAnswers($need_answers) {
  49      $this->needAnswers = $need_answers;
  50      return $this;
  51    }
  52  
  53    public function needViewerVotes($need_viewer_votes) {
  54      $this->needViewerVotes = $need_viewer_votes;
  55      return $this;
  56    }
  57  
  58    public function setOrder($order) {
  59      $this->order = $order;
  60      return $this;
  61    }
  62  
  63    private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
  64      $where = array();
  65  
  66      if ($this->ids) {
  67        $where[] = qsprintf(
  68          $conn_r,
  69          'q.id IN (%Ld)',
  70          $this->ids);
  71      }
  72  
  73      if ($this->phids) {
  74        $where[] = qsprintf(
  75          $conn_r,
  76          'q.phid IN (%Ls)',
  77          $this->phids);
  78      }
  79  
  80      if ($this->authorPHIDs) {
  81        $where[] = qsprintf(
  82          $conn_r,
  83          'q.authorPHID IN (%Ls)',
  84          $this->authorPHIDs);
  85      }
  86  
  87      if ($this->status) {
  88        switch ($this->status) {
  89          case self::STATUS_ANY:
  90            break;
  91          case self::STATUS_OPEN:
  92            $where[] = qsprintf(
  93              $conn_r,
  94              'q.status = %d',
  95              PonderQuestionStatus::STATUS_OPEN);
  96            break;
  97          case self::STATUS_CLOSED:
  98            $where[] = qsprintf(
  99              $conn_r,
 100              'q.status = %d',
 101              PonderQuestionStatus::STATUS_CLOSED);
 102            break;
 103          default:
 104            throw new Exception("Unknown status query '{$this->status}'!");
 105        }
 106      }
 107  
 108      $where[] = $this->buildPagingClause($conn_r);
 109  
 110      return $this->formatWhereClause($where);
 111    }
 112  
 113    private function buildOrderByClause(AphrontDatabaseConnection $conn_r) {
 114      switch ($this->order) {
 115        case self::ORDER_HOTTEST:
 116          return qsprintf($conn_r, 'ORDER BY q.heat DESC, q.id DESC');
 117        case self::ORDER_CREATED:
 118          return qsprintf($conn_r, 'ORDER BY q.id DESC');
 119        default:
 120          throw new Exception("Unknown order '{$this->order}'!");
 121      }
 122    }
 123  
 124    protected function loadPage() {
 125      $question = new PonderQuestion();
 126      $conn_r = $question->establishConnection('r');
 127  
 128      $data = queryfx_all(
 129        $conn_r,
 130        'SELECT q.* FROM %T q %Q %Q %Q %Q',
 131        $question->getTableName(),
 132        $this->buildJoinsClause($conn_r),
 133        $this->buildWhereClause($conn_r),
 134        $this->buildOrderByClause($conn_r),
 135        $this->buildLimitClause($conn_r));
 136  
 137      return $question->loadAllFromArray($data);
 138    }
 139  
 140    public function willFilterPage(array $questions) {
 141      if ($this->needAnswers) {
 142        $aquery = id(new PonderAnswerQuery())
 143          ->setViewer($this->getViewer())
 144          ->withQuestionIDs(mpull($questions, 'getID'));
 145  
 146        if ($this->needViewerVotes) {
 147          $aquery->needViewerVotes($this->needViewerVotes);
 148        }
 149  
 150        $answers = $aquery->execute();
 151        $answers = mgroup($answers, 'getQuestionID');
 152  
 153        foreach ($questions as $question) {
 154          $question_answers = idx($answers, $question->getID(), array());
 155          $question->attachAnswers(mpull($question_answers, null, 'getPHID'));
 156        }
 157      }
 158  
 159      if ($this->needViewerVotes) {
 160        $viewer_phid = $this->getViewer()->getPHID();
 161  
 162        $etype = PhabricatorEdgeConfig::TYPE_QUESTION_HAS_VOTING_USER;
 163        $edges = id(new PhabricatorEdgeQuery())
 164          ->withSourcePHIDs(mpull($questions, 'getPHID'))
 165          ->withDestinationPHIDs(array($viewer_phid))
 166          ->withEdgeTypes(array($etype))
 167          ->needEdgeData(true)
 168          ->execute();
 169        foreach ($questions as $question) {
 170          $user_edge = idx(
 171            $edges[$question->getPHID()][$etype],
 172            $viewer_phid,
 173            array());
 174  
 175          $question->attachUserVote($viewer_phid, idx($user_edge, 'data', 0));
 176        }
 177      }
 178  
 179      return $questions;
 180    }
 181  
 182    private function buildJoinsClause(AphrontDatabaseConnection $conn_r) {
 183      $joins = array();
 184  
 185      if ($this->answererPHIDs) {
 186        $answer_table = new PonderAnswer();
 187        $joins[] = qsprintf(
 188          $conn_r,
 189          'JOIN %T a ON a.questionID = q.id AND a.authorPHID IN (%Ls)',
 190          $answer_table->getTableName(),
 191          $this->answererPHIDs);
 192      }
 193  
 194      return implode(' ', $joins);
 195    }
 196  
 197    public function getQueryApplicationClass() {
 198      return 'PhabricatorPonderApplication';
 199    }
 200  
 201  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1