Changeset View
Changeset View
Standalone View
Standalone View
src/applications/differential/query/DifferentialRevisionQuery.php
Show First 20 Lines • Show All 525 Lines • ▼ Show 20 Lines | private function loadData() { | ||||
// NOTE: If the query includes "responsiblePHIDs", we execute it as a | // NOTE: If the query includes "responsiblePHIDs", we execute it as a | ||||
// UNION of revisions they own and revisions they're reviewing. This has | // UNION of revisions they own and revisions they're reviewing. This has | ||||
// much better performance than doing it with JOIN/WHERE. | // much better performance than doing it with JOIN/WHERE. | ||||
if ($this->responsibles) { | if ($this->responsibles) { | ||||
$basic_authors = $this->authors; | $basic_authors = $this->authors; | ||||
$basic_reviewers = $this->reviewers; | $basic_reviewers = $this->reviewers; | ||||
$authority_phids = $this->responsibles; | |||||
$authority_projects = id(new PhabricatorProjectQuery()) | $authority_projects = id(new PhabricatorProjectQuery()) | ||||
->setViewer($this->getViewer()) | ->setViewer($this->getViewer()) | ||||
->withMemberPHIDs($this->responsibles) | ->withMemberPHIDs($this->responsibles) | ||||
->execute(); | ->execute(); | ||||
$authority_phids = mpull($authority_projects, 'getPHID'); | foreach ($authority_projects as $project) { | ||||
$authority_phids[] = $project->getPHID(); | |||||
} | |||||
// NOTE: We're querying by explicit owners to make this a little faster, | |||||
// since we've already expanded project membership so we don't need to | |||||
// have the PackageQuery do it again. | |||||
$authority_packages = id(new PhabricatorOwnersPackageQuery()) | |||||
->setViewer($this->getViewer()) | |||||
->withOwnerPHIDs($authority_phids) | |||||
->execute(); | |||||
foreach ($authority_packages as $package) { | |||||
$authority_phids[] = $package->getPHID(); | |||||
} | |||||
try { | try { | ||||
// Build the query where the responsible users are authors. | // Build the query where the responsible users are authors. | ||||
$this->authors = array_merge($basic_authors, $this->responsibles); | $this->authors = array_merge($basic_authors, $this->responsibles); | ||||
$this->reviewers = $basic_reviewers; | $this->reviewers = $basic_reviewers; | ||||
$selects[] = $this->buildSelectStatement($conn_r); | $selects[] = $this->buildSelectStatement($conn_r); | ||||
// Build the query where the responsible users are reviewers, or | // Build the query where the responsible users are reviewers, or | ||||
// projects they are members of are reviewers. | // projects they are members of are reviewers. | ||||
$this->authors = $basic_authors; | $this->authors = $basic_authors; | ||||
$this->reviewers = array_merge( | $this->reviewers = array_merge( | ||||
$basic_reviewers, | $basic_reviewers, | ||||
$this->responsibles, | |||||
$authority_phids); | $authority_phids); | ||||
$selects[] = $this->buildSelectStatement($conn_r); | $selects[] = $this->buildSelectStatement($conn_r); | ||||
// Put everything back like it was. | // Put everything back like it was. | ||||
$this->authors = $basic_authors; | $this->authors = $basic_authors; | ||||
$this->reviewers = $basic_reviewers; | $this->reviewers = $basic_reviewers; | ||||
} catch (Exception $ex) { | } catch (Exception $ex) { | ||||
$this->authors = $basic_authors; | $this->authors = $basic_authors; | ||||
▲ Show 20 Lines • Show All 540 Lines • ▼ Show 20 Lines | /* -( Internals )---------------------------------------------------------- */ | ||||
private function loadReviewerAuthority( | private function loadReviewerAuthority( | ||||
array $revisions, | array $revisions, | ||||
array $edges, | array $edges, | ||||
$allow_self) { | $allow_self) { | ||||
$revision_map = mpull($revisions, null, 'getPHID'); | $revision_map = mpull($revisions, null, 'getPHID'); | ||||
$viewer_phid = $this->getViewer()->getPHID(); | $viewer_phid = $this->getViewer()->getPHID(); | ||||
// Find all the project reviewers which the user may have authority over. | // Find all the project/package reviewers which the user may have authority | ||||
// over. | |||||
$project_phids = array(); | $project_phids = array(); | ||||
$package_phids = array(); | |||||
$project_type = PhabricatorProjectProjectPHIDType::TYPECONST; | $project_type = PhabricatorProjectProjectPHIDType::TYPECONST; | ||||
$package_type = PhabricatorOwnersPackagePHIDType::TYPECONST; | |||||
$edge_type = DifferentialRevisionHasReviewerEdgeType::EDGECONST; | $edge_type = DifferentialRevisionHasReviewerEdgeType::EDGECONST; | ||||
foreach ($edges as $src => $types) { | foreach ($edges as $src => $types) { | ||||
if (!$allow_self) { | if (!$allow_self) { | ||||
if ($revision_map[$src]->getAuthorPHID() == $viewer_phid) { | if ($revision_map[$src]->getAuthorPHID() == $viewer_phid) { | ||||
// If self-review isn't permitted, the user will never have | // If self-review isn't permitted, the user will never have | ||||
// authority over projects on revisions they authored because you | // authority over projects on revisions they authored because you | ||||
// can't accept your own revisions, so we don't need to load any | // can't accept your own revisions, so we don't need to load any | ||||
// data about these reviewers. | // data about these reviewers. | ||||
continue; | continue; | ||||
} | } | ||||
} | } | ||||
$edge_data = idx($types, $edge_type, array()); | $edge_data = idx($types, $edge_type, array()); | ||||
foreach ($edge_data as $dst => $data) { | foreach ($edge_data as $dst => $data) { | ||||
if (phid_get_type($dst) == $project_type) { | $phid_type = phid_get_type($dst); | ||||
if ($phid_type == $project_type) { | |||||
$project_phids[] = $dst; | $project_phids[] = $dst; | ||||
} | } | ||||
if ($phid_type == $package_type) { | |||||
$package_phids[] = $dst; | |||||
} | } | ||||
} | } | ||||
} | |||||
// The viewer has authority over themselves. | |||||
$user_authority = array_fuse(array($viewer_phid)); | |||||
// Now, figure out which of these projects the viewer is actually a | // And over any projects they are a member of. | ||||
// member of. | |||||
$project_authority = array(); | $project_authority = array(); | ||||
if ($project_phids) { | if ($project_phids) { | ||||
$project_authority = id(new PhabricatorProjectQuery()) | $project_authority = id(new PhabricatorProjectQuery()) | ||||
->setViewer($this->getViewer()) | ->setViewer($this->getViewer()) | ||||
->withPHIDs($project_phids) | ->withPHIDs($project_phids) | ||||
->withMemberPHIDs(array($viewer_phid)) | ->withMemberPHIDs(array($viewer_phid)) | ||||
->execute(); | ->execute(); | ||||
$project_authority = mpull($project_authority, 'getPHID'); | $project_authority = mpull($project_authority, 'getPHID'); | ||||
$project_authority = array_fuse($project_authority); | |||||
} | } | ||||
// Finally, the viewer has authority over themselves. | // And over any packages they own. | ||||
return array( | $package_authority = array(); | ||||
$viewer_phid => true, | if ($package_phids) { | ||||
) + array_fuse($project_authority); | $package_authority = id(new PhabricatorOwnersPackageQuery()) | ||||
->setViewer($this->getViewer()) | |||||
->withPHIDs($package_phids) | |||||
->withAuthorityPHIDs(array($viewer_phid)) | |||||
->execute(); | |||||
$package_authority = mpull($package_authority, 'getPHID'); | |||||
$package_authority = array_fuse($package_authority); | |||||
} | |||||
return $user_authority + $project_authority + $package_authority; | |||||
} | } | ||||
public function getQueryApplicationClass() { | public function getQueryApplicationClass() { | ||||
return 'PhabricatorDifferentialApplication'; | return 'PhabricatorDifferentialApplication'; | ||||
} | } | ||||
protected function getPrimaryTableAlias() { | protected function getPrimaryTableAlias() { | ||||
return 'r'; | return 'r'; | ||||
} | } | ||||
} | } |