*/ final class DifferentialDiffQuery extends PhabricatorCursorPagedPolicyAwareQuery { private $ids; private $phids; private $revisionIDs; private $revisionPHIDs; private $commitPHIDs; private $hasRevision; private $needChangesets = false; private $needProperties; public function withIDs(array $ids) { $this->ids = $ids; return $this; } public function withPHIDs(array $phids) { $this->phids = $phids; return $this; } public function withRevisionIDs(array $revision_ids) { $this->revisionIDs = $revision_ids; return $this; } public function withRevisionPHIDs(array $revision_phids) { $this->revisionPHIDs = $revision_phids; return $this; } public function withCommitPHIDs(array $phids) { $this->commitPHIDs = $phids; return $this; } public function withHasRevision($has_revision) { $this->hasRevision = $has_revision; return $this; } public function needChangesets($bool) { $this->needChangesets = $bool; return $this; } public function needProperties($need_properties) { $this->needProperties = $need_properties; return $this; } public function newResultObject() { return new DifferentialDiff(); } protected function willFilterPage(array $diffs) { $revision_ids = array_filter(mpull($diffs, 'getRevisionID')); $revisions = array(); if ($revision_ids) { $revisions = id(new DifferentialRevisionQuery()) ->setViewer($this->getViewer()) ->withIDs($revision_ids) ->execute(); } foreach ($diffs as $key => $diff) { if (!$diff->getRevisionID()) { continue; } $revision = idx($revisions, $diff->getRevisionID()); if ($revision) { $diff->attachRevision($revision); continue; } unset($diffs[$key]); } if ($diffs && $this->needChangesets) { $diffs = $this->loadChangesets($diffs); } return $diffs; } protected function didFilterPage(array $diffs) { if ($this->needProperties) { $properties = id(new DifferentialDiffProperty())->loadAllWhere( 'diffID IN (%Ld)', mpull($diffs, 'getID')); $properties = mgroup($properties, 'getDiffID'); foreach ($diffs as $diff) { $map = idx($properties, $diff->getID(), array()); $map = mpull($map, 'getData', 'getName'); $diff->attachDiffProperties($map); } } return $diffs; } private function loadChangesets(array $diffs) { id(new DifferentialChangesetQuery()) ->setViewer($this->getViewer()) ->setParentQuery($this) ->withDiffs($diffs) ->needAttachToDiffs(true) ->needHunks(true) ->execute(); return $diffs; } protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { $where = parent::buildWhereClauseParts($conn); if ($this->ids !== null) { $where[] = qsprintf( $conn, 'id IN (%Ld)', $this->ids); } if ($this->phids !== null) { $where[] = qsprintf( $conn, 'phid IN (%Ls)', $this->phids); } if ($this->revisionIDs !== null) { $where[] = qsprintf( $conn, 'revisionID IN (%Ld)', $this->revisionIDs); } if ($this->commitPHIDs !== null) { $where[] = qsprintf( $conn, 'commitPHID IN (%Ls)', $this->commitPHIDs); } if ($this->hasRevision !== null) { if ($this->hasRevision) { $where[] = qsprintf( $conn, 'revisionID IS NOT NULL'); } else { $where[] = qsprintf( $conn, 'revisionID IS NULL'); } } if ($this->revisionPHIDs !== null) { $viewer = $this->getViewer(); $revisions = id(new DifferentialRevisionQuery()) ->setViewer($viewer) ->setParentQuery($this) ->withPHIDs($this->revisionPHIDs) ->execute(); $revision_ids = mpull($revisions, 'getID'); if (!$revision_ids) { throw new PhabricatorEmptyQueryException(); } $where[] = qsprintf( $conn, 'revisionID IN (%Ls)', $revision_ids); } return $where; } public function getQueryApplicationClass() { return PhabricatorDifferentialApplication::class; } }