Changeset View
Changeset View
Standalone View
Standalone View
src/applications/project/query/PhabricatorProjectQuery.php
Show First 20 Lines • Show All 120 Lines • ▼ Show 20 Lines | final class PhabricatorProjectQuery | ||||
protected function getPagingValueMap($cursor, array $keys) { | protected function getPagingValueMap($cursor, array $keys) { | ||||
$project = $this->loadCursorObject($cursor); | $project = $this->loadCursorObject($cursor); | ||||
return array( | return array( | ||||
'name' => $project->getName(), | 'name' => $project->getName(), | ||||
); | ); | ||||
} | } | ||||
protected function loadPage() { | protected function loadPage() { | ||||
$table = new PhabricatorProject(); | return $this->loadStandardPage($this->newResultObject()); | ||||
$data = $this->loadStandardPageRows($table); | } | ||||
$projects = $table->loadAllFromArray($data); | |||||
if ($projects) { | protected function willFilterPage(array $projects) { | ||||
$viewer_phid = $this->getViewer()->getPHID(); | $viewer_phid = $this->getViewer()->getPHID(); | ||||
$project_phids = mpull($projects, 'getPHID'); | $project_phids = mpull($projects, 'getPHID'); | ||||
$member_type = PhabricatorProjectProjectHasMemberEdgeType::EDGECONST; | $member_type = PhabricatorProjectProjectHasMemberEdgeType::EDGECONST; | ||||
$watcher_type = PhabricatorObjectHasWatcherEdgeType::EDGECONST; | $watcher_type = PhabricatorObjectHasWatcherEdgeType::EDGECONST; | ||||
$need_edge_types = array(); | $types = array(); | ||||
if ($this->needMembers) { | $types[] = $member_type; | ||||
$need_edge_types[] = $member_type; | |||||
} else { | |||||
foreach ($data as $row) { | |||||
$projects[$row['id']]->setIsUserMember( | |||||
$viewer_phid, | |||||
($row['viewerIsMember'] !== null)); | |||||
} | |||||
} | |||||
if ($this->needWatchers) { | if ($this->needWatchers) { | ||||
$need_edge_types[] = $watcher_type; | $types[] = $watcher_type; | ||||
} | } | ||||
if ($need_edge_types) { | $edge_query = id(new PhabricatorEdgeQuery()) | ||||
$edges = id(new PhabricatorEdgeQuery()) | |||||
->withSourcePHIDs($project_phids) | ->withSourcePHIDs($project_phids) | ||||
->withEdgeTypes($need_edge_types) | ->withEdgeTypes($types); | ||||
->execute(); | |||||
// If we only need to know if the viewer is a member, we can restrict | |||||
// the query to just their PHID. | |||||
if (!$this->needMembers && !$this->needWatchers) { | |||||
$edge_query->withDestinationPHIDs(array($viewer_phid)); | |||||
} | |||||
$edge_query->execute(); | |||||
if ($this->needMembers) { | |||||
foreach ($projects as $project) { | foreach ($projects as $project) { | ||||
$phid = $project->getPHID(); | $project_phid = $project->getPHID(); | ||||
$project->attachMemberPHIDs( | |||||
array_keys($edges[$phid][$member_type])); | $member_phids = $edge_query->getDestinationPHIDs( | ||||
array($project_phid), | |||||
array($member_type)); | |||||
$project->setIsUserMember( | $project->setIsUserMember( | ||||
$viewer_phid, | $viewer_phid, | ||||
isset($edges[$phid][$member_type][$viewer_phid])); | in_array($viewer_phid, $member_phids)); | ||||
} | |||||
if ($this->needMembers) { | |||||
$project->attachMemberPHIDs($member_phids); | |||||
} | } | ||||
if ($this->needWatchers) { | if ($this->needWatchers) { | ||||
foreach ($projects as $project) { | $watcher_phids = $edge_query->getDestinationPHIDs( | ||||
$phid = $project->getPHID(); | array($project_phid), | ||||
$project->attachWatcherPHIDs( | array($watcher_type)); | ||||
array_keys($edges[$phid][$watcher_type])); | $project->attachWatcherPHIDs($watcher_phids); | ||||
$project->setIsUserWatcher( | $project->setIsUserWatcher( | ||||
$viewer_phid, | $viewer_phid, | ||||
isset($edges[$phid][$watcher_type][$viewer_phid])); | in_array($viewer_phid, $watcher_phids)); | ||||
} | |||||
} | |||||
} | } | ||||
} | } | ||||
return $projects; | return $projects; | ||||
} | } | ||||
protected function didFilterPage(array $projects) { | protected function didFilterPage(array $projects) { | ||||
if ($this->needImages) { | if ($this->needImages) { | ||||
Show All 36 Lines | if ($this->needSlugs) { | ||||
$project_slugs = idx($slugs, $project->getPHID(), array()); | $project_slugs = idx($slugs, $project->getPHID(), array()); | ||||
$project->attachSlugs($project_slugs); | $project->attachSlugs($project_slugs); | ||||
} | } | ||||
} | } | ||||
return $projects; | return $projects; | ||||
} | } | ||||
protected function buildSelectClauseParts(AphrontDatabaseConnection $conn) { | |||||
$select = parent::buildSelectClauseParts($conn); | |||||
// NOTE: Because visibility checks for projects depend on whether or not | |||||
// the user is a project member, we always load their membership. If we're | |||||
// loading all members anyway we can piggyback on that; otherwise we | |||||
// do an explicit join. | |||||
if (!$this->needMembers) { | |||||
$select[] = 'vm.dst viewerIsMember'; | |||||
} | |||||
return $select; | |||||
} | |||||
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { | protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { | ||||
$where = parent::buildWhereClauseParts($conn); | $where = parent::buildWhereClauseParts($conn); | ||||
if ($this->status != self::STATUS_ANY) { | if ($this->status != self::STATUS_ANY) { | ||||
switch ($this->status) { | switch ($this->status) { | ||||
case self::STATUS_OPEN: | case self::STATUS_OPEN: | ||||
case self::STATUS_ACTIVE: | case self::STATUS_ACTIVE: | ||||
$filter = array( | $filter = array( | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | if ($this->memberPHIDs || $this->nameTokens) { | ||||
return true; | return true; | ||||
} | } | ||||
return parent::shouldGroupQueryResultRows(); | return parent::shouldGroupQueryResultRows(); | ||||
} | } | ||||
protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { | protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { | ||||
$joins = parent::buildJoinClauseParts($conn); | $joins = parent::buildJoinClauseParts($conn); | ||||
if (!$this->needMembers !== null) { | |||||
$joins[] = qsprintf( | |||||
$conn, | |||||
'LEFT JOIN %T vm ON vm.src = p.phid AND vm.type = %d AND vm.dst = %s', | |||||
PhabricatorEdgeConfig::TABLE_NAME_EDGE, | |||||
PhabricatorProjectProjectHasMemberEdgeType::EDGECONST, | |||||
$this->getViewer()->getPHID()); | |||||
} | |||||
if ($this->memberPHIDs !== null) { | if ($this->memberPHIDs !== null) { | ||||
$joins[] = qsprintf( | $joins[] = qsprintf( | ||||
$conn, | $conn, | ||||
'JOIN %T e ON e.src = p.phid AND e.type = %d', | 'JOIN %T e ON e.src = p.phid AND e.type = %d', | ||||
PhabricatorEdgeConfig::TABLE_NAME_EDGE, | PhabricatorEdgeConfig::TABLE_NAME_EDGE, | ||||
PhabricatorProjectProjectHasMemberEdgeType::EDGECONST); | PhabricatorProjectProjectHasMemberEdgeType::EDGECONST); | ||||
} | } | ||||
Show All 33 Lines |