Something went wrong. Try again.
@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
Something went wrong. Try again.
6.7 kB · 235 lines
PHP
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236<?php
abstract class PhabricatorProjectController extends PhabricatorController {
private $project; private $profileMenu; private $profileMenuEngine;
protected function setProject(PhabricatorProject $project) { $this->project = $project; return $this; }
protected function getProject() { return $this->project; }
protected function loadProject() { return $this->loadProjectWithCapabilities( array( PhabricatorPolicyCapability::CAN_VIEW, )); }
protected function loadProjectForEdit() { return $this->loadProjectWithCapabilities( array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, )); }
private function loadProjectWithCapabilities(array $capabilities) { $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) ->requireCapabilities($capabilities) ->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)) { // Things like milestones do not have a '/tag/something/' page. if (!phutil_nonempty_string($primary_slug)) { return new Aphront404Response(); } $primary_uri = "/tag/{$primary_slug}/"; return id(new AphrontRedirectResponse())->setURI($primary_uri); }
$this->setProject($project);
return null; }
protected function buildApplicationCrumbs() { return $this->newApplicationCrumbs('profile'); }
protected function newWorkboardCrumbs() { return $this->newApplicationCrumbs('workboard'); }
private function newApplicationCrumbs($mode) { $crumbs = parent::buildApplicationCrumbs();
$project = $this->getProject(); if ($project) { $ancestors = $project->getAncestorProjects(); $ancestors = array_reverse($ancestors); $ancestors[] = $project; foreach ($ancestors as $ancestor) { if ($ancestor->getPHID() === $project->getPHID()) { // Link the current project's crumb to its profile no matter what, // since we're already on the right context page for it and linking // to the current page isn't helpful. $crumb_uri = $ancestor->getProfileURI(); } else { switch ($mode) { case 'workboard': if ($ancestor->getHasWorkboard()) { $crumb_uri = $ancestor->getWorkboardURI(); } else { $crumb_uri = $ancestor->getProfileURI(); } break; case 'profile': default: $crumb_uri = $ancestor->getProfileURI(); break; } } $archived = $ancestor->isArchived(); $crumbs->addTextCrumb($ancestor->getName(), $crumb_uri, $archived); } }
return $crumbs; }
protected function getProfileMenuEngine() { if (!$this->profileMenuEngine) { $viewer = $this->getViewer(); $project = $this->getProject(); if ($project) { $engine = id(new PhabricatorProjectProfileMenuEngine()) ->setViewer($viewer) ->setController($this) ->setProfileObject($project); $this->profileMenuEngine = $engine; } }
return $this->profileMenuEngine; }
protected function setProfileMenuEngine( PhabricatorProjectProfileMenuEngine $engine) { $this->profileMenuEngine = $engine; return $this; }
protected function newCardResponse( $board_phid, $object_phid, ?PhabricatorProjectColumnOrder $ordering = null, $sounds = array()) {
$viewer = $this->getViewer();
$request = $this->getRequest(); $visible_phids = $request->getStrList('visiblePHIDs'); if (!$visible_phids) { $visible_phids = array(); }
$engine = id(new PhabricatorBoardResponseEngine()) ->setViewer($viewer) ->setBoardPHID($board_phid) ->setUpdatePHIDs(array($object_phid)) ->setVisiblePHIDs($visible_phids) ->setSounds($sounds);
if ($ordering) { $engine->setOrdering($ordering); }
return $engine->buildResponse(); }
public function renderHashtags(array $tags) { $result = array(); foreach ($tags as $key => $tag) { $result[] = '#'.$tag; } return implode(', ', $result); }
final protected function newNavigation( PhabricatorProject $project, $item_identifier) {
$engine = $this->getProfileMenuEngine();
$view_list = $engine->newProfileMenuItemViewList();
// See PHI1247. If the "Workboard" item is removed from the menu, we will // not be able to select it. This can happen if a user removes the item, // then manually navigate to the workboard URI (or follows an older link). // In this case, just render the menu with no selected item. if ($view_list->getViewsWithItemIdentifier($item_identifier)) { $view_list->setSelectedViewWithItemIdentifier($item_identifier); }
$navigation = $view_list->newNavigationView();
if ($item_identifier === PhabricatorProject::ITEM_WORKBOARD) { $navigation->addClass('project-board-nav'); }
return $navigation; }
}