@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
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Make settings panels more modular and modern

Summary:
Currently, we have a hard-coded list of settings panels. Make them a bit more modular.

- Allow new settings panels to be defined by third-party code (see {D2340}, for example -- @ptarjan).
- This makes the OAuth stuff more flexible for {T887} / {T1536}.
- Reduce the number of hard-coded URIs in various places.

Test Plan: Viewed / edited every option in every panel. Grepped for all references to these URIs.

Reviewers: btrahan, vrana, ptarjan

Reviewed By: btrahan

CC: aran

Differential Revision: https://secure.phabricator.com/D3257

+545 -308
+23 -24
src/__phutil_library_map__.php
··· 1003 1003 'PhabricatorSearchUserIndexer' => 'applications/search/index/indexer/PhabricatorSearchUserIndexer.php', 1004 1004 'PhabricatorSettingsAdjustController' => 'applications/settings/controller/PhabricatorSettingsAdjustController.php', 1005 1005 'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php', 1006 + 'PhabricatorSettingsPanel' => 'applications/settings/panel/PhabricatorSettingsPanel.php', 1007 + 'PhabricatorSettingsPanelAccount' => 'applications/settings/panel/PhabricatorSettingsPanelAccount.php', 1008 + 'PhabricatorSettingsPanelConduit' => 'applications/settings/panel/PhabricatorSettingsPanelConduit.php', 1009 + 'PhabricatorSettingsPanelDisplayPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelDisplayPreferences.php', 1010 + 'PhabricatorSettingsPanelEmailAddresses' => 'applications/settings/panel/PhabricatorSettingsPanelEmailAddresses.php', 1011 + 'PhabricatorSettingsPanelEmailPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelEmailPreferences.php', 1012 + 'PhabricatorSettingsPanelLDAP' => 'applications/settings/panel/PhabricatorSettingsPanelLDAP.php', 1013 + 'PhabricatorSettingsPanelOAuth' => 'applications/settings/panel/PhabricatorSettingsPanelOAuth.php', 1014 + 'PhabricatorSettingsPanelPassword' => 'applications/settings/panel/PhabricatorSettingsPanelPassword.php', 1015 + 'PhabricatorSettingsPanelProfile' => 'applications/settings/panel/PhabricatorSettingsPanelProfile.php', 1016 + 'PhabricatorSettingsPanelSSHKeys' => 'applications/settings/panel/PhabricatorSettingsPanelSSHKeys.php', 1017 + 'PhabricatorSettingsPanelSearchPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelSearchPreferences.php', 1006 1018 'PhabricatorSetup' => 'infrastructure/PhabricatorSetup.php', 1007 1019 'PhabricatorSlowvoteChoice' => 'applications/slowvote/storage/PhabricatorSlowvoteChoice.php', 1008 1020 'PhabricatorSlowvoteComment' => 'applications/slowvote/storage/PhabricatorSlowvoteComment.php', ··· 1053 1065 'PhabricatorUITooltipExample' => 'applications/uiexample/examples/PhabricatorUITooltipExample.php', 1054 1066 'PhabricatorUnitsTestCase' => 'view/__tests__/PhabricatorUnitsTestCase.php', 1055 1067 'PhabricatorUser' => 'applications/people/storage/PhabricatorUser.php', 1056 - 'PhabricatorUserAccountSettingsPanelController' => 'applications/settings/panel/PhabricatorUserAccountSettingsPanelController.php', 1057 - 'PhabricatorUserConduitSettingsPanelController' => 'applications/settings/panel/PhabricatorUserConduitSettingsPanelController.php', 1058 1068 'PhabricatorUserDAO' => 'applications/people/storage/PhabricatorUserDAO.php', 1059 1069 'PhabricatorUserEditor' => 'applications/people/PhabricatorUserEditor.php', 1060 1070 'PhabricatorUserEmail' => 'applications/people/storage/PhabricatorUserEmail.php', 1061 - 'PhabricatorUserEmailPreferenceSettingsPanelController' => 'applications/settings/panel/PhabricatorUserEmailPreferenceSettingsPanelController.php', 1062 - 'PhabricatorUserEmailSettingsPanelController' => 'applications/settings/panel/PhabricatorUserEmailSettingsPanelController.php', 1063 1071 'PhabricatorUserLDAPInfo' => 'applications/people/storage/PhabricatorUserLDAPInfo.php', 1064 - 'PhabricatorUserLDAPSettingsPanelController' => 'applications/settings/panel/PhabricatorUserLDAPSettingsPanelController.php', 1065 1072 'PhabricatorUserLog' => 'applications/people/storage/PhabricatorUserLog.php', 1066 1073 'PhabricatorUserOAuthInfo' => 'applications/people/storage/PhabricatorUserOAuthInfo.php', 1067 - 'PhabricatorUserOAuthSettingsPanelController' => 'applications/settings/panel/PhabricatorUserOAuthSettingsPanelController.php', 1068 - 'PhabricatorUserPasswordSettingsPanelController' => 'applications/settings/panel/PhabricatorUserPasswordSettingsPanelController.php', 1069 - 'PhabricatorUserPreferenceSettingsPanelController' => 'applications/settings/panel/PhabricatorUserPreferenceSettingsPanelController.php', 1070 1074 'PhabricatorUserPreferences' => 'applications/settings/storage/PhabricatorUserPreferences.php', 1071 1075 'PhabricatorUserProfile' => 'applications/people/storage/PhabricatorUserProfile.php', 1072 - 'PhabricatorUserProfileSettingsPanelController' => 'applications/settings/panel/PhabricatorUserProfileSettingsPanelController.php', 1073 1076 'PhabricatorUserSSHKey' => 'applications/settings/storage/PhabricatorUserSSHKey.php', 1074 - 'PhabricatorUserSSHKeysSettingsPanelController' => 'applications/settings/panel/PhabricatorUserSSHKeysSettingsPanelController.php', 1075 - 'PhabricatorUserSearchSettingsPanelController' => 'applications/settings/panel/PhabricatorUserSearchSettingsPanelController.php', 1076 - 'PhabricatorUserSettingsPanelController' => 'applications/settings/panel/PhabricatorUserSettingsPanelController.php', 1077 1077 'PhabricatorUserStatus' => 'applications/people/storage/PhabricatorUserStatus.php', 1078 1078 'PhabricatorUserTestCase' => 'applications/people/storage/__tests__/PhabricatorUserTestCase.php', 1079 1079 'PhabricatorWorker' => 'infrastructure/daemon/workers/PhabricatorWorker.php', ··· 2074 2074 'PhabricatorSearchUserIndexer' => 'PhabricatorSearchDocumentIndexer', 2075 2075 'PhabricatorSettingsAdjustController' => 'PhabricatorController', 2076 2076 'PhabricatorSettingsMainController' => 'PhabricatorController', 2077 + 'PhabricatorSettingsPanelAccount' => 'PhabricatorSettingsPanel', 2078 + 'PhabricatorSettingsPanelConduit' => 'PhabricatorSettingsPanel', 2079 + 'PhabricatorSettingsPanelDisplayPreferences' => 'PhabricatorSettingsPanel', 2080 + 'PhabricatorSettingsPanelEmailAddresses' => 'PhabricatorSettingsPanel', 2081 + 'PhabricatorSettingsPanelEmailPreferences' => 'PhabricatorSettingsPanel', 2082 + 'PhabricatorSettingsPanelLDAP' => 'PhabricatorSettingsPanel', 2083 + 'PhabricatorSettingsPanelOAuth' => 'PhabricatorSettingsPanel', 2084 + 'PhabricatorSettingsPanelPassword' => 'PhabricatorSettingsPanel', 2085 + 'PhabricatorSettingsPanelProfile' => 'PhabricatorSettingsPanel', 2086 + 'PhabricatorSettingsPanelSSHKeys' => 'PhabricatorSettingsPanel', 2087 + 'PhabricatorSettingsPanelSearchPreferences' => 'PhabricatorSettingsPanel', 2077 2088 'PhabricatorSlowvoteChoice' => 'PhabricatorSlowvoteDAO', 2078 2089 'PhabricatorSlowvoteComment' => 'PhabricatorSlowvoteDAO', 2079 2090 'PhabricatorSlowvoteController' => 'PhabricatorController', ··· 2119 2130 0 => 'PhabricatorUserDAO', 2120 2131 1 => 'PhutilPerson', 2121 2132 ), 2122 - 'PhabricatorUserAccountSettingsPanelController' => 'PhabricatorUserSettingsPanelController', 2123 - 'PhabricatorUserConduitSettingsPanelController' => 'PhabricatorUserSettingsPanelController', 2124 2133 'PhabricatorUserDAO' => 'PhabricatorLiskDAO', 2125 2134 'PhabricatorUserEmail' => 'PhabricatorUserDAO', 2126 - 'PhabricatorUserEmailPreferenceSettingsPanelController' => 'PhabricatorUserSettingsPanelController', 2127 - 'PhabricatorUserEmailSettingsPanelController' => 'PhabricatorUserSettingsPanelController', 2128 2135 'PhabricatorUserLDAPInfo' => 'PhabricatorUserDAO', 2129 - 'PhabricatorUserLDAPSettingsPanelController' => 'PhabricatorUserSettingsPanelController', 2130 2136 'PhabricatorUserLog' => 'PhabricatorUserDAO', 2131 2137 'PhabricatorUserOAuthInfo' => 'PhabricatorUserDAO', 2132 - 'PhabricatorUserOAuthSettingsPanelController' => 'PhabricatorUserSettingsPanelController', 2133 - 'PhabricatorUserPasswordSettingsPanelController' => 'PhabricatorUserSettingsPanelController', 2134 - 'PhabricatorUserPreferenceSettingsPanelController' => 'PhabricatorUserSettingsPanelController', 2135 2138 'PhabricatorUserPreferences' => 'PhabricatorUserDAO', 2136 2139 'PhabricatorUserProfile' => 'PhabricatorUserDAO', 2137 - 'PhabricatorUserProfileSettingsPanelController' => 'PhabricatorUserSettingsPanelController', 2138 2140 'PhabricatorUserSSHKey' => 'PhabricatorUserDAO', 2139 - 'PhabricatorUserSSHKeysSettingsPanelController' => 'PhabricatorUserSettingsPanelController', 2140 - 'PhabricatorUserSearchSettingsPanelController' => 'PhabricatorUserSettingsPanelController', 2141 - 'PhabricatorUserSettingsPanelController' => 'PhabricatorPeopleController', 2142 2141 'PhabricatorUserStatus' => 'PhabricatorUserDAO', 2143 2142 'PhabricatorUserTestCase' => 'PhabricatorTestCase', 2144 2143 'PhabricatorWorkerDAO' => 'PhabricatorLiskDAO',
+1 -1
src/applications/auth/controller/PhabricatorEmailTokenController.php
··· 97 97 $request->setCookie('phsid', $session_key); 98 98 99 99 if (PhabricatorEnv::getEnvConfig('account.editable')) { 100 - $next = (string)id(new PhutilURI('/settings/page/password/')) 100 + $next = (string)id(new PhutilURI('/settings/panel/password/')) 101 101 ->setQueryParams( 102 102 array( 103 103 'token' => $token,
+4 -4
src/applications/auth/controller/PhabricatorLDAPLoginController.php
··· 64 64 'another Phabricator account. Before you can link it to a '. 65 65 'different LDAP account, you must unlink the old account.</p>' 66 66 ); 67 - $dialog->addCancelButton('/settings/page/ldap/'); 67 + $dialog->addCancelButton('/settings/panel/ldap/'); 68 68 69 69 return id(new AphrontDialogResponse())->setDialog($dialog); 70 70 } else { 71 71 return id(new AphrontRedirectResponse()) 72 - ->setURI('/settings/page/ldap/'); 72 + ->setURI('/settings/panel/ldap/'); 73 73 } 74 74 } 75 75 ··· 82 82 $dialog->addHiddenInput('username', $request->getStr('username')); 83 83 $dialog->addHiddenInput('password', $request->getStr('password')); 84 84 $dialog->addSubmitButton('Link Accounts'); 85 - $dialog->addCancelButton('/settings/page/ldap/'); 85 + $dialog->addCancelButton('/settings/panel/ldap/'); 86 86 87 87 return id(new AphrontDialogResponse())->setDialog($dialog); 88 88 } ··· 92 92 $this->saveLDAPInfo($ldap_info); 93 93 94 94 return id(new AphrontRedirectResponse()) 95 - ->setURI('/settings/page/ldap/'); 95 + ->setURI('/settings/panel/ldap/'); 96 96 } 97 97 98 98 if ($ldap_info->getID()) {
+2 -2
src/applications/auth/controller/PhabricatorLDAPUnlinkController.php
··· 38 38 '<p><strong>You will not be able to login</strong> using this account '. 39 39 'once you unlink it. Continue?</p>'); 40 40 $dialog->addSubmitButton('Unlink Account'); 41 - $dialog->addCancelButton('/settings/page/ldap/'); 41 + $dialog->addCancelButton('/settings/panel/ldap/'); 42 42 43 43 return id(new AphrontDialogResponse())->setDialog($dialog); 44 44 } ··· 46 46 $ldap_info->delete(); 47 47 48 48 return id(new AphrontRedirectResponse()) 49 - ->setURI('/settings/page/ldap/'); 49 + ->setURI('/settings/panel/ldap/'); 50 50 } 51 51 52 52 }
+5 -5
src/applications/auth/controller/PhabricatorOAuthLoginController.php
··· 93 93 'the Phabricator account it is currently linked to.</p>', 94 94 $provider_name, 95 95 $provider_name)); 96 - $dialog->addCancelButton('/settings/page/'.$provider_key.'/'); 96 + $dialog->addCancelButton($provider->getSettingsPanelURI()); 97 97 98 98 return id(new AphrontDialogResponse())->setDialog($dialog); 99 99 } else { 100 100 $this->saveOAuthInfo($oauth_info); // Refresh token. 101 101 return id(new AphrontRedirectResponse()) 102 - ->setURI('/settings/page/'.$provider_key.'/'); 102 + ->setURI($provider->getSettingsPanelURI()); 103 103 } 104 104 } 105 105 ··· 119 119 'must unlink the old account.</p>', 120 120 $provider_name, 121 121 $provider_name)); 122 - $dialog->addCancelButton('/settings/page/'.$provider_key.'/'); 122 + $dialog->addCancelButton($provider->getSettingsPanelURI()); 123 123 return id(new AphrontDialogResponse())->setDialog($dialog); 124 124 } 125 125 ··· 136 136 $dialog->addHiddenInput('state', $this->oauthState); 137 137 $dialog->addHiddenInput('scope', $oauth_info->getTokenScope()); 138 138 $dialog->addSubmitButton('Link Accounts'); 139 - $dialog->addCancelButton('/settings/page/'.$provider_key.'/'); 139 + $dialog->addCancelButton($provider->getSettingsPanelURI()); 140 140 141 141 return id(new AphrontDialogResponse())->setDialog($dialog); 142 142 } ··· 146 146 $this->saveOAuthInfo($oauth_info); 147 147 148 148 return id(new AphrontRedirectResponse()) 149 - ->setURI('/settings/page/'.$provider_key.'/'); 149 + ->setURI($provider->getSettingsPanelURI()); 150 150 } 151 151 152 152 // Login with known auth.
+2 -2
src/applications/auth/controller/PhabricatorOAuthUnlinkController.php
··· 54 54 '<p><strong>You will not be able to login</strong> using this account '. 55 55 'once you unlink it. Continue?</p>'); 56 56 $dialog->addSubmitButton('Unlink Account'); 57 - $dialog->addCancelButton('/settings/page/'.$provider_key.'/'); 57 + $dialog->addCancelButton($provider->getSettingsPanelURI()); 58 58 59 59 return id(new AphrontDialogResponse())->setDialog($dialog); 60 60 } ··· 62 62 $oauth_info->delete(); 63 63 64 64 return id(new AphrontRedirectResponse()) 65 - ->setURI('/settings/page/'.$provider_key.'/'); 65 + ->setURI($provider->getSettingsPanelURI()); 66 66 } 67 67 68 68 }
+6
src/applications/auth/oauth/provider/PhabricatorOAuthProvider.php
··· 38 38 abstract public function getAuthURI(); 39 39 abstract public function getTestURIs(); 40 40 41 + public function getSettingsPanelURI() { 42 + $panel = new PhabricatorSettingsPanelOAuth(); 43 + $panel->setOAuthProvider($this); 44 + return $panel->getPanelURI(); 45 + } 46 + 41 47 /** 42 48 * If the provider needs extra stuff in the auth request, return it here. 43 49 * For example, Google needs a response_type parameter.
+1 -1
src/applications/differential/view/DifferentialChangesetListView.php
··· 293 293 if ($editor_link) { 294 294 $meta['editor'] = $editor_link; 295 295 } else { 296 - $meta['editorConfigure'] = '/settings/page/preferences/'; 296 + $meta['editorConfigure'] = '/settings/panel/display/'; 297 297 } 298 298 } 299 299
+1 -1
src/applications/people/controller/PhabricatorEmailVerificationController.php
··· 51 51 $settings_link = phutil_render_tag( 52 52 'a', 53 53 array( 54 - 'href' => '/settings/page/email/', 54 + 'href' => '/settings/panel/email/', 55 55 ), 56 56 'Return to Email Settings'); 57 57 $settings_link = '<br /><p><strong>'.$settings_link.'</strong></p>';
+1 -1
src/applications/people/controller/PhabricatorPeopleProfileController.php
··· 147 147 148 148 if ($user->getPHID() == $viewer->getPHID()) { 149 149 $nav->addSpacer(); 150 - $nav->addFilter(null, 'Edit Profile...', '/settings/page/profile/'); 150 + $nav->addFilter(null, 'Edit Profile...', '/settings/panel/profile/'); 151 151 } 152 152 153 153 if ($viewer->getIsAdmin()) {
+1 -1
src/applications/settings/application/PhabricatorApplicationSettings.php
··· 33 33 public function getRoutes() { 34 34 return array( 35 35 '/settings/' => array( 36 - '(?:page/(?P<page>[^/]+)/)?' => 'PhabricatorSettingsMainController', 36 + '(?:panel/(?P<key>[^/]+)/)?' => 'PhabricatorSettingsMainController', 37 37 'adjust/' => 'PhabricatorSettingsAdjustController', 38 38 ), 39 39 );
+56 -97
src/applications/settings/controller/PhabricatorSettingsMainController.php
··· 19 19 final class PhabricatorSettingsMainController 20 20 extends PhabricatorController { 21 21 22 - private $page; 23 - private $pages; 22 + private $key; 24 23 25 24 public function willProcessRequest(array $data) { 26 - $this->page = idx($data, 'page'); 25 + $this->key = idx($data, 'key'); 27 26 } 28 27 29 28 public function processRequest() { 30 - 31 29 $request = $this->getRequest(); 32 30 33 - $oauth_providers = PhabricatorOAuthProvider::getAllProviders(); 34 - $sidenav = $this->renderSideNav($oauth_providers); 35 - $this->page = $sidenav->selectFilter($this->page, 'account'); 31 + $panels = $this->buildPanels(); 32 + $nav = $this->renderSideNav($panels); 36 33 37 - switch ($this->page) { 38 - case 'account': 39 - $delegate = new PhabricatorUserAccountSettingsPanelController($request); 40 - break; 41 - case 'profile': 42 - $delegate = new PhabricatorUserProfileSettingsPanelController($request); 43 - break; 44 - case 'email': 45 - $delegate = new PhabricatorUserEmailSettingsPanelController($request); 46 - break; 47 - case 'emailpref': 48 - $delegate = new PhabricatorUserEmailPreferenceSettingsPanelController( 49 - $request); 50 - break; 51 - case 'password': 52 - $delegate = new PhabricatorUserPasswordSettingsPanelController( 53 - $request); 54 - break; 55 - case 'conduit': 56 - $delegate = new PhabricatorUserConduitSettingsPanelController($request); 57 - break; 58 - case 'sshkeys': 59 - $delegate = new PhabricatorUserSSHKeysSettingsPanelController($request); 60 - break; 61 - case 'preferences': 62 - $delegate = new PhabricatorUserPreferenceSettingsPanelController( 63 - $request); 64 - break; 65 - case 'search': 66 - $delegate = new PhabricatorUserSearchSettingsPanelController($request); 67 - break; 68 - case 'ldap': 69 - $delegate = new PhabricatorUserLDAPSettingsPanelController($request); 70 - break; 71 - default: 72 - $delegate = new PhabricatorUserOAuthSettingsPanelController($request); 73 - $delegate->setOAuthProvider($oauth_providers[$this->page]); 74 - break; 75 - } 34 + $key = $nav->selectFilter($this->key, head($panels)->getPanelKey()); 35 + 76 36 77 - $response = $this->delegateToController($delegate); 37 + $panel = $panels[$key]; 78 38 79 - if ($response instanceof AphrontView) { 80 - $sidenav->appendChild($response); 81 - return $this->buildStandardPageResponse( 82 - $sidenav, 83 - array( 84 - 'title' => 'Account Settings', 85 - )); 86 - } else { 39 + $response = $panel->processRequest($request); 40 + if ($response instanceof AphrontResponse) { 87 41 return $response; 88 42 } 43 + 44 + $nav->appendChild($response); 45 + return $this->buildApplicationPage( 46 + $nav, 47 + array( 48 + 'title' => $panel->getPanelName(), 49 + )); 89 50 } 90 51 91 - private function renderSideNav($oauth_providers) { 92 - $sidenav = new AphrontSideNavFilterView(); 93 - $sidenav 94 - ->setBaseURI(new PhutilURI('/settings/page/')) 95 - ->addLabel('Account Information') 96 - ->addFilter('account', 'Account') 97 - ->addFilter('profile', 'Profile') 98 - ->addSpacer() 99 - ->addLabel('Email') 100 - ->addFilter('email', 'Email Addresses') 101 - ->addFilter('emailpref', 'Email Preferences') 102 - ->addSpacer() 103 - ->addLabel('Authentication'); 104 - 105 - if (PhabricatorEnv::getEnvConfig('account.editable') && 106 - PhabricatorEnv::getEnvConfig('auth.password-auth-enabled')) { 107 - $sidenav->addFilter('password', 'Password'); 108 - } 109 - 110 - $sidenav->addFilter('conduit', 'Conduit Certificate'); 52 + private function buildPanels() { 53 + $panel_specs = id(new PhutilSymbolLoader()) 54 + ->setAncestorClass('PhabricatorSettingsPanel') 55 + ->setConcreteOnly(true) 56 + ->selectAndLoadSymbols(); 111 57 112 - if (PhabricatorUserSSHKeysSettingsPanelController::isEnabled()) { 113 - $sidenav->addFilter('sshkeys', 'SSH Public Keys'); 58 + $panels = array(); 59 + foreach ($panel_specs as $spec) { 60 + $class = newv($spec['name'], array()); 61 + $panels[] = $class->buildPanels(); 114 62 } 115 63 116 - $sidenav->addSpacer(); 117 - $sidenav->addLabel('Application Settings'); 118 - $sidenav->addFilter('preferences', 'Display Preferences'); 119 - $sidenav->addFilter('search', 'Search Preferences'); 64 + $panels = array_mergev($panels); 65 + $panels = mpull($panels, null, 'getPanelKey'); 120 66 121 - $items = array(); 122 - foreach ($oauth_providers as $provider) { 123 - if (!$provider->isProviderEnabled()) { 67 + $result = array(); 68 + foreach ($panels as $key => $panel) { 69 + if (!$panel->isEnabled()) { 124 70 continue; 125 71 } 126 - $key = $provider->getProviderKey(); 127 - $name = $provider->getProviderName(); 128 - $items[$key] = $name.' Account'; 72 + if (!empty($result[$key])) { 73 + throw new Exception( 74 + "Two settings panels share the same panel key ('{$key}'): ". 75 + get_class($panel).', '.get_class($result[$key]).'.'); 76 + } 77 + $result[$key] = $panel; 129 78 } 130 79 131 - $ldap_provider = new PhabricatorLDAPProvider(); 132 - if ($ldap_provider->isProviderEnabled()) { 133 - $items['ldap'] = 'LDAP Account'; 134 - } 80 + $result = msort($result, 'getPanelSortKey'); 135 81 136 - if ($items) { 137 - $sidenav->addSpacer(); 138 - $sidenav->addLabel('Linked Accounts'); 139 - foreach ($items as $key => $name) { 140 - $sidenav->addFilter($key, $name); 82 + return $result; 83 + } 84 + 85 + private function renderSideNav(array $panels) { 86 + $nav = new AphrontSideNavFilterView(); 87 + $nav->setBaseURI(new PhutilURI($this->getApplicationURI('/panel/'))); 88 + 89 + $group = null; 90 + foreach ($panels as $panel) { 91 + if ($panel->getPanelGroup() != $group) { 92 + if ($group !== null) { 93 + $nav->addSpacer(); 94 + } 95 + $group = $panel->getPanelGroup(); 96 + $nav->addLabel($group); 141 97 } 98 + 99 + $nav->addFilter($panel->getPanelKey(), $panel->getPanelName()); 142 100 } 143 101 144 - return $sidenav; 102 + return $nav; 145 103 } 104 + 146 105 }
+156
src/applications/settings/panel/PhabricatorSettingsPanel.php
··· 1 + <?php 2 + 3 + /* 4 + * Copyright 2012 Facebook, Inc. 5 + * 6 + * Licensed under the Apache License, Version 2.0 (the "License"); 7 + * you may not use this file except in compliance with the License. 8 + * You may obtain a copy of the License at 9 + * 10 + * http://www.apache.org/licenses/LICENSE-2.0 11 + * 12 + * Unless required by applicable law or agreed to in writing, software 13 + * distributed under the License is distributed on an "AS IS" BASIS, 14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 + * See the License for the specific language governing permissions and 16 + * limitations under the License. 17 + */ 18 + 19 + /** 20 + * Defines a settings panel. Settings panels appear in the Settings application, 21 + * and behave like lightweight controllers -- generally, they render some sort 22 + * of form with options in it, and then update preferences when the user 23 + * submits the form. By extending this class, you can add new settings 24 + * panels. 25 + * 26 + * NOTE: This stuff is new and might not be completely stable. 27 + * 28 + * @task config Panel Configuration 29 + * @task panel Panel Implementation 30 + * @task internal Internals 31 + * 32 + * @group settings 33 + */ 34 + abstract class PhabricatorSettingsPanel { 35 + 36 + 37 + /* -( Panel Configuration )------------------------------------------------ */ 38 + 39 + 40 + /** 41 + * Return a unique string used in the URI to identify this panel, like 42 + * "example". 43 + * 44 + * @return string Unique panel identifier (used in URIs). 45 + * @task config 46 + */ 47 + abstract public function getPanelKey(); 48 + 49 + 50 + /** 51 + * Return a human-readable description of the panel's contents, like 52 + * "Example Settings". 53 + * 54 + * @return string Human-readable panel name. 55 + * @task config 56 + */ 57 + abstract public function getPanelName(); 58 + 59 + 60 + /** 61 + * Return a human-readable group name for this panel. For instance, if you 62 + * had several related panels like "Volume Settings" and 63 + * "Microphone Settings", you might put them in a group called "Audio". 64 + * 65 + * When displayed, panels are grouped with other panels that have the same 66 + * group name. 67 + * 68 + * @return string Human-readable panel group name. 69 + * @task config 70 + */ 71 + abstract public function getPanelGroup(); 72 + 73 + 74 + /** 75 + * Return false to prevent this panel from being displayed or used. You can 76 + * do, e.g., configuration checks here, to determine if the feature your 77 + * panel controls is unavailble in this install. By default, all panels are 78 + * enabled. 79 + * 80 + * @return bool True if the panel should be shown. 81 + * @task config 82 + */ 83 + public function isEnabled() { 84 + return true; 85 + } 86 + 87 + 88 + /** 89 + * You can use this callback to generate multiple similar panels which all 90 + * share the same implementation. For example, OAuth providers each have a 91 + * separate panel, but the implementation for each panel is the same. 92 + * 93 + * To generate multiple panels, build them here and return a list. By default, 94 + * the current panel (`$this`) is returned alone. For most panels, this 95 + * is the right implementation. 96 + * 97 + * @return list<PhabricatorSettingsPanel> Zero or more panels. 98 + * @task config 99 + */ 100 + public function buildPanels() { 101 + return array($this); 102 + } 103 + 104 + 105 + /* -( Panel Implementation )----------------------------------------------- */ 106 + 107 + 108 + /** 109 + * Process a user request for this settings panel. Implement this method like 110 + * a lightweight controller. If you return an @{class:AphrontResponse}, the 111 + * response will be used in whole. If you return anything else, it will be 112 + * treated as a view and composed into a normal settings page. 113 + * 114 + * Generally, render your settings panel by returning a form, then return 115 + * a redirect when the user saves settings. 116 + * 117 + * @param AphrontRequest Incoming request. 118 + * @return wild Response to request, either as an 119 + * @{class:AphrontResponse} or something which can 120 + * be composed into a @{class:AphrontView}. 121 + * @task panel 122 + */ 123 + abstract public function processRequest(AphrontRequest $request); 124 + 125 + 126 + /** 127 + * Get the URI for this panel. 128 + * 129 + * @param string? Optional path to append. 130 + * @return string Relative URI for the panel. 131 + * @task panel 132 + */ 133 + final public function getPanelURI($path = '') { 134 + $key = $this->getPanelKey(); 135 + $key = phutil_escape_uri($key); 136 + return '/settings/panel/'.$key.'/'.ltrim($path, '/'); 137 + } 138 + 139 + 140 + /* -( Internals )---------------------------------------------------------- */ 141 + 142 + 143 + /** 144 + * Generates a key to sort the list of panels. 145 + * 146 + * @return string Sortable key. 147 + * @task internal 148 + */ 149 + final public function getPanelSortKey() { 150 + return sprintf( 151 + '%s'.chr(255).'%s', 152 + $this->getPanelGroup(), 153 + $this->getPanelName()); 154 + } 155 + 156 + }
+20 -13
src/applications/settings/panel/PhabricatorUserAccountSettingsPanelController.php src/applications/settings/panel/PhabricatorSettingsPanelAccount.php
··· 16 16 * limitations under the License. 17 17 */ 18 18 19 - final class PhabricatorUserAccountSettingsPanelController 20 - extends PhabricatorUserSettingsPanelController { 19 + final class PhabricatorSettingsPanelAccount 20 + extends PhabricatorSettingsPanel { 21 + 22 + public function getPanelKey() { 23 + return 'account'; 24 + } 25 + 26 + public function getPanelName() { 27 + return pht('Account'); 28 + } 21 29 22 - public function processRequest() { 30 + public function getPanelGroup() { 31 + return pht('Account Information'); 32 + } 23 33 24 - $request = $this->getRequest(); 34 + public function processRequest(AphrontRequest $request) { 25 35 $user = $request->getUser(); 26 - $editable = $this->getAccountEditable(); 36 + $editable = PhabricatorEnv::getEnvConfig('account.editable'); 27 37 28 38 $e_realname = $editable ? true : null; 29 39 $errors = array(); ··· 47 57 if (!$errors) { 48 58 $user->save(); 49 59 return id(new AphrontRedirectResponse()) 50 - ->setURI('/settings/page/account/?saved=true'); 60 + ->setURI($this->getPanelURI('?saved=true')); 51 61 } 52 62 } 53 63 ··· 73 83 $form = new AphrontFormView(); 74 84 $form 75 85 ->setUser($user) 76 - ->setEncType('multipart/form-data') 77 86 ->appendChild( 78 87 id(new AphrontFormStaticControl()) 79 88 ->setLabel('Username') ··· 100 109 $panel->setWidth(AphrontPanelView::WIDTH_FORM); 101 110 $panel->appendChild($form); 102 111 103 - return id(new AphrontNullView()) 104 - ->appendChild( 105 - array( 106 - $notice, 107 - $panel, 108 - )); 112 + return array( 113 + $notice, 114 + $panel, 115 + ); 109 116 } 110 117 }
+24 -15
src/applications/settings/panel/PhabricatorUserConduitSettingsPanelController.php src/applications/settings/panel/PhabricatorSettingsPanelConduit.php
··· 16 16 * limitations under the License. 17 17 */ 18 18 19 - final class PhabricatorUserConduitSettingsPanelController 20 - extends PhabricatorUserSettingsPanelController { 19 + final class PhabricatorSettingsPanelConduit 20 + extends PhabricatorSettingsPanel { 21 21 22 - public function processRequest() { 22 + public function getPanelKey() { 23 + return 'conduit'; 24 + } 23 25 24 - $request = $this->getRequest(); 26 + public function getPanelName() { 27 + return pht('Conduit'); 28 + } 29 + 30 + public function getPanelGroup() { 31 + return pht('Authentication'); 32 + } 33 + 34 + public function processRequest(AphrontRequest $request) { 25 35 $user = $request->getUser(); 26 36 27 37 if ($request->isFormPost()) { ··· 29 39 $dialog = new AphrontDialogView(); 30 40 $dialog->setUser($user); 31 41 $dialog->setTitle('Really regenerate session?'); 32 - $dialog->setSubmitURI('/settings/page/conduit/'); 42 + $dialog->setSubmitURI($this->getPanelURI()); 33 43 $dialog->addSubmitButton('Regenerate'); 34 - $dialog->addCancelbutton('/settings/page/conduit/'); 44 + $dialog->addCancelbutton($this->getPanelURI()); 35 45 $dialog->appendChild( 36 46 '<p>Really destroy the old certificate? Any established '. 37 47 'sessions will be terminated.'); ··· 52 62 $user->setConduitCertificate(null); 53 63 $user->save(); 54 64 return id(new AphrontRedirectResponse()) 55 - ->setURI('/settings/page/conduit/?regenerated=true'); 65 + ->setURI($this->getPanelURI('?regenerated=true')); 56 66 } 57 67 58 68 if ($request->getStr('regenerated')) { ··· 89 99 $regen_form = new AphrontFormView(); 90 100 $regen_form 91 101 ->setUser($user) 92 - ->setAction('/settings/page/conduit/') 102 + ->setAction($this->getPanelURI()) 103 + ->setWorkflow(true) 93 104 ->appendChild( 94 105 '<p class="aphront-form-instructions">You can regenerate this '. 95 106 'certificate, which will invalidate the old certificate and create '. ··· 103 114 $regen->appendChild($regen_form); 104 115 $regen->setWidth(AphrontPanelView::WIDTH_FORM); 105 116 106 - return id(new AphrontNullView()) 107 - ->appendChild( 108 - array( 109 - $notice, 110 - $cert, 111 - $regen, 112 - )); 117 + return array( 118 + $notice, 119 + $cert, 120 + $regen, 121 + ); 113 122 } 114 123 }
+16 -5
src/applications/settings/panel/PhabricatorUserEmailPreferenceSettingsPanelController.php src/applications/settings/panel/PhabricatorSettingsPanelEmailPreferences.php
··· 16 16 * limitations under the License. 17 17 */ 18 18 19 - final class PhabricatorUserEmailPreferenceSettingsPanelController 20 - extends PhabricatorUserSettingsPanelController { 19 + final class PhabricatorSettingsPanelEmailPreferences 20 + extends PhabricatorSettingsPanel { 21 + 22 + public function getPanelKey() { 23 + return 'emailpreferences'; 24 + } 25 + 26 + public function getPanelName() { 27 + return pht('Email Preferences'); 28 + } 29 + 30 + public function getPanelGroup() { 31 + return pht('Email'); 32 + } 21 33 22 - public function processRequest() { 23 - $request = $this->getRequest(); 34 + public function processRequest(AphrontRequest $request) { 24 35 $user = $request->getUser(); 25 36 26 37 $preferences = $user->loadPreferences(); ··· 64 75 $preferences->save(); 65 76 66 77 return id(new AphrontRedirectResponse()) 67 - ->setURI('/settings/page/emailpref/?saved=true'); 78 + ->setURI($this->getPanelURI('?saved=true')); 68 79 } 69 80 70 81 $notice = null;
+39 -17
src/applications/settings/panel/PhabricatorUserEmailSettingsPanelController.php src/applications/settings/panel/PhabricatorSettingsPanelEmailAddresses.php
··· 16 16 * limitations under the License. 17 17 */ 18 18 19 - final class PhabricatorUserEmailSettingsPanelController 20 - extends PhabricatorUserSettingsPanelController { 19 + final class PhabricatorSettingsPanelEmailAddresses 20 + extends PhabricatorSettingsPanel { 21 21 22 - public function processRequest() { 22 + public function getPanelKey() { 23 + return 'email'; 24 + } 23 25 24 - $request = $this->getRequest(); 26 + public function getPanelName() { 27 + return pht('Email Addresses'); 28 + } 29 + 30 + public function getPanelGroup() { 31 + return pht('Email'); 32 + } 33 + 34 + public function processRequest(AphrontRequest $request) { 25 35 $user = $request->getUser(); 26 - $editable = $this->getAccountEditable(); 36 + $editable = PhabricatorEnv::getEnvConfig('account.editable'); 27 37 28 38 $uri = $request->getRequestURI(); 29 39 $uri->setQueryParams(array()); ··· 31 41 if ($editable) { 32 42 $new = $request->getStr('new'); 33 43 if ($new) { 34 - return $this->returnNewAddressResponse($uri, $new); 44 + return $this->returnNewAddressResponse($request, $uri, $new); 35 45 } 36 46 37 47 $delete = $request->getInt('delete'); 38 48 if ($delete) { 39 - return $this->returnDeleteAddressResponse($uri, $delete); 49 + return $this->returnDeleteAddressResponse($request, $uri, $delete); 40 50 } 41 51 } 42 52 43 53 $verify = $request->getInt('verify'); 44 54 if ($verify) { 45 - return $this->returnVerifyAddressResponse($uri, $verify); 55 + return $this->returnVerifyAddressResponse($request, $uri, $verify); 46 56 } 47 57 48 58 $primary = $request->getInt('primary'); 49 59 if ($primary) { 50 - return $this->returnPrimaryAddressResponse($uri, $primary); 60 + return $this->returnPrimaryAddressResponse($request, $uri, $primary); 51 61 } 52 62 53 63 $emails = id(new PhabricatorUserEmail())->loadAllWhere( ··· 154 164 return $view; 155 165 } 156 166 157 - private function returnNewAddressResponse(PhutilURI $uri, $new) { 158 - $request = $this->getRequest(); 167 + private function returnNewAddressResponse( 168 + AphrontRequest $request, 169 + PhutilURI $uri, 170 + $new) { 171 + 159 172 $user = $request->getUser(); 160 173 161 174 $e_email = true; ··· 234 247 return id(new AphrontDialogResponse())->setDialog($dialog); 235 248 } 236 249 237 - private function returnDeleteAddressResponse(PhutilURI $uri, $email_id) { 238 - $request = $this->getRequest(); 250 + private function returnDeleteAddressResponse( 251 + AphrontRequest $request, 252 + PhutilURI $uri, 253 + $email_id) { 254 + 239 255 $user = $request->getUser(); 240 256 241 257 // NOTE: You can only delete your own email addresses, and you can not ··· 273 289 return id(new AphrontDialogResponse())->setDialog($dialog); 274 290 } 275 291 276 - private function returnVerifyAddressResponse(PhutilURI $uri, $email_id) { 277 - $request = $this->getRequest(); 292 + private function returnVerifyAddressResponse( 293 + AphrontRequest $request, 294 + PhutilURI $uri, 295 + $email_id) { 296 + 278 297 $user = $request->getUser(); 279 298 280 299 // NOTE: You can only send more email for your unverified addresses. ··· 307 326 return id(new AphrontDialogResponse())->setDialog($dialog); 308 327 } 309 328 310 - private function returnPrimaryAddressResponse(PhutilURI $uri, $email_id) { 311 - $request = $this->getRequest(); 329 + private function returnPrimaryAddressResponse( 330 + AphrontRequest $request, 331 + PhutilURI $uri, 332 + $email_id) { 333 + 312 334 $user = $request->getUser(); 313 335 314 336 // NOTE: You can only make your own verified addresses primary.
+24 -10
src/applications/settings/panel/PhabricatorUserLDAPSettingsPanelController.php src/applications/settings/panel/PhabricatorSettingsPanelLDAP.php
··· 16 16 * limitations under the License. 17 17 */ 18 18 19 - final class PhabricatorUserLDAPSettingsPanelController 20 - extends PhabricatorUserSettingsPanelController { 19 + final class PhabricatorSettingsPanelLDAP 20 + extends PhabricatorSettingsPanel { 21 + 22 + public function getPanelKey() { 23 + return 'ldap'; 24 + } 21 25 22 - public function processRequest() { 23 - $request = $this->getRequest(); 24 - $user = $request->getUser(); 26 + public function getPanelName() { 27 + return pht('LDAP'); 28 + } 29 + 30 + public function getPanelGroup() { 31 + return pht('Linked Accounts'); 32 + } 33 + 34 + public function isEnabled() { 35 + $ldap_provider = new PhabricatorLDAPProvider(); 36 + return $ldap_provider->isProviderEnabled(); 37 + } 38 + 39 + public function processRequest(AphrontRequest $request) { 40 + $user = $request->getUser(); 25 41 26 42 $ldap_info = id(new PhabricatorUserLDAPInfo())->loadOneWhere( 27 43 'userID = %d', ··· 78 94 $panel->appendChild($form); 79 95 } 80 96 81 - return id(new AphrontNullView()) 82 - ->appendChild( 83 - array( 84 - $panel, 85 - )); 97 + return array( 98 + $panel, 99 + ); 86 100 } 87 101 }
+38 -7
src/applications/settings/panel/PhabricatorUserOAuthSettingsPanelController.php src/applications/settings/panel/PhabricatorSettingsPanelOAuth.php
··· 16 16 * limitations under the License. 17 17 */ 18 18 19 - final class PhabricatorUserOAuthSettingsPanelController 20 - extends PhabricatorUserSettingsPanelController { 19 + final class PhabricatorSettingsPanelOAuth 20 + extends PhabricatorSettingsPanel { 21 + 22 + public function getPanelKey() { 23 + return 'oauth-'.$this->provider->getProviderKey(); 24 + } 25 + 26 + public function getPanelName() { 27 + return $this->provider->getProviderName(); 28 + } 29 + 30 + public function getPanelGroup() { 31 + return pht('Linked Accounts'); 32 + } 33 + 34 + public function buildPanels() { 35 + $panels = array(); 36 + 37 + $providers = PhabricatorOAuthProvider::getAllProviders(); 38 + foreach ($providers as $provider) { 39 + $panel = clone $this; 40 + $panel->setOAuthProvider($provider); 41 + $panels[] = $panel; 42 + } 43 + 44 + return $panels; 45 + } 46 + 47 + public function isEnabled() { 48 + return $this->provider->isProviderEnabled(); 49 + } 21 50 22 51 private $provider; 23 52 ··· 48 77 return $form; 49 78 } 50 79 51 - public function processRequest() { 52 - $request = $this->getRequest(); 80 + public function processRequest(AphrontRequest $request) { 53 81 $user = $request->getUser(); 54 82 $provider = $this->provider; 55 83 $notice = null; ··· 62 90 $provider->getProviderKey()); 63 91 64 92 if ($request->isFormPost() && $oauth_info) { 65 - $notice = $this->refreshProfileImage($oauth_info); 93 + $notice = $this->refreshProfileImage($request, $oauth_info); 66 94 } 67 95 68 96 $form = new AphrontFormView(); ··· 198 226 )); 199 227 } 200 228 201 - private function refreshProfileImage(PhabricatorUserOAuthInfo $oauth_info) { 202 - $user = $this->getRequest()->getUser(); 229 + private function refreshProfileImage( 230 + AphrontRequest $request, 231 + PhabricatorUserOAuthInfo $oauth_info) { 232 + 233 + $user = $request->getUser(); 203 234 $provider = $this->provider; 204 235 $error = false; 205 236 $userinfo_uri = new PhutilURI($provider->getUserInfoURI());
+34 -17
src/applications/settings/panel/PhabricatorUserPasswordSettingsPanelController.php src/applications/settings/panel/PhabricatorSettingsPanelPassword.php
··· 16 16 * limitations under the License. 17 17 */ 18 18 19 - final class PhabricatorUserPasswordSettingsPanelController 20 - extends PhabricatorUserSettingsPanelController { 19 + final class PhabricatorSettingsPanelPassword 20 + extends PhabricatorSettingsPanel { 21 21 22 - public function processRequest() { 22 + public function getPanelKey() { 23 + return 'password'; 24 + } 23 25 24 - $request = $this->getRequest(); 25 - $user = $request->getUser(); 26 - $editable = $this->getAccountEditable(); 26 + public function getPanelName() { 27 + return pht('Password'); 28 + } 27 29 30 + public function getPanelGroup() { 31 + return pht('Authentication'); 32 + } 33 + 34 + public function isEnabled() { 28 35 // There's no sense in showing a change password panel if the user 29 - // can't change their password 30 - if (!$editable || 31 - !PhabricatorEnv::getEnvConfig('auth.password-auth-enabled')) { 32 - return new Aphront400Response(); 36 + // can't change their password... 37 + 38 + if (!PhabricatorEnv::getEnvConfig('account.editable')) { 39 + return false; 40 + } 41 + 42 + // ...or this install doesn't support password authentication at all. 43 + 44 + if (!PhabricatorEnv::getEnvConfig('auth.password-auth-enabled')) { 45 + return false; 33 46 } 47 + 48 + return true; 49 + } 50 + 51 + public function processRequest(AphrontRequest $request) { 52 + $user = $request->getUser(); 34 53 35 54 $min_len = PhabricatorEnv::getEnvConfig('account.minimum-password-length'); 36 55 $min_len = (int)$min_len; ··· 98 117 // after we update their account. 99 118 $next = '/'; 100 119 } else { 101 - $next = '/settings/page/password/?saved=true'; 120 + $next = $this->getPanelURI('?saved=true'); 102 121 } 103 122 104 123 return id(new AphrontRedirectResponse())->setURI($next); ··· 160 179 $panel->setWidth(AphrontPanelView::WIDTH_FORM); 161 180 $panel->appendChild($form); 162 181 163 - return id(new AphrontNullView()) 164 - ->appendChild( 165 - array( 166 - $notice, 167 - $panel, 168 - )); 182 + return array( 183 + $notice, 184 + $panel, 185 + ); 169 186 } 170 187 }
+20 -13
src/applications/settings/panel/PhabricatorUserPreferenceSettingsPanelController.php src/applications/settings/panel/PhabricatorSettingsPanelDisplayPreferences.php
··· 16 16 * limitations under the License. 17 17 */ 18 18 19 - final class PhabricatorUserPreferenceSettingsPanelController 20 - extends PhabricatorUserSettingsPanelController { 19 + final class PhabricatorSettingsPanelDisplayPreferences 20 + extends PhabricatorSettingsPanel { 21 + 22 + public function getPanelKey() { 23 + return 'display'; 24 + } 25 + 26 + public function getPanelName() { 27 + return pht('Display Preferences'); 28 + } 21 29 22 - public function processRequest() { 30 + public function getPanelGroup() { 31 + return pht('Application Settings'); 32 + } 23 33 24 - $request = $this->getRequest(); 34 + public function processRequest(AphrontRequest $request) { 25 35 $user = $request->getUser(); 26 36 $preferences = $user->loadPreferences(); 27 37 ··· 44 54 45 55 $preferences->save(); 46 56 return id(new AphrontRedirectResponse()) 47 - ->setURI('/settings/page/preferences/?saved=true'); 57 + ->setURI($this->getPanelURI('?saved=true')); 48 58 } 49 59 50 60 $example_string = <<<EXAMPLE ··· 67 77 68 78 $form = id(new AphrontFormView()) 69 79 ->setUser($user) 70 - ->setAction('/settings/page/preferences/') 71 80 ->appendChild( 72 81 id(new AphrontFormSelectControl()) 73 82 ->setLabel('Page Titles') ··· 95 104 ->setLabel('Monospaced Font') 96 105 ->setName($pref_monospaced) 97 106 ->setCaption( 98 - 'Overrides default fonts in tools like Differential. '. 107 + 'Overrides default fonts in tools like Differential.<br />'. 99 108 '(Default: '.$font_default.')') 100 109 ->setValue($preferences->getPreference($pref_monospaced))) 101 110 ->appendChild( ··· 130 139 ->setErrors(array('Your preferences have been saved.')); 131 140 } 132 141 133 - return id(new AphrontNullView()) 134 - ->appendChild( 135 - array( 136 - $error_view, 137 - $panel, 138 - )); 142 + return array( 143 + $error_view, 144 + $panel, 145 + ); 139 146 } 140 147 } 141 148
+20 -13
src/applications/settings/panel/PhabricatorUserProfileSettingsPanelController.php src/applications/settings/panel/PhabricatorSettingsPanelProfile.php
··· 16 16 * limitations under the License. 17 17 */ 18 18 19 - final class PhabricatorUserProfileSettingsPanelController 20 - extends PhabricatorUserSettingsPanelController { 19 + final class PhabricatorSettingsPanelProfile 20 + extends PhabricatorSettingsPanel { 21 + 22 + public function getPanelKey() { 23 + return 'profile'; 24 + } 25 + 26 + public function getPanelName() { 27 + return pht('Profile'); 28 + } 21 29 22 - public function processRequest() { 30 + public function getPanelGroup() { 31 + return pht('Account Information'); 32 + } 23 33 24 - $request = $this->getRequest(); 34 + public function processRequest(AphrontRequest $request) { 25 35 $user = $request->getUser(); 26 36 27 37 $profile = id(new PhabricatorUserProfile())->loadOneWhere( ··· 95 105 $user->save(); 96 106 $profile->save(); 97 107 $response = id(new AphrontRedirectResponse()) 98 - ->setURI('/settings/page/profile/?saved=true'); 108 + ->setURI($this->getPanelURI('?saved=true')); 99 109 return $response; 100 110 } 101 111 } ··· 143 153 $form = new AphrontFormView(); 144 154 $form 145 155 ->setUser($request->getUser()) 146 - ->setAction('/settings/page/profile/') 147 156 ->setEncType('multipart/form-data') 148 157 ->appendChild( 149 158 id(new AphrontFormTextControl()) ··· 176 185 ->appendChild( 177 186 '<p class="aphront-form-instructions">Write something about yourself! '. 178 187 'Make sure to include <strong>important information</strong> like '. 179 - 'your favorite pokemon and which Starcraft race you play.</p>') 188 + 'your favorite Pokemon and which Starcraft race you play.</p>') 180 189 ->appendChild( 181 190 id(new AphrontFormTextAreaControl()) 182 191 ->setLabel('Blurb') ··· 207 216 $panel->appendChild($form); 208 217 $panel->setWidth(AphrontPanelView::WIDTH_FORM); 209 218 210 - return id(new AphrontNullView()) 211 - ->appendChild( 212 - array( 213 - $error_view, 214 - $panel, 215 - )); 219 + return array( 220 + $error_view, 221 + $panel, 222 + ); 216 223 } 217 224 218 225 }
+31 -20
src/applications/settings/panel/PhabricatorUserSSHKeysSettingsPanelController.php src/applications/settings/panel/PhabricatorSettingsPanelSSHKeys.php
··· 16 16 * limitations under the License. 17 17 */ 18 18 19 - final class PhabricatorUserSSHKeysSettingsPanelController 20 - extends PhabricatorUserSettingsPanelController { 19 + final class PhabricatorSettingsPanelSSHKeys 20 + extends PhabricatorSettingsPanel { 21 + 22 + public function getPanelKey() { 23 + return 'ssh'; 24 + } 21 25 22 - const PANEL_BASE_URI = '/settings/page/sshkeys/'; 26 + public function getPanelName() { 27 + return pht('SSH Public Keys'); 28 + } 23 29 24 - public static function isEnabled() { 30 + public function getPanelGroup() { 31 + return pht('Authentication'); 32 + } 33 + 34 + public function isEnabled() { 25 35 return PhabricatorEnv::getEnvConfig('auth.sshkeys.enabled'); 26 36 } 27 37 28 - public function processRequest() { 38 + public function processRequest(AphrontRequest $request) { 29 39 30 - $request = $this->getRequest(); 31 40 $user = $request->getUser(); 32 41 33 42 $edit = $request->getStr('edit'); 34 43 $delete = $request->getStr('delete'); 35 44 if (!$edit && !$delete) { 36 - return $this->renderKeyListView(); 45 + return $this->renderKeyListView($request); 37 46 } 38 47 39 48 $id = nonempty($edit, $delete); ··· 43 52 $key = id(new PhabricatorUserSSHKey())->loadOneWhere( 44 53 'userPHID = %s AND id = %d', 45 54 $user->getPHID(), 46 - $id); 55 + (int)$id); 47 56 if (!$key) { 48 57 return new Aphront404Response(); 49 58 } ··· 53 62 } 54 63 55 64 if ($delete) { 56 - return $this->processDelete($key); 65 + return $this->processDelete($request, $key); 57 66 } 58 67 59 68 $e_name = true; ··· 113 122 try { 114 123 $key->save(); 115 124 return id(new AphrontRedirectResponse()) 116 - ->setURI(self::PANEL_BASE_URI); 125 + ->setURI($this->getPanelURI()); 117 126 } catch (AphrontQueryDuplicateKeyException $ex) { 118 127 $e_key = 'Duplicate'; 119 128 $errors[] = 'This public key is already associated with a user '. ··· 156 165 ->setError($e_key)) 157 166 ->appendChild( 158 167 id(new AphrontFormSubmitControl()) 159 - ->addCancelButton(self::PANEL_BASE_URI) 168 + ->addCancelButton($this->getPanelURI()) 160 169 ->setValue($save)); 161 170 162 171 $panel = new AphrontPanelView(); ··· 172 181 )); 173 182 } 174 183 175 - private function renderKeyListView() { 176 - $request = $this->getRequest(); 184 + private function renderKeyListView(AphrontRequest $request) { 185 + 177 186 $user = $request->getUser(); 178 187 179 188 $keys = id(new PhabricatorUserSSHKey())->loadAllWhere( ··· 186 195 phutil_render_tag( 187 196 'a', 188 197 array( 189 - 'href' => '/settings/page/sshkeys/?edit='.$key->getID(), 198 + 'href' => $this->getPanelURI('?edit='.$key->getID()), 190 199 ), 191 200 phutil_escape_html($key->getName())), 192 201 phutil_escape_html($key->getKeyComment()), ··· 196 205 javelin_render_tag( 197 206 'a', 198 207 array( 199 - 'href' => '/settings/page/sshkeys/?delete='.$key->getID(), 208 + 'href' => $this->getPanelURI('?delete='.$key->getID()), 200 209 'class' => 'small grey button', 201 210 'sigil' => 'workflow', 202 211 ), ··· 230 239 phutil_render_tag( 231 240 'a', 232 241 array( 233 - 'href' => '/settings/page/sshkeys/?edit=true', 242 + 'href' => $this->getPanelURI('?edit=true'), 234 243 'class' => 'green button', 235 244 ), 236 245 'Add New Public Key')); ··· 240 249 return $panel; 241 250 } 242 251 243 - private function processDelete(PhabricatorUserSSHKey $key) { 244 - $request = $this->getRequest(); 252 + private function processDelete( 253 + AphrontRequest $request, 254 + PhabricatorUserSSHKey $key) { 255 + 245 256 $user = $request->getUser(); 246 257 247 258 $name = phutil_escape_html($key->getName()); ··· 249 260 if ($request->isDialogFormPost()) { 250 261 $key->delete(); 251 262 return id(new AphrontReloadResponse()) 252 - ->setURI(self::PANEL_BASE_URI); 263 + ->setURI($this->getPanelURI()); 253 264 } 254 265 255 266 $dialog = id(new AphrontDialogView()) ··· 261 272 'and you will not longer be able to use the corresponding private key '. 262 273 'to authenticate.</p>') 263 274 ->addSubmitButton('Delete Public Key') 264 - ->addCancelButton(self::PANEL_BASE_URI); 275 + ->addCancelButton($this->getPanelURI()); 265 276 266 277 return id(new AphrontDialogResponse()) 267 278 ->setDialog($dialog);
+20 -13
src/applications/settings/panel/PhabricatorUserSearchSettingsPanelController.php src/applications/settings/panel/PhabricatorSettingsPanelSearchPreferences.php
··· 16 16 * limitations under the License. 17 17 */ 18 18 19 - final class PhabricatorUserSearchSettingsPanelController 20 - extends PhabricatorUserSettingsPanelController { 19 + final class PhabricatorSettingsPanelSearchPreferences 20 + extends PhabricatorSettingsPanel { 21 + 22 + public function getPanelKey() { 23 + return 'search'; 24 + } 25 + 26 + public function getPanelName() { 27 + return pht('Search Preferences'); 28 + } 21 29 22 - public function processRequest() { 30 + public function getPanelGroup() { 31 + return pht('Application Settings'); 32 + } 23 33 24 - $request = $this->getRequest(); 34 + public function processRequest(AphrontRequest $request) { 25 35 $user = $request->getUser(); 26 36 $preferences = $user->loadPreferences(); 27 37 ··· 37 47 38 48 $preferences->save(); 39 49 return id(new AphrontRedirectResponse()) 40 - ->setURI('/settings/page/search/?saved=true'); 50 + ->setURI($this->getPanelURI('?saved=true')); 41 51 } 42 52 43 53 $form = id(new AphrontFormView()) 44 54 ->setUser($user) 45 - ->setAction('/settings/page/search/') 46 55 ->appendChild( 47 56 id(new AphrontFormCheckboxControl()) 48 57 ->addCheckbox($pref_jump, ··· 51 60 $preferences->getPreference($pref_jump, 1)) 52 61 ->addCheckbox($pref_shortcut, 53 62 1, 54 - '\'/\' focuses search box.', 63 + "Press '/' to focus the search input.", 55 64 $preferences->getPreference($pref_shortcut, 1)) 56 65 ) 57 66 ->appendChild( ··· 71 80 ->setErrors(array('Your preferences have been saved.')); 72 81 } 73 82 74 - return id(new AphrontNullView()) 75 - ->appendChild( 76 - array( 77 - $error_view, 78 - $panel, 79 - )); 83 + return array( 84 + $error_view, 85 + $panel, 86 + ); 80 87 } 81 88 } 82 89
-26
src/applications/settings/panel/PhabricatorUserSettingsPanelController.php
··· 1 - <?php 2 - 3 - /* 4 - * Copyright 2012 Facebook, Inc. 5 - * 6 - * Licensed under the Apache License, Version 2.0 (the "License"); 7 - * you may not use this file except in compliance with the License. 8 - * You may obtain a copy of the License at 9 - * 10 - * http://www.apache.org/licenses/LICENSE-2.0 11 - * 12 - * Unless required by applicable law or agreed to in writing, software 13 - * distributed under the License is distributed on an "AS IS" BASIS, 14 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 - * See the License for the specific language governing permissions and 16 - * limitations under the License. 17 - */ 18 - 19 - abstract class PhabricatorUserSettingsPanelController 20 - extends PhabricatorPeopleController { 21 - 22 - public function getAccountEditable() { 23 - return PhabricatorEnv::getEnvConfig('account.editable'); 24 - } 25 - 26 - }