Changeset View
Changeset View
Standalone View
Standalone View
src/applications/project/query/PhabricatorProjectQuery.php
| Show All 24 Lines | final class PhabricatorProjectQuery | ||||
| const STATUS_ANY = 'status-any'; | const STATUS_ANY = 'status-any'; | ||||
| const STATUS_OPEN = 'status-open'; | const STATUS_OPEN = 'status-open'; | ||||
| const STATUS_CLOSED = 'status-closed'; | const STATUS_CLOSED = 'status-closed'; | ||||
| const STATUS_ACTIVE = 'status-active'; | const STATUS_ACTIVE = 'status-active'; | ||||
| const STATUS_ARCHIVED = 'status-archived'; | const STATUS_ARCHIVED = 'status-archived'; | ||||
| private $needSlugs; | private $needSlugs; | ||||
| private $needMembers; | private $needMembers; | ||||
| private $needAncestorMembers; | |||||
| private $needWatchers; | private $needWatchers; | ||||
| private $needImages; | private $needImages; | ||||
| public function withIDs(array $ids) { | public function withIDs(array $ids) { | ||||
| $this->ids = $ids; | $this->ids = $ids; | ||||
| return $this; | return $this; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | public function withDepthBetween($min, $max) { | ||||
| return $this; | return $this; | ||||
| } | } | ||||
| public function needMembers($need_members) { | public function needMembers($need_members) { | ||||
| $this->needMembers = $need_members; | $this->needMembers = $need_members; | ||||
| return $this; | return $this; | ||||
| } | } | ||||
| public function needAncestorMembers($need_ancestor_members) { | |||||
| $this->needAncestorMembers = $need_ancestor_members; | |||||
| return $this; | |||||
| } | |||||
| public function needWatchers($need_watchers) { | public function needWatchers($need_watchers) { | ||||
| $this->needWatchers = $need_watchers; | $this->needWatchers = $need_watchers; | ||||
| return $this; | return $this; | ||||
| } | } | ||||
| public function needImages($need_images) { | public function needImages($need_images) { | ||||
| $this->needImages = $need_images; | $this->needImages = $need_images; | ||||
| return $this; | return $this; | ||||
| ▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | protected function willFilterPage(array $projects) { | ||||
| $watcher_type = PhabricatorObjectHasWatcherEdgeType::EDGECONST; | $watcher_type = PhabricatorObjectHasWatcherEdgeType::EDGECONST; | ||||
| $types = array(); | $types = array(); | ||||
| $types[] = $material_type; | $types[] = $material_type; | ||||
| if ($this->needWatchers) { | if ($this->needWatchers) { | ||||
| $types[] = $watcher_type; | $types[] = $watcher_type; | ||||
| } | } | ||||
| $all_graph = $this->getAllReachableAncestors($projects); | |||||
| if ($this->needAncestorMembers) { | |||||
| $src_projects = $all_graph; | |||||
| } else { | |||||
| $src_projects = $projects; | |||||
| } | |||||
| $all_sources = array(); | $all_sources = array(); | ||||
| foreach ($projects as $project) { | foreach ($src_projects as $project) { | ||||
| if ($project->isMilestone()) { | if ($project->isMilestone()) { | ||||
| $phid = $project->getParentProjectPHID(); | $phid = $project->getParentProjectPHID(); | ||||
| } else { | } else { | ||||
| $phid = $project->getPHID(); | $phid = $project->getPHID(); | ||||
| } | } | ||||
| $all_sources[$phid] = $phid; | $all_sources[$phid] = $phid; | ||||
| } | } | ||||
| $edge_query = id(new PhabricatorEdgeQuery()) | $edge_query = id(new PhabricatorEdgeQuery()) | ||||
| ->withSourcePHIDs($all_sources) | ->withSourcePHIDs($all_sources) | ||||
| ->withEdgeTypes($types); | ->withEdgeTypes($types); | ||||
| $need_all_edges = | |||||
| $this->needMembers || | |||||
| $this->needWatchers || | |||||
| $this->needAncestorMembers; | |||||
| // If we only need to know if the viewer is a member, we can restrict | // If we only need to know if the viewer is a member, we can restrict | ||||
| // the query to just their PHID. | // the query to just their PHID. | ||||
| $any_edges = true; | $any_edges = true; | ||||
| if (!$this->needMembers && !$this->needWatchers) { | if (!$need_all_edges) { | ||||
| if ($viewer_phid) { | if ($viewer_phid) { | ||||
| $edge_query->withDestinationPHIDs(array($viewer_phid)); | $edge_query->withDestinationPHIDs(array($viewer_phid)); | ||||
| } else { | } else { | ||||
| // If we don't need members or watchers and don't have a viewer PHID | // If we don't need members or watchers and don't have a viewer PHID | ||||
| // (viewer is logged-out or omnipotent), they'll never be a member | // (viewer is logged-out or omnipotent), they'll never be a member | ||||
| // so we don't need to issue this query at all. | // so we don't need to issue this query at all. | ||||
| $any_edges = false; | $any_edges = false; | ||||
| } | } | ||||
| } | } | ||||
| if ($any_edges) { | if ($any_edges) { | ||||
| $edge_query->execute(); | $edge_query->execute(); | ||||
| } | } | ||||
| $membership_projects = array(); | $membership_projects = array(); | ||||
| foreach ($projects as $project) { | foreach ($src_projects as $project) { | ||||
| $project_phid = $project->getPHID(); | $project_phid = $project->getPHID(); | ||||
| if ($project->isMilestone()) { | if ($project->isMilestone()) { | ||||
| $source_phids = array($project->getParentProjectPHID()); | $source_phids = array($project->getParentProjectPHID()); | ||||
| } else { | } else { | ||||
| $source_phids = array($project_phid); | $source_phids = array($project_phid); | ||||
| } | } | ||||
| if ($any_edges) { | if ($any_edges) { | ||||
| $member_phids = $edge_query->getDestinationPHIDs( | $member_phids = $edge_query->getDestinationPHIDs( | ||||
| $source_phids, | $source_phids, | ||||
| array($material_type)); | array($material_type)); | ||||
| } else { | } else { | ||||
| $member_phids = array(); | $member_phids = array(); | ||||
| } | } | ||||
| if (in_array($viewer_phid, $member_phids)) { | if (in_array($viewer_phid, $member_phids)) { | ||||
| $membership_projects[$project_phid] = $project; | $membership_projects[$project_phid] = $project; | ||||
| } | } | ||||
| if ($this->needMembers) { | if ($this->needMembers || $this->needAncestorMembers) { | ||||
| $project->attachMemberPHIDs($member_phids); | $project->attachMemberPHIDs($member_phids); | ||||
| } | } | ||||
| if ($this->needWatchers) { | if ($this->needWatchers) { | ||||
| $watcher_phids = $edge_query->getDestinationPHIDs( | $watcher_phids = $edge_query->getDestinationPHIDs( | ||||
| $source_phids, | $source_phids, | ||||
| array($watcher_type)); | array($watcher_type)); | ||||
| $project->attachWatcherPHIDs($watcher_phids); | $project->attachWatcherPHIDs($watcher_phids); | ||||
| $project->setIsUserWatcher( | $project->setIsUserWatcher( | ||||
| $viewer_phid, | $viewer_phid, | ||||
| in_array($viewer_phid, $watcher_phids)); | in_array($viewer_phid, $watcher_phids)); | ||||
| } | } | ||||
| } | } | ||||
| $all_graph = $this->getAllReachableAncestors($projects); | // If we loaded ancestor members, we've already populated membership | ||||
| // lists above, so we can skip this step. | |||||
| if (!$this->needAncestorMembers) { | |||||
| $member_graph = $this->getAllReachableAncestors($membership_projects); | $member_graph = $this->getAllReachableAncestors($membership_projects); | ||||
| foreach ($all_graph as $phid => $project) { | foreach ($all_graph as $phid => $project) { | ||||
| $is_member = isset($member_graph[$phid]); | $is_member = isset($member_graph[$phid]); | ||||
| $project->setIsUserMember($viewer_phid, $is_member); | $project->setIsUserMember($viewer_phid, $is_member); | ||||
| } | } | ||||
| } | |||||
| return $projects; | return $projects; | ||||
| } | } | ||||
| protected function didFilterPage(array $projects) { | protected function didFilterPage(array $projects) { | ||||
| if ($this->needImages) { | if ($this->needImages) { | ||||
| $default = null; | $default = null; | ||||
| ▲ Show 20 Lines • Show All 394 Lines • Show Last 20 Lines | |||||