Changeset View
Changeset View
Standalone View
Standalone View
src/applications/project/query/PhabricatorProjectQuery.php
<?php | <?php | ||||
final class PhabricatorProjectQuery | final class PhabricatorProjectQuery | ||||
extends PhabricatorCursorPagedPolicyAwareQuery { | extends PhabricatorCursorPagedPolicyAwareQuery { | ||||
private $ids; | private $ids; | ||||
private $phids; | private $phids; | ||||
private $memberPHIDs; | private $memberPHIDs; | ||||
private $slugs; | private $slugs; | ||||
private $slugNormals; | |||||
private $slugMap; | |||||
private $names; | private $names; | ||||
private $nameTokens; | private $nameTokens; | ||||
private $icons; | private $icons; | ||||
private $colors; | private $colors; | ||||
private $ancestorPHIDs; | private $ancestorPHIDs; | ||||
private $parentPHIDs; | private $parentPHIDs; | ||||
private $isMilestone; | private $isMilestone; | ||||
private $hasSubprojects; | private $hasSubprojects; | ||||
▲ Show 20 Lines • Show All 134 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(), | ||||
); | ); | ||||
} | } | ||||
public function getSlugMap() { | |||||
if ($this->slugMap === null) { | |||||
throw new PhutilInvalidStateException('execute'); | |||||
} | |||||
return $this->slugMap; | |||||
} | |||||
protected function willExecute() { | |||||
$this->slugMap = array(); | |||||
$this->slugNormals = array(); | |||||
if ($this->slugs) { | |||||
foreach ($this->slugs as $slug) { | |||||
$normal = PhabricatorSlug::normalizeProjectSlug($slug); | |||||
$this->slugNormals[$slug] = $normal; | |||||
} | |||||
} | |||||
} | |||||
protected function loadPage() { | protected function loadPage() { | ||||
return $this->loadStandardPage($this->newResultObject()); | return $this->loadStandardPage($this->newResultObject()); | ||||
} | } | ||||
protected function willFilterPage(array $projects) { | protected function willFilterPage(array $projects) { | ||||
$ancestor_paths = array(); | $ancestor_paths = array(); | ||||
foreach ($projects as $project) { | foreach ($projects as $project) { | ||||
foreach ($project->getAncestorProjectPaths() as $path) { | foreach ($project->getAncestorProjectPaths() as $path) { | ||||
▲ Show 20 Lines • Show All 114 Lines • ▼ Show 20 Lines | if ($this->needImages) { | ||||
'project.png'); | 'project.png'); | ||||
} | } | ||||
$file = $default; | $file = $default; | ||||
} | } | ||||
$project->attachProfileImageFile($file); | $project->attachProfileImageFile($file); | ||||
} | } | ||||
} | } | ||||
if ($this->needSlugs) { | $this->loadSlugs($projects); | ||||
$slugs = id(new PhabricatorProjectSlug()) | |||||
->loadAllWhere( | |||||
'projectPHID IN (%Ls)', | |||||
mpull($projects, 'getPHID')); | |||||
$slugs = mgroup($slugs, 'getProjectPHID'); | |||||
foreach ($projects as $project) { | |||||
$project_slugs = idx($slugs, $project->getPHID(), array()); | |||||
$project->attachSlugs($project_slugs); | |||||
} | |||||
} | |||||
return $projects; | return $projects; | ||||
} | } | ||||
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) { | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | if ($this->memberPHIDs !== null) { | ||||
'e.dst IN (%Ls)', | 'e.dst IN (%Ls)', | ||||
$this->memberPHIDs); | $this->memberPHIDs); | ||||
} | } | ||||
if ($this->slugs !== null) { | if ($this->slugs !== null) { | ||||
$where[] = qsprintf( | $where[] = qsprintf( | ||||
$conn, | $conn, | ||||
'slug.slug IN (%Ls)', | 'slug.slug IN (%Ls)', | ||||
$this->slugs); | $this->slugNormals); | ||||
} | } | ||||
if ($this->names !== null) { | if ($this->names !== null) { | ||||
$where[] = qsprintf( | $where[] = qsprintf( | ||||
$conn, | $conn, | ||||
'name IN (%Ls)', | 'name IN (%Ls)', | ||||
$this->names); | $this->names); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 210 Lines • ▼ Show 20 Lines | while ($stack) { | ||||
$seen[$parent_phid] = true; | $seen[$parent_phid] = true; | ||||
$stack[] = $project->getParentProject(); | $stack[] = $project->getParentProject(); | ||||
} | } | ||||
return $ancestors; | return $ancestors; | ||||
} | } | ||||
private function loadSlugs(array $projects) { | |||||
// Build a map from primary slugs to projects. | |||||
$primary_map = array(); | |||||
foreach ($projects as $project) { | |||||
$primary_slug = $project->getPrimarySlug(); | |||||
if ($primary_slug === null) { | |||||
continue; | |||||
} | |||||
$primary_map[$primary_slug] = $project; | |||||
} | |||||
// Link up all of the queried slugs which correspond to primary | |||||
// slugs. If we can link up everything from this (no slugs were queried, | |||||
// or only primary slugs were queried) we don't need to load anything | |||||
// else. | |||||
$unknown = $this->slugNormals; | |||||
foreach ($unknown as $input => $normal) { | |||||
if (!isset($primary_map[$normal])) { | |||||
continue; | |||||
} | |||||
$this->slugMap[$input] = array( | |||||
'slug' => $normal, | |||||
'projectPHID' => $primary_map[$normal]->getPHID(), | |||||
); | |||||
unset($unknown[$input]); | |||||
} | |||||
// If we need slugs, we have to load everything. | |||||
// If we still have some queried slugs which we haven't mapped, we only | |||||
// need to look for them. | |||||
// If we've mapped everything, we don't have to do any work. | |||||
$project_phids = mpull($projects, 'getPHID'); | |||||
if ($this->needSlugs) { | |||||
$slugs = id(new PhabricatorProjectSlug())->loadAllWhere( | |||||
'projectPHID IN (%Ls)', | |||||
$project_phids); | |||||
} else if ($unknown) { | |||||
$slugs = id(new PhabricatorProjectSlug())->loadAllWhere( | |||||
'projectPHID IN (%Ls) AND slug IN (%Ls)', | |||||
$project_phids, | |||||
$unknown); | |||||
} else { | |||||
$slugs = array(); | |||||
} | |||||
// Link up any slugs we were not able to link up earlier. | |||||
$extra_map = mpull($slugs, 'getProjectPHID', 'getSlug'); | |||||
foreach ($unknown as $input => $normal) { | |||||
if (!isset($extra_map[$normal])) { | |||||
continue; | |||||
} | |||||
$this->slugMap[$input] = array( | |||||
'slug' => $normal, | |||||
'projectPHID' => $extra_map[$normal], | |||||
); | |||||
unset($unknown[$input]); | |||||
} | |||||
if ($this->needSlugs) { | |||||
$slug_groups = mgroup($slugs, 'getProjectPHID'); | |||||
foreach ($projects as $project) { | |||||
$project_slugs = idx($slug_groups, $project->getPHID(), array()); | |||||
$project->attachSlugs($project_slugs); | |||||
} | |||||
} | |||||
} | |||||
} | } |