2011-02-21 03:41:23 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
abstract class PhabricatorProjectController extends PhabricatorController {
|
|
|
|
|
2015-02-23 20:27:19 +01:00
|
|
|
private $project;
|
2016-01-12 23:15:59 +01:00
|
|
|
private $profileMenu;
|
2016-01-19 19:35:32 +01:00
|
|
|
private $profilePanelEngine;
|
2015-02-23 20:27:19 +01:00
|
|
|
|
|
|
|
protected function setProject(PhabricatorProject $project) {
|
|
|
|
$this->project = $project;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getProject() {
|
|
|
|
return $this->project;
|
|
|
|
}
|
|
|
|
|
2015-12-27 11:04:37 +01:00
|
|
|
protected function loadProject() {
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
$request = $this->getRequest();
|
|
|
|
|
2016-01-13 00:06:43 +01:00
|
|
|
$id = nonempty(
|
|
|
|
$request->getURIData('projectID'),
|
|
|
|
$request->getURIData('id'));
|
|
|
|
|
2015-12-27 11:04:37 +01:00
|
|
|
$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;
|
|
|
|
}
|
|
|
|
|
2015-01-12 19:04:01 +01:00
|
|
|
public function buildApplicationMenu() {
|
2016-01-12 23:15:59 +01:00
|
|
|
$menu = $this->newApplicationMenu();
|
2015-01-12 19:04:01 +01:00
|
|
|
|
2016-01-12 23:15:59 +01:00
|
|
|
$profile_menu = $this->getProfileMenu();
|
|
|
|
if ($profile_menu) {
|
|
|
|
$menu->setProfileMenu($profile_menu);
|
|
|
|
}
|
2013-02-13 18:22:14 +01:00
|
|
|
|
2016-01-12 23:15:59 +01:00
|
|
|
$menu->setSearchEngine(new PhabricatorProjectSearchEngine());
|
2016-01-12 19:27:39 +01:00
|
|
|
|
2016-01-12 23:15:59 +01:00
|
|
|
return $menu;
|
|
|
|
}
|
2016-01-12 19:27:39 +01:00
|
|
|
|
2016-01-12 23:15:59 +01:00
|
|
|
protected function getProfileMenu() {
|
|
|
|
if (!$this->profileMenu) {
|
2016-01-19 19:35:32 +01:00
|
|
|
$engine = $this->getProfilePanelEngine();
|
|
|
|
if ($engine) {
|
2016-01-12 23:15:59 +01:00
|
|
|
$this->profileMenu = $engine->buildNavigation();
|
2015-01-12 19:04:01 +01:00
|
|
|
}
|
|
|
|
}
|
2013-07-22 17:34:35 +02:00
|
|
|
|
2016-01-12 23:15:59 +01:00
|
|
|
return $this->profileMenu;
|
2015-01-12 19:04:01 +01:00
|
|
|
}
|
|
|
|
|
2015-12-27 13:10:59 +01:00
|
|
|
protected function buildApplicationCrumbs() {
|
|
|
|
$crumbs = parent::buildApplicationCrumbs();
|
|
|
|
|
|
|
|
$project = $this->getProject();
|
|
|
|
if ($project) {
|
|
|
|
$ancestors = $project->getAncestorProjects();
|
|
|
|
$ancestors = array_reverse($ancestors);
|
|
|
|
$ancestors[] = $project;
|
|
|
|
foreach ($ancestors as $ancestor) {
|
|
|
|
$crumbs->addTextCrumb(
|
2015-12-27 14:16:36 +01:00
|
|
|
$ancestor->getName(),
|
|
|
|
$ancestor->getURI());
|
2015-12-27 13:10:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $crumbs;
|
|
|
|
}
|
|
|
|
|
2016-01-19 19:35:32 +01:00
|
|
|
protected function getProfilePanelEngine() {
|
|
|
|
if (!$this->profilePanelEngine) {
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
$project = $this->getProject();
|
|
|
|
if ($project) {
|
|
|
|
$engine = id(new PhabricatorProjectProfilePanelEngine())
|
|
|
|
->setViewer($viewer)
|
2016-01-22 16:36:56 +01:00
|
|
|
->setController($this)
|
2016-01-19 19:35:32 +01:00
|
|
|
->setProfileObject($project);
|
|
|
|
$this->profilePanelEngine = $engine;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $this->profilePanelEngine;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function setProfilePanelEngine(
|
|
|
|
PhabricatorProjectProfilePanelEngine $engine) {
|
|
|
|
$this->profilePanelEngine = $engine;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2016-02-06 23:05:15 +01:00
|
|
|
protected function newCardResponse($board_phid, $object_phid) {
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
|
|
|
|
$project = id(new PhabricatorProjectQuery())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->withPHIDs(array($board_phid))
|
|
|
|
->executeOne();
|
|
|
|
if (!$project) {
|
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reload the object so it reflects edits which have been applied.
|
|
|
|
$object = id(new ManiphestTaskQuery())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->withPHIDs(array($object_phid))
|
|
|
|
->needProjectPHIDs(true)
|
|
|
|
->executeOne();
|
|
|
|
if (!$object) {
|
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
|
|
|
|
|
|
|
$except_phids = array($board_phid);
|
|
|
|
if ($project->getHasSubprojects() || $project->getHasMilestones()) {
|
|
|
|
$descendants = id(new PhabricatorProjectQuery())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->withAncestorProjectPHIDs($except_phids)
|
|
|
|
->execute();
|
|
|
|
foreach ($descendants as $descendant) {
|
|
|
|
$except_phids[] = $descendant->getPHID();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$rendering_engine = id(new PhabricatorBoardRenderingEngine())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->setObjects(array($object))
|
|
|
|
->setExcludedProjectPHIDs($except_phids);
|
|
|
|
|
|
|
|
$card = $rendering_engine->renderCard($object->getPHID());
|
|
|
|
|
|
|
|
$item = $card->getItem();
|
|
|
|
$item->addClass('phui-workcard');
|
|
|
|
|
|
|
|
return id(new AphrontAjaxResponse())
|
|
|
|
->setContent(
|
|
|
|
array(
|
2016-02-09 15:14:42 +01:00
|
|
|
'objectPHID' => $object->getPHID(),
|
|
|
|
'cardHTML' => $item,
|
2016-02-06 23:05:15 +01:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2011-02-21 03:41:23 +01:00
|
|
|
}
|