Correct a parameter order swap in "diffusion.historyquery" for Mercurial
[phabricator.git] / src / applications / settings / controller / PhabricatorSettingsMainController.php
blobded20a8e962a1793ff45f2cd04569e105eac91dd
1 <?php
3 final class PhabricatorSettingsMainController
4 extends PhabricatorController {
6 private $user;
7 private $builtinKey;
8 private $preferences;
10 private function getUser() {
11 return $this->user;
14 private function isSelf() {
15 $user = $this->getUser();
16 if (!$user) {
17 return false;
20 $user_phid = $user->getPHID();
22 $viewer_phid = $this->getViewer()->getPHID();
23 return ($viewer_phid == $user_phid);
26 private function isTemplate() {
27 return ($this->builtinKey !== null);
30 public function handleRequest(AphrontRequest $request) {
31 $viewer = $this->getViewer();
33 // Redirect "/panel/XYZ/" to the viewer's personal settings panel. This
34 // was the primary URI before global settings were introduced and allows
35 // generation of viewer-agnostic URIs for email and logged-out users.
36 $panel = $request->getURIData('panel');
37 if ($panel) {
38 $panel = phutil_escape_uri($panel);
39 $username = $viewer->getUsername();
41 $panel_uri = "/user/{$username}/page/{$panel}/";
42 $panel_uri = $this->getApplicationURI($panel_uri);
43 return id(new AphrontRedirectResponse())->setURI($panel_uri);
46 $username = $request->getURIData('username');
47 $builtin = $request->getURIData('builtin');
49 $key = $request->getURIData('pageKey');
51 if ($builtin) {
52 $this->builtinKey = $builtin;
54 $preferences = id(new PhabricatorUserPreferencesQuery())
55 ->setViewer($viewer)
56 ->withBuiltinKeys(array($builtin))
57 ->requireCapabilities(
58 array(
59 PhabricatorPolicyCapability::CAN_VIEW,
60 PhabricatorPolicyCapability::CAN_EDIT,
62 ->executeOne();
63 if (!$preferences) {
64 $preferences = id(new PhabricatorUserPreferences())
65 ->attachUser(null)
66 ->setBuiltinKey($builtin);
68 } else {
69 $user = id(new PhabricatorPeopleQuery())
70 ->setViewer($viewer)
71 ->withUsernames(array($username))
72 ->requireCapabilities(
73 array(
74 PhabricatorPolicyCapability::CAN_VIEW,
75 PhabricatorPolicyCapability::CAN_EDIT,
77 ->executeOne();
79 if (!$user) {
80 return new Aphront404Response();
83 $preferences = PhabricatorUserPreferences::loadUserPreferences($user);
84 $this->user = $user;
87 if (!$preferences) {
88 return new Aphront404Response();
91 PhabricatorPolicyFilter::requireCapability(
92 $viewer,
93 $preferences,
94 PhabricatorPolicyCapability::CAN_EDIT);
96 $this->preferences = $preferences;
98 $panels = $this->buildPanels($preferences);
99 $nav = $this->renderSideNav($panels);
101 $key = $nav->selectFilter($key, head($panels)->getPanelKey());
103 $panel = $panels[$key]
104 ->setController($this)
105 ->setNavigation($nav);
107 $response = $panel->processRequest($request);
108 if (($response instanceof AphrontResponse) ||
109 ($response instanceof AphrontResponseProducerInterface)) {
110 return $response;
113 $crumbs = $this->buildApplicationCrumbs();
114 $crumbs->addTextCrumb($panel->getPanelName());
115 $crumbs->setBorder(true);
117 if ($this->user) {
118 $header_text = pht('Edit Settings: %s', $user->getUserName());
119 } else {
120 $header_text = pht('Edit Global Settings');
123 $header = id(new PHUIHeaderView())
124 ->setHeader($header_text);
126 $title = $panel->getPanelName();
128 $view = id(new PHUITwoColumnView())
129 ->setHeader($header)
130 ->setFooter($response);
132 return $this->newPage()
133 ->setTitle($title)
134 ->setCrumbs($crumbs)
135 ->setNavigation($nav)
136 ->appendChild($view);
139 private function buildPanels(PhabricatorUserPreferences $preferences) {
140 $viewer = $this->getViewer();
141 $panels = PhabricatorSettingsPanel::getAllDisplayPanels();
143 $result = array();
144 foreach ($panels as $key => $panel) {
145 $panel
146 ->setPreferences($preferences)
147 ->setViewer($viewer);
149 if ($this->user) {
150 $panel->setUser($this->user);
153 if (!$panel->isEnabled()) {
154 continue;
157 if ($this->isTemplate()) {
158 if (!$panel->isTemplatePanel()) {
159 continue;
161 } else {
162 if (!$this->isSelf() && !$panel->isManagementPanel()) {
163 continue;
166 if ($this->isSelf() && !$panel->isUserPanel()) {
167 continue;
171 if (!empty($result[$key])) {
172 throw new Exception(pht(
173 "Two settings panels share the same panel key ('%s'): %s, %s.",
174 $key,
175 get_class($panel),
176 get_class($result[$key])));
179 $result[$key] = $panel;
182 if (!$result) {
183 throw new Exception(pht('No settings panels are available.'));
186 return $result;
189 private function renderSideNav(array $panels) {
190 $nav = new AphrontSideNavFilterView();
192 if ($this->isTemplate()) {
193 $base_uri = 'builtin/'.$this->builtinKey.'/page/';
194 } else {
195 $user = $this->getUser();
196 $base_uri = 'user/'.$user->getUsername().'/page/';
199 $nav->setBaseURI(new PhutilURI($this->getApplicationURI($base_uri)));
201 $group_key = null;
202 foreach ($panels as $panel) {
203 if ($panel->getPanelGroupKey() != $group_key) {
204 $group_key = $panel->getPanelGroupKey();
205 $group = $panel->getPanelGroup();
206 $panel_name = $group->getPanelGroupName();
207 if ($panel_name) {
208 $nav->addLabel($panel_name);
212 $nav->addFilter(
213 $panel->getPanelKey(),
214 $panel->getPanelName(),
215 null,
216 $panel->getPanelMenuIcon());
219 return $nav;
222 public function buildApplicationMenu() {
223 if ($this->preferences) {
224 $panels = $this->buildPanels($this->preferences);
225 return $this->renderSideNav($panels)->getMenu();
227 return parent::buildApplicationMenu();
230 protected function buildApplicationCrumbs() {
231 $crumbs = parent::buildApplicationCrumbs();
233 $user = $this->getUser();
234 if (!$this->isSelf() && $user) {
235 $username = $user->getUsername();
236 $crumbs->addTextCrumb($username, "/p/{$username}/");
239 return $crumbs;