Changeset View
Changeset View
Standalone View
Standalone View
src/applications/differential/query/DifferentialRevisionQuery.php
| Show First 20 Lines • Show All 599 Lines • ▼ Show 20 Lines | if ($this->ccs) { | ||||
| PhabricatorEdgeConfig::TABLE_NAME_EDGE, | PhabricatorEdgeConfig::TABLE_NAME_EDGE, | ||||
| PhabricatorObjectHasSubscriberEdgeType::EDGECONST, | PhabricatorObjectHasSubscriberEdgeType::EDGECONST, | ||||
| $this->ccs); | $this->ccs); | ||||
| } | } | ||||
| if ($this->reviewers) { | if ($this->reviewers) { | ||||
| $joins[] = qsprintf( | $joins[] = qsprintf( | ||||
| $conn_r, | $conn_r, | ||||
| 'JOIN %T e_reviewers ON e_reviewers.src = r.phid '. | 'JOIN %T reviewer ON reviewer.revisionPHID = r.phid | ||||
| 'AND e_reviewers.type = %s '. | AND reviewer.reviewerStatus != %s | ||||
| 'AND e_reviewers.dst in (%Ls)', | AND reviewer.reviewerPHID in (%Ls)', | ||||
| PhabricatorEdgeConfig::TABLE_NAME_EDGE, | id(new DifferentialReviewer())->getTableName(), | ||||
| DifferentialRevisionHasReviewerEdgeType::EDGECONST, | DifferentialReviewerStatus::STATUS_RESIGNED, | ||||
| $this->reviewers); | $this->reviewers); | ||||
| } | } | ||||
| if ($this->draftAuthors) { | if ($this->draftAuthors) { | ||||
| $joins[] = qsprintf( | $joins[] = qsprintf( | ||||
| $conn_r, | $conn_r, | ||||
| 'JOIN %T has_draft ON has_draft.srcPHID = r.phid | 'JOIN %T has_draft ON has_draft.srcPHID = r.phid | ||||
| AND has_draft.type = %s | AND has_draft.type = %s | ||||
| ▲ Show 20 Lines • Show All 346 Lines • ▼ Show 20 Lines | foreach ($revisions as $revision) { | ||||
| foreach ($hashes as $hash) { | foreach ($hashes as $hash) { | ||||
| $list[] = array($hash['type'], $hash['hash']); | $list[] = array($hash['type'], $hash['hash']); | ||||
| } | } | ||||
| $revision->attachHashes($list); | $revision->attachHashes($list); | ||||
| } | } | ||||
| } | } | ||||
| private function loadReviewers( | private function loadReviewers( | ||||
| AphrontDatabaseConnection $conn_r, | AphrontDatabaseConnection $conn, | ||||
| array $revisions) { | array $revisions) { | ||||
| assert_instances_of($revisions, 'DifferentialRevision'); | assert_instances_of($revisions, 'DifferentialRevision'); | ||||
| $edge_type = DifferentialRevisionHasReviewerEdgeType::EDGECONST; | |||||
| $edges = id(new PhabricatorEdgeQuery()) | $reviewer_table = new DifferentialReviewer(); | ||||
| ->withSourcePHIDs(mpull($revisions, 'getPHID')) | $reviewer_rows = queryfx_all( | ||||
| ->withEdgeTypes(array($edge_type)) | $conn, | ||||
| ->needEdgeData(true) | 'SELECT * FROM %T WHERE revisionPHID IN (%Ls) | ||||
| ->setOrder(PhabricatorEdgeQuery::ORDER_OLDEST_FIRST) | ORDER BY id ASC', | ||||
| ->execute(); | $reviewer_table->getTableName(), | ||||
| mpull($revisions, 'getPHID')); | |||||
| $reviewer_list = $reviewer_table->loadAllFromArray($reviewer_rows); | |||||
| $reviewer_map = mgroup($reviewer_list, 'getRevisionPHID'); | |||||
| foreach ($reviewer_map as $key => $reviewers) { | |||||
| $reviewer_map[$key] = mpull($reviewers, null, 'getReviewerPHID'); | |||||
| } | |||||
| $viewer = $this->getViewer(); | $viewer = $this->getViewer(); | ||||
| $viewer_phid = $viewer->getPHID(); | $viewer_phid = $viewer->getPHID(); | ||||
| $allow_key = 'differential.allow-self-accept'; | $allow_key = 'differential.allow-self-accept'; | ||||
| $allow_self = PhabricatorEnv::getEnvConfig($allow_key); | $allow_self = PhabricatorEnv::getEnvConfig($allow_key); | ||||
| // Figure out which of these reviewers the viewer has authority to act as. | // Figure out which of these reviewers the viewer has authority to act as. | ||||
| if ($this->needReviewerAuthority && $viewer_phid) { | if ($this->needReviewerAuthority && $viewer_phid) { | ||||
| $authority = $this->loadReviewerAuthority( | $authority = $this->loadReviewerAuthority( | ||||
| $revisions, | $revisions, | ||||
| $edges, | $reviewer_map, | ||||
| $allow_self); | $allow_self); | ||||
| } | } | ||||
| foreach ($revisions as $revision) { | foreach ($revisions as $revision) { | ||||
| $revision_edges = $edges[$revision->getPHID()][$edge_type]; | $reviewers = idx($reviewer_map, $revision->getPHID(), array()); | ||||
| $reviewers = array(); | foreach ($reviewers as $reviewer_phid => $reviewer) { | ||||
| foreach ($revision_edges as $reviewer_phid => $edge) { | |||||
| $reviewer = new DifferentialReviewerProxy( | |||||
| $reviewer_phid, | |||||
| $edge['data']); | |||||
| if ($this->needReviewerAuthority) { | if ($this->needReviewerAuthority) { | ||||
| if (!$viewer_phid) { | if (!$viewer_phid) { | ||||
| // Logged-out users never have authority. | // Logged-out users never have authority. | ||||
| $has_authority = false; | $has_authority = false; | ||||
| } else if ((!$allow_self) && | } else if ((!$allow_self) && | ||||
| ($revision->getAuthorPHID() == $viewer_phid)) { | ($revision->getAuthorPHID() == $viewer_phid)) { | ||||
| // The author can never have authority unless we allow self-accept. | // The author can never have authority unless we allow self-accept. | ||||
| $has_authority = false; | $has_authority = false; | ||||
| Show All 9 Lines | foreach ($revisions as $revision) { | ||||
| } | } | ||||
| $revision->attachReviewerStatus($reviewers); | $revision->attachReviewerStatus($reviewers); | ||||
| } | } | ||||
| } | } | ||||
| private function loadReviewerAuthority( | private function loadReviewerAuthority( | ||||
| array $revisions, | array $revisions, | ||||
| array $edges, | array $reviewers, | ||||
| $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/package reviewers which the user may have authority | // Find all the project/package reviewers which the user may have authority | ||||
| // over. | // over. | ||||
| $project_phids = array(); | $project_phids = array(); | ||||
| $package_phids = array(); | $package_phids = array(); | ||||
| $project_type = PhabricatorProjectProjectPHIDType::TYPECONST; | $project_type = PhabricatorProjectProjectPHIDType::TYPECONST; | ||||
| $package_type = PhabricatorOwnersPackagePHIDType::TYPECONST; | $package_type = PhabricatorOwnersPackagePHIDType::TYPECONST; | ||||
| $edge_type = DifferentialRevisionHasReviewerEdgeType::EDGECONST; | $edge_type = DifferentialRevisionHasReviewerEdgeType::EDGECONST; | ||||
| foreach ($edges as $src => $types) { | foreach ($reviewers as $revision_phid => $reviewer_list) { | ||||
| if (!$allow_self) { | if (!$allow_self) { | ||||
| if ($revision_map[$src]->getAuthorPHID() == $viewer_phid) { | if ($revision_map[$revision_phid]->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()); | |||||
| foreach ($edge_data as $dst => $data) { | foreach ($reviewer_list as $reviewer_phid => $reviewer) { | ||||
| $phid_type = phid_get_type($dst); | $phid_type = phid_get_type($reviewer_phid); | ||||
| if ($phid_type == $project_type) { | if ($phid_type == $project_type) { | ||||
| $project_phids[] = $dst; | $project_phids[] = $reviewer_phid; | ||||
| } | } | ||||
| if ($phid_type == $package_type) { | if ($phid_type == $package_type) { | ||||
| $package_phids[] = $dst; | $package_phids[] = $reviewer_phid; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| // The viewer has authority over themselves. | // The viewer has authority over themselves. | ||||
| $user_authority = array_fuse(array($viewer_phid)); | $user_authority = array_fuse(array($viewer_phid)); | ||||
| // And over any projects they are a member of. | // And over any projects they are a member of. | ||||
| Show All 35 Lines | |||||