project = $project; return $this; } protected function getProject() { return $this->project; } protected function loadProject() { $viewer = $this->getViewer(); $request = $this->getRequest(); $id = nonempty( $request->getURIData('projectID'), $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() { $menu = $this->newApplicationMenu(); $profile_menu = $this->getProfileMenu(); if ($profile_menu) { $menu->setProfileMenu($profile_menu); } $menu->setSearchEngine(new PhabricatorProjectSearchEngine()); return $menu; } protected function getProfileMenu() { if (!$this->profileMenu) { $engine = $this->getProfilePanelEngine(); if ($engine) { $this->profileMenu = $engine->buildNavigation(); } } return $this->profileMenu; } 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( $ancestor->getName(), $ancestor->getURI()); } } return $crumbs; } protected function getProfilePanelEngine() { if (!$this->profilePanelEngine) { $viewer = $this->getViewer(); $project = $this->getProject(); if ($project) { $engine = id(new PhabricatorProjectProfilePanelEngine()) ->setViewer($viewer) ->setController($this) ->setProfileObject($project); $this->profilePanelEngine = $engine; } } return $this->profilePanelEngine; } protected function setProfilePanelEngine( PhabricatorProjectProfilePanelEngine $engine) { $this->profilePanelEngine = $engine; return $this; } 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( 'objectPHID' => $object->getPHID(), 'cardHTML' => $item, )); } }