1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-19 12:00:55 +01:00

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
This commit is contained in:
epriestley 2015-12-27 02:04:37 -08:00
parent d1f1d3ec33
commit 5e715c1aca
5 changed files with 99 additions and 130 deletions

View file

@ -13,6 +13,72 @@ abstract class PhabricatorProjectController extends PhabricatorController {
return $this->project; return $this->project;
} }
protected function loadProject() {
$viewer = $this->getViewer();
$request = $this->getRequest();
$id = $request->getURIData('id');
$slug = $request->getURIData('slug');
if ($slug) {
$normal_slug = PhabricatorSlug::normalizeProjectSlug($slug);
$is_abnormal = ($slug !== $normal_slug);
$normal_uri = "/tag/{$normal_slug}/";
} else {
$is_abnormal = false;
}
$query = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->needMembers(true)
->needWatchers(true)
->needImages(true)
->needSlugs(true);
if ($slug) {
$query->withSlugs(array($slug));
} else {
$query->withIDs(array($id));
}
$policy_exception = null;
try {
$project = $query->executeOne();
} catch (PhabricatorPolicyException $ex) {
$policy_exception = $ex;
$project = null;
}
if (!$project) {
// This project legitimately does not exist, so just 404 the user.
if (!$policy_exception) {
return new Aphront404Response();
}
// Here, the project exists but the user can't see it. If they are
// using a non-canonical slug to view the project, redirect to the
// canonical slug. If they're already using the canonical slug, rethrow
// the exception to give them the policy error.
if ($is_abnormal) {
return id(new AphrontRedirectResponse())->setURI($normal_uri);
} else {
throw $policy_exception;
}
}
// The user can view the project, but is using a noncanonical slug.
// Redirect to the canonical slug.
$primary_slug = $project->getPrimarySlug();
if ($slug && ($slug !== $primary_slug)) {
$primary_uri = "/tag/{$primary_slug}/";
return id(new AphrontRedirectResponse())->setURI($primary_uri);
}
$this->setProject($project);
return null;
}
public function buildApplicationMenu() { public function buildApplicationMenu() {
return $this->buildSideNavView(true)->getMenu(); return $this->buildSideNavView(true)->getMenu();
} }

View file

@ -8,38 +8,25 @@ final class PhabricatorProjectFeedController
} }
public function handleRequest(AphrontRequest $request) { public function handleRequest(AphrontRequest $request) {
$user = $request->getUser(); $viewer = $request->getUser();
$query = id(new PhabricatorProjectQuery()) $response = $this->loadProject();
->setViewer($user) if ($response) {
->needMembers(true) return $response;
->needWatchers(true)
->needImages(true)
->needSlugs(true);
$id = $request->getURIData('id');
$slug = $request->getURIData('slug');
if ($slug) {
$query->withSlugs(array($slug));
} else {
$query->withIDs(array($id));
}
$project = $query->executeOne();
if (!$project) {
return new Aphront404Response();
}
if ($slug && $slug != $project->getPrimarySlug()) {
return id(new AphrontRedirectResponse())
->setURI('/tag/'.$project->getPrimarySlug().'/');
} }
$query = new PhabricatorFeedQuery(); $project = $this->getProject();
$query->setFilterPHIDs( $id = $project->getID();
array(
$project->getPHID(), $stories = id(new PhabricatorFeedQuery())
)); ->setViewer($viewer)
$query->setLimit(50); ->setFilterPHIDs(
$query->setViewer($request->getUser()); array(
$stories = $query->execute(); $project->getPHID(),
))
->setLimit(50)
->execute();
$feed = $this->renderStories($stories); $feed = $this->renderStories($stories);
$box = id(new PHUIObjectBoxView()) $box = id(new PHUIObjectBoxView())
@ -57,21 +44,6 @@ final class PhabricatorProjectFeedController
)); ));
} }
private function renderFeedPage(PhabricatorProject $project) {
$query = new PhabricatorFeedQuery();
$query->setFilterPHIDs(array($project->getPHID()));
$query->setViewer($this->getRequest()->getUser());
$query->setLimit(100);
$stories = $query->execute();
if (!$stories) {
return pht('There are no stories about this project.');
}
return $this->renderStories($stories);
}
private function renderStories(array $stories) { private function renderStories(array $stories) {
assert_instances_of($stories, 'PhabricatorFeedStory'); assert_instances_of($stories, 'PhabricatorFeedStory');
@ -85,5 +57,4 @@ final class PhabricatorProjectFeedController
$view->render()); $view->render());
} }
} }

View file

@ -12,10 +12,6 @@ final class PhabricatorProjectMembersEditController
->withIDs(array($id)) ->withIDs(array($id))
->needMembers(true) ->needMembers(true)
->needImages(true) ->needImages(true)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
))
->executeOne(); ->executeOne();
if (!$project) { if (!$project) {
return new Aphront404Response(); return new Aphront404Response();

View file

@ -8,35 +8,20 @@ final class PhabricatorProjectProfileController
} }
public function handleRequest(AphrontRequest $request) { public function handleRequest(AphrontRequest $request) {
$user = $request->getUser(); $viewer = $request->getUser();
$query = id(new PhabricatorProjectQuery()) $response = $this->loadProject();
->setViewer($user) if ($response) {
->needMembers(true) return $response;
->needWatchers(true)
->needImages(true)
->needSlugs(true);
$id = $request->getURIData('id');
$slug = $request->getURIData('slug');
if ($slug) {
$query->withSlugs(array($slug));
} else {
$query->withIDs(array($id));
}
$project = $query->executeOne();
if (!$project) {
return new Aphront404Response();
}
if ($slug && $slug != $project->getPrimarySlug()) {
return id(new AphrontRedirectResponse())
->setURI('/tag/'.$project->getPrimarySlug().'/');
} }
$project = $this->getProject();
$id = $project->getID();
$picture = $project->getProfileImageURI(); $picture = $project->getProfileImageURI();
$header = id(new PHUIHeaderView()) $header = id(new PHUIHeaderView())
->setHeader($project->getName()) ->setHeader($project->getName())
->setUser($user) ->setUser($viewer)
->setPolicyObject($project) ->setPolicyObject($project)
->setImage($picture); ->setImage($picture);
@ -60,15 +45,13 @@ final class PhabricatorProjectProfileController
$nav = $this->buildIconNavView($project); $nav = $this->buildIconNavView($project);
$nav->selectFilter("profile/{$id}/"); $nav->selectFilter("profile/{$id}/");
$nav->appendChild($object_box);
$nav->appendChild($timeline);
return $this->buildApplicationPage( return $this->newPage()
$nav, ->setNavigation($nav)
array( ->setTitle($project->getName())
'title' => $project->getName(), ->setPageObjectPHIDs(array($project->getPHID()))
'pageObjects' => array($project->getPHID()), ->appendChild($object_box)
)); ->appendChild($timeline);
} }
private function buildActionListView(PhabricatorProject $project) { private function buildActionListView(PhabricatorProject $project) {

View file

@ -11,31 +11,11 @@ final class PhabricatorProjectViewController
$request = $this->getRequest(); $request = $this->getRequest();
$viewer = $request->getViewer(); $viewer = $request->getViewer();
$query = id(new PhabricatorProjectQuery()) $response = $this->loadProject();
->setViewer($viewer) if ($response) {
->needMembers(true) return $response;
->needWatchers(true)
->needImages(true)
->needSlugs(true);
$id = $request->getURIData('id');
$slug = $request->getURIData('slug');
if ($slug) {
$query->withSlugs(array($slug));
} else {
$query->withIDs(array($id));
}
$project = $query->executeOne();
if (!$project) {
// If this request corresponds to a project but just doesn't have the
// slug quite right, redirect to the proper URI.
$uri = $this->getNormalizedURI($slug);
if ($uri !== null) {
return id(new AphrontRedirectResponse())->setURI($uri);
}
return new Aphront404Response();
} }
$project = $this->getProject();
$columns = id(new PhabricatorProjectColumnQuery()) $columns = id(new PhabricatorProjectColumnQuery())
->setViewer($viewer) ->setViewer($viewer)
@ -60,31 +40,4 @@ final class PhabricatorProjectViewController
return $this->delegateToController($controller_object); return $this->delegateToController($controller_object);
} }
private function getNormalizedURI($slug) {
if (!strlen($slug)) {
return null;
}
$normal = PhabricatorSlug::normalizeProjectSlug($slug);
if ($normal === $slug) {
return null;
}
$viewer = $this->getViewer();
// Do execute() instead of executeOne() here so we canonicalize before
// raising a policy exception. This is a little more polished than letting
// the user hit the error on any variant of the slug.
$projects = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->withSlugs(array($normal))
->execute();
if (!$projects) {
return null;
}
return "/tag/{$normal}/";
}
} }