@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Simplify some logic in project controllers

Summary: Ref T10010. Several controlers currently have similar logic for handling tags and slugs, loading projects, and canonicalizing URIs. Clean it up a bit.

Test Plan:
- Visited profile, boards, feed.
- Visited by ID and by tag.
- Visited by non-normal tag (redircted).
- Visited by alternate tag (redirected).
- Visited non-policy project by non-normal tag (redirected into policy error).

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10010

Differential Revision: https://secure.phabricator.com/D14890

+99 -130
+66
src/applications/project/controller/PhabricatorProjectController.php
··· 13 13 return $this->project; 14 14 } 15 15 16 + protected function loadProject() { 17 + $viewer = $this->getViewer(); 18 + $request = $this->getRequest(); 19 + 20 + $id = $request->getURIData('id'); 21 + $slug = $request->getURIData('slug'); 22 + 23 + if ($slug) { 24 + $normal_slug = PhabricatorSlug::normalizeProjectSlug($slug); 25 + $is_abnormal = ($slug !== $normal_slug); 26 + $normal_uri = "/tag/{$normal_slug}/"; 27 + } else { 28 + $is_abnormal = false; 29 + } 30 + 31 + $query = id(new PhabricatorProjectQuery()) 32 + ->setViewer($viewer) 33 + ->needMembers(true) 34 + ->needWatchers(true) 35 + ->needImages(true) 36 + ->needSlugs(true); 37 + 38 + if ($slug) { 39 + $query->withSlugs(array($slug)); 40 + } else { 41 + $query->withIDs(array($id)); 42 + } 43 + 44 + $policy_exception = null; 45 + try { 46 + $project = $query->executeOne(); 47 + } catch (PhabricatorPolicyException $ex) { 48 + $policy_exception = $ex; 49 + $project = null; 50 + } 51 + 52 + if (!$project) { 53 + // This project legitimately does not exist, so just 404 the user. 54 + if (!$policy_exception) { 55 + return new Aphront404Response(); 56 + } 57 + 58 + // Here, the project exists but the user can't see it. If they are 59 + // using a non-canonical slug to view the project, redirect to the 60 + // canonical slug. If they're already using the canonical slug, rethrow 61 + // the exception to give them the policy error. 62 + if ($is_abnormal) { 63 + return id(new AphrontRedirectResponse())->setURI($normal_uri); 64 + } else { 65 + throw $policy_exception; 66 + } 67 + } 68 + 69 + // The user can view the project, but is using a noncanonical slug. 70 + // Redirect to the canonical slug. 71 + $primary_slug = $project->getPrimarySlug(); 72 + if ($slug && ($slug !== $primary_slug)) { 73 + $primary_uri = "/tag/{$primary_slug}/"; 74 + return id(new AphrontRedirectResponse())->setURI($primary_uri); 75 + } 76 + 77 + $this->setProject($project); 78 + 79 + return null; 80 + } 81 + 16 82 public function buildApplicationMenu() { 17 83 return $this->buildSideNavView(true)->getMenu(); 18 84 }
+16 -45
src/applications/project/controller/PhabricatorProjectFeedController.php
··· 8 8 } 9 9 10 10 public function handleRequest(AphrontRequest $request) { 11 - $user = $request->getUser(); 11 + $viewer = $request->getUser(); 12 12 13 - $query = id(new PhabricatorProjectQuery()) 14 - ->setViewer($user) 15 - ->needMembers(true) 16 - ->needWatchers(true) 17 - ->needImages(true) 18 - ->needSlugs(true); 19 - $id = $request->getURIData('id'); 20 - $slug = $request->getURIData('slug'); 21 - if ($slug) { 22 - $query->withSlugs(array($slug)); 23 - } else { 24 - $query->withIDs(array($id)); 13 + $response = $this->loadProject(); 14 + if ($response) { 15 + return $response; 25 16 } 26 - $project = $query->executeOne(); 27 - if (!$project) { 28 - return new Aphront404Response(); 29 - } 30 - if ($slug && $slug != $project->getPrimarySlug()) { 31 - return id(new AphrontRedirectResponse()) 32 - ->setURI('/tag/'.$project->getPrimarySlug().'/'); 33 - } 17 + 18 + $project = $this->getProject(); 19 + $id = $project->getID(); 20 + 21 + $stories = id(new PhabricatorFeedQuery()) 22 + ->setViewer($viewer) 23 + ->setFilterPHIDs( 24 + array( 25 + $project->getPHID(), 26 + )) 27 + ->setLimit(50) 28 + ->execute(); 34 29 35 - $query = new PhabricatorFeedQuery(); 36 - $query->setFilterPHIDs( 37 - array( 38 - $project->getPHID(), 39 - )); 40 - $query->setLimit(50); 41 - $query->setViewer($request->getUser()); 42 - $stories = $query->execute(); 43 30 $feed = $this->renderStories($stories); 44 31 45 32 $box = id(new PHUIObjectBoxView()) ··· 57 44 )); 58 45 } 59 46 60 - private function renderFeedPage(PhabricatorProject $project) { 61 - 62 - $query = new PhabricatorFeedQuery(); 63 - $query->setFilterPHIDs(array($project->getPHID())); 64 - $query->setViewer($this->getRequest()->getUser()); 65 - $query->setLimit(100); 66 - $stories = $query->execute(); 67 - 68 - if (!$stories) { 69 - return pht('There are no stories about this project.'); 70 - } 71 - 72 - return $this->renderStories($stories); 73 - } 74 - 75 47 private function renderStories(array $stories) { 76 48 assert_instances_of($stories, 'PhabricatorFeedStory'); 77 49 ··· 84 56 'profile-feed', 85 57 $view->render()); 86 58 } 87 - 88 59 89 60 }
-4
src/applications/project/controller/PhabricatorProjectMembersEditController.php
··· 12 12 ->withIDs(array($id)) 13 13 ->needMembers(true) 14 14 ->needImages(true) 15 - ->requireCapabilities( 16 - array( 17 - PhabricatorPolicyCapability::CAN_VIEW, 18 - )) 19 15 ->executeOne(); 20 16 if (!$project) { 21 17 return new Aphront404Response();
+13 -30
src/applications/project/controller/PhabricatorProjectProfileController.php
··· 8 8 } 9 9 10 10 public function handleRequest(AphrontRequest $request) { 11 - $user = $request->getUser(); 11 + $viewer = $request->getUser(); 12 12 13 - $query = id(new PhabricatorProjectQuery()) 14 - ->setViewer($user) 15 - ->needMembers(true) 16 - ->needWatchers(true) 17 - ->needImages(true) 18 - ->needSlugs(true); 19 - $id = $request->getURIData('id'); 20 - $slug = $request->getURIData('slug'); 21 - if ($slug) { 22 - $query->withSlugs(array($slug)); 23 - } else { 24 - $query->withIDs(array($id)); 25 - } 26 - $project = $query->executeOne(); 27 - if (!$project) { 28 - return new Aphront404Response(); 29 - } 30 - if ($slug && $slug != $project->getPrimarySlug()) { 31 - return id(new AphrontRedirectResponse()) 32 - ->setURI('/tag/'.$project->getPrimarySlug().'/'); 13 + $response = $this->loadProject(); 14 + if ($response) { 15 + return $response; 33 16 } 34 17 18 + $project = $this->getProject(); 19 + $id = $project->getID(); 35 20 $picture = $project->getProfileImageURI(); 36 21 37 22 $header = id(new PHUIHeaderView()) 38 23 ->setHeader($project->getName()) 39 - ->setUser($user) 24 + ->setUser($viewer) 40 25 ->setPolicyObject($project) 41 26 ->setImage($picture); 42 27 ··· 60 45 61 46 $nav = $this->buildIconNavView($project); 62 47 $nav->selectFilter("profile/{$id}/"); 63 - $nav->appendChild($object_box); 64 - $nav->appendChild($timeline); 65 48 66 - return $this->buildApplicationPage( 67 - $nav, 68 - array( 69 - 'title' => $project->getName(), 70 - 'pageObjects' => array($project->getPHID()), 71 - )); 49 + return $this->newPage() 50 + ->setNavigation($nav) 51 + ->setTitle($project->getName()) 52 + ->setPageObjectPHIDs(array($project->getPHID())) 53 + ->appendChild($object_box) 54 + ->appendChild($timeline); 72 55 } 73 56 74 57 private function buildActionListView(PhabricatorProject $project) {
+4 -51
src/applications/project/controller/PhabricatorProjectViewController.php
··· 11 11 $request = $this->getRequest(); 12 12 $viewer = $request->getViewer(); 13 13 14 - $query = id(new PhabricatorProjectQuery()) 15 - ->setViewer($viewer) 16 - ->needMembers(true) 17 - ->needWatchers(true) 18 - ->needImages(true) 19 - ->needSlugs(true); 20 - $id = $request->getURIData('id'); 21 - $slug = $request->getURIData('slug'); 22 - if ($slug) { 23 - $query->withSlugs(array($slug)); 24 - } else { 25 - $query->withIDs(array($id)); 26 - } 27 - $project = $query->executeOne(); 28 - if (!$project) { 29 - 30 - // If this request corresponds to a project but just doesn't have the 31 - // slug quite right, redirect to the proper URI. 32 - $uri = $this->getNormalizedURI($slug); 33 - if ($uri !== null) { 34 - return id(new AphrontRedirectResponse())->setURI($uri); 35 - } 36 - 37 - return new Aphront404Response(); 14 + $response = $this->loadProject(); 15 + if ($response) { 16 + return $response; 38 17 } 18 + $project = $this->getProject(); 39 19 40 20 $columns = id(new PhabricatorProjectColumnQuery()) 41 21 ->setViewer($viewer) ··· 58 38 } 59 39 60 40 return $this->delegateToController($controller_object); 61 - } 62 - 63 - private function getNormalizedURI($slug) { 64 - if (!strlen($slug)) { 65 - return null; 66 - } 67 - 68 - $normal = PhabricatorSlug::normalizeProjectSlug($slug); 69 - if ($normal === $slug) { 70 - return null; 71 - } 72 - 73 - $viewer = $this->getViewer(); 74 - 75 - // Do execute() instead of executeOne() here so we canonicalize before 76 - // raising a policy exception. This is a little more polished than letting 77 - // the user hit the error on any variant of the slug. 78 - 79 - $projects = id(new PhabricatorProjectQuery()) 80 - ->setViewer($viewer) 81 - ->withSlugs(array($normal)) 82 - ->execute(); 83 - if (!$projects) { 84 - return null; 85 - } 86 - 87 - return "/tag/{$normal}/"; 88 41 } 89 42 90 43 }