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
This commit is contained in:
epriestley 2012-08-13 12:37:26 -07:00
parent df5bf75e36
commit 20ac900e8b
25 changed files with 548 additions and 311 deletions

View file

@ -1003,6 +1003,18 @@ phutil_register_library_map(array(
'PhabricatorSearchUserIndexer' => 'applications/search/index/indexer/PhabricatorSearchUserIndexer.php', 'PhabricatorSearchUserIndexer' => 'applications/search/index/indexer/PhabricatorSearchUserIndexer.php',
'PhabricatorSettingsAdjustController' => 'applications/settings/controller/PhabricatorSettingsAdjustController.php', 'PhabricatorSettingsAdjustController' => 'applications/settings/controller/PhabricatorSettingsAdjustController.php',
'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php', 'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php',
'PhabricatorSettingsPanel' => 'applications/settings/panel/PhabricatorSettingsPanel.php',
'PhabricatorSettingsPanelAccount' => 'applications/settings/panel/PhabricatorSettingsPanelAccount.php',
'PhabricatorSettingsPanelConduit' => 'applications/settings/panel/PhabricatorSettingsPanelConduit.php',
'PhabricatorSettingsPanelDisplayPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelDisplayPreferences.php',
'PhabricatorSettingsPanelEmailAddresses' => 'applications/settings/panel/PhabricatorSettingsPanelEmailAddresses.php',
'PhabricatorSettingsPanelEmailPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelEmailPreferences.php',
'PhabricatorSettingsPanelLDAP' => 'applications/settings/panel/PhabricatorSettingsPanelLDAP.php',
'PhabricatorSettingsPanelOAuth' => 'applications/settings/panel/PhabricatorSettingsPanelOAuth.php',
'PhabricatorSettingsPanelPassword' => 'applications/settings/panel/PhabricatorSettingsPanelPassword.php',
'PhabricatorSettingsPanelProfile' => 'applications/settings/panel/PhabricatorSettingsPanelProfile.php',
'PhabricatorSettingsPanelSSHKeys' => 'applications/settings/panel/PhabricatorSettingsPanelSSHKeys.php',
'PhabricatorSettingsPanelSearchPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelSearchPreferences.php',
'PhabricatorSetup' => 'infrastructure/PhabricatorSetup.php', 'PhabricatorSetup' => 'infrastructure/PhabricatorSetup.php',
'PhabricatorSlowvoteChoice' => 'applications/slowvote/storage/PhabricatorSlowvoteChoice.php', 'PhabricatorSlowvoteChoice' => 'applications/slowvote/storage/PhabricatorSlowvoteChoice.php',
'PhabricatorSlowvoteComment' => 'applications/slowvote/storage/PhabricatorSlowvoteComment.php', 'PhabricatorSlowvoteComment' => 'applications/slowvote/storage/PhabricatorSlowvoteComment.php',
@ -1053,27 +1065,15 @@ phutil_register_library_map(array(
'PhabricatorUITooltipExample' => 'applications/uiexample/examples/PhabricatorUITooltipExample.php', 'PhabricatorUITooltipExample' => 'applications/uiexample/examples/PhabricatorUITooltipExample.php',
'PhabricatorUnitsTestCase' => 'view/__tests__/PhabricatorUnitsTestCase.php', 'PhabricatorUnitsTestCase' => 'view/__tests__/PhabricatorUnitsTestCase.php',
'PhabricatorUser' => 'applications/people/storage/PhabricatorUser.php', 'PhabricatorUser' => 'applications/people/storage/PhabricatorUser.php',
'PhabricatorUserAccountSettingsPanelController' => 'applications/settings/panel/PhabricatorUserAccountSettingsPanelController.php',
'PhabricatorUserConduitSettingsPanelController' => 'applications/settings/panel/PhabricatorUserConduitSettingsPanelController.php',
'PhabricatorUserDAO' => 'applications/people/storage/PhabricatorUserDAO.php', 'PhabricatorUserDAO' => 'applications/people/storage/PhabricatorUserDAO.php',
'PhabricatorUserEditor' => 'applications/people/PhabricatorUserEditor.php', 'PhabricatorUserEditor' => 'applications/people/PhabricatorUserEditor.php',
'PhabricatorUserEmail' => 'applications/people/storage/PhabricatorUserEmail.php', 'PhabricatorUserEmail' => 'applications/people/storage/PhabricatorUserEmail.php',
'PhabricatorUserEmailPreferenceSettingsPanelController' => 'applications/settings/panel/PhabricatorUserEmailPreferenceSettingsPanelController.php',
'PhabricatorUserEmailSettingsPanelController' => 'applications/settings/panel/PhabricatorUserEmailSettingsPanelController.php',
'PhabricatorUserLDAPInfo' => 'applications/people/storage/PhabricatorUserLDAPInfo.php', 'PhabricatorUserLDAPInfo' => 'applications/people/storage/PhabricatorUserLDAPInfo.php',
'PhabricatorUserLDAPSettingsPanelController' => 'applications/settings/panel/PhabricatorUserLDAPSettingsPanelController.php',
'PhabricatorUserLog' => 'applications/people/storage/PhabricatorUserLog.php', 'PhabricatorUserLog' => 'applications/people/storage/PhabricatorUserLog.php',
'PhabricatorUserOAuthInfo' => 'applications/people/storage/PhabricatorUserOAuthInfo.php', 'PhabricatorUserOAuthInfo' => 'applications/people/storage/PhabricatorUserOAuthInfo.php',
'PhabricatorUserOAuthSettingsPanelController' => 'applications/settings/panel/PhabricatorUserOAuthSettingsPanelController.php',
'PhabricatorUserPasswordSettingsPanelController' => 'applications/settings/panel/PhabricatorUserPasswordSettingsPanelController.php',
'PhabricatorUserPreferenceSettingsPanelController' => 'applications/settings/panel/PhabricatorUserPreferenceSettingsPanelController.php',
'PhabricatorUserPreferences' => 'applications/settings/storage/PhabricatorUserPreferences.php', 'PhabricatorUserPreferences' => 'applications/settings/storage/PhabricatorUserPreferences.php',
'PhabricatorUserProfile' => 'applications/people/storage/PhabricatorUserProfile.php', 'PhabricatorUserProfile' => 'applications/people/storage/PhabricatorUserProfile.php',
'PhabricatorUserProfileSettingsPanelController' => 'applications/settings/panel/PhabricatorUserProfileSettingsPanelController.php',
'PhabricatorUserSSHKey' => 'applications/settings/storage/PhabricatorUserSSHKey.php', 'PhabricatorUserSSHKey' => 'applications/settings/storage/PhabricatorUserSSHKey.php',
'PhabricatorUserSSHKeysSettingsPanelController' => 'applications/settings/panel/PhabricatorUserSSHKeysSettingsPanelController.php',
'PhabricatorUserSearchSettingsPanelController' => 'applications/settings/panel/PhabricatorUserSearchSettingsPanelController.php',
'PhabricatorUserSettingsPanelController' => 'applications/settings/panel/PhabricatorUserSettingsPanelController.php',
'PhabricatorUserStatus' => 'applications/people/storage/PhabricatorUserStatus.php', 'PhabricatorUserStatus' => 'applications/people/storage/PhabricatorUserStatus.php',
'PhabricatorUserTestCase' => 'applications/people/storage/__tests__/PhabricatorUserTestCase.php', 'PhabricatorUserTestCase' => 'applications/people/storage/__tests__/PhabricatorUserTestCase.php',
'PhabricatorWorker' => 'infrastructure/daemon/workers/PhabricatorWorker.php', 'PhabricatorWorker' => 'infrastructure/daemon/workers/PhabricatorWorker.php',
@ -2074,6 +2074,17 @@ phutil_register_library_map(array(
'PhabricatorSearchUserIndexer' => 'PhabricatorSearchDocumentIndexer', 'PhabricatorSearchUserIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorSettingsAdjustController' => 'PhabricatorController', 'PhabricatorSettingsAdjustController' => 'PhabricatorController',
'PhabricatorSettingsMainController' => 'PhabricatorController', 'PhabricatorSettingsMainController' => 'PhabricatorController',
'PhabricatorSettingsPanelAccount' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelConduit' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelDisplayPreferences' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelEmailAddresses' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelEmailPreferences' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelLDAP' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelOAuth' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelPassword' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelProfile' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelSSHKeys' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelSearchPreferences' => 'PhabricatorSettingsPanel',
'PhabricatorSlowvoteChoice' => 'PhabricatorSlowvoteDAO', 'PhabricatorSlowvoteChoice' => 'PhabricatorSlowvoteDAO',
'PhabricatorSlowvoteComment' => 'PhabricatorSlowvoteDAO', 'PhabricatorSlowvoteComment' => 'PhabricatorSlowvoteDAO',
'PhabricatorSlowvoteController' => 'PhabricatorController', 'PhabricatorSlowvoteController' => 'PhabricatorController',
@ -2119,26 +2130,14 @@ phutil_register_library_map(array(
0 => 'PhabricatorUserDAO', 0 => 'PhabricatorUserDAO',
1 => 'PhutilPerson', 1 => 'PhutilPerson',
), ),
'PhabricatorUserAccountSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserConduitSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserDAO' => 'PhabricatorLiskDAO', 'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
'PhabricatorUserEmail' => 'PhabricatorUserDAO', 'PhabricatorUserEmail' => 'PhabricatorUserDAO',
'PhabricatorUserEmailPreferenceSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserEmailSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserLDAPInfo' => 'PhabricatorUserDAO', 'PhabricatorUserLDAPInfo' => 'PhabricatorUserDAO',
'PhabricatorUserLDAPSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserLog' => 'PhabricatorUserDAO', 'PhabricatorUserLog' => 'PhabricatorUserDAO',
'PhabricatorUserOAuthInfo' => 'PhabricatorUserDAO', 'PhabricatorUserOAuthInfo' => 'PhabricatorUserDAO',
'PhabricatorUserOAuthSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserPasswordSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserPreferenceSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserPreferences' => 'PhabricatorUserDAO', 'PhabricatorUserPreferences' => 'PhabricatorUserDAO',
'PhabricatorUserProfile' => 'PhabricatorUserDAO', 'PhabricatorUserProfile' => 'PhabricatorUserDAO',
'PhabricatorUserProfileSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserSSHKey' => 'PhabricatorUserDAO', 'PhabricatorUserSSHKey' => 'PhabricatorUserDAO',
'PhabricatorUserSSHKeysSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserSearchSettingsPanelController' => 'PhabricatorUserSettingsPanelController',
'PhabricatorUserSettingsPanelController' => 'PhabricatorPeopleController',
'PhabricatorUserStatus' => 'PhabricatorUserDAO', 'PhabricatorUserStatus' => 'PhabricatorUserDAO',
'PhabricatorUserTestCase' => 'PhabricatorTestCase', 'PhabricatorUserTestCase' => 'PhabricatorTestCase',
'PhabricatorWorkerDAO' => 'PhabricatorLiskDAO', 'PhabricatorWorkerDAO' => 'PhabricatorLiskDAO',

View file

@ -97,7 +97,7 @@ final class PhabricatorEmailTokenController
$request->setCookie('phsid', $session_key); $request->setCookie('phsid', $session_key);
if (PhabricatorEnv::getEnvConfig('account.editable')) { if (PhabricatorEnv::getEnvConfig('account.editable')) {
$next = (string)id(new PhutilURI('/settings/page/password/')) $next = (string)id(new PhutilURI('/settings/panel/password/'))
->setQueryParams( ->setQueryParams(
array( array(
'token' => $token, 'token' => $token,

View file

@ -64,12 +64,12 @@ final class PhabricatorLDAPLoginController extends PhabricatorAuthController {
'another Phabricator account. Before you can link it to a '. 'another Phabricator account. Before you can link it to a '.
'different LDAP account, you must unlink the old account.</p>' 'different LDAP account, you must unlink the old account.</p>'
); );
$dialog->addCancelButton('/settings/page/ldap/'); $dialog->addCancelButton('/settings/panel/ldap/');
return id(new AphrontDialogResponse())->setDialog($dialog); return id(new AphrontDialogResponse())->setDialog($dialog);
} else { } else {
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())
->setURI('/settings/page/ldap/'); ->setURI('/settings/panel/ldap/');
} }
} }
@ -82,7 +82,7 @@ final class PhabricatorLDAPLoginController extends PhabricatorAuthController {
$dialog->addHiddenInput('username', $request->getStr('username')); $dialog->addHiddenInput('username', $request->getStr('username'));
$dialog->addHiddenInput('password', $request->getStr('password')); $dialog->addHiddenInput('password', $request->getStr('password'));
$dialog->addSubmitButton('Link Accounts'); $dialog->addSubmitButton('Link Accounts');
$dialog->addCancelButton('/settings/page/ldap/'); $dialog->addCancelButton('/settings/panel/ldap/');
return id(new AphrontDialogResponse())->setDialog($dialog); return id(new AphrontDialogResponse())->setDialog($dialog);
} }
@ -92,7 +92,7 @@ final class PhabricatorLDAPLoginController extends PhabricatorAuthController {
$this->saveLDAPInfo($ldap_info); $this->saveLDAPInfo($ldap_info);
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())
->setURI('/settings/page/ldap/'); ->setURI('/settings/panel/ldap/');
} }
if ($ldap_info->getID()) { if ($ldap_info->getID()) {

View file

@ -38,7 +38,7 @@ final class PhabricatorLDAPUnlinkController extends PhabricatorAuthController {
'<p><strong>You will not be able to login</strong> using this account '. '<p><strong>You will not be able to login</strong> using this account '.
'once you unlink it. Continue?</p>'); 'once you unlink it. Continue?</p>');
$dialog->addSubmitButton('Unlink Account'); $dialog->addSubmitButton('Unlink Account');
$dialog->addCancelButton('/settings/page/ldap/'); $dialog->addCancelButton('/settings/panel/ldap/');
return id(new AphrontDialogResponse())->setDialog($dialog); return id(new AphrontDialogResponse())->setDialog($dialog);
} }
@ -46,7 +46,7 @@ final class PhabricatorLDAPUnlinkController extends PhabricatorAuthController {
$ldap_info->delete(); $ldap_info->delete();
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())
->setURI('/settings/page/ldap/'); ->setURI('/settings/panel/ldap/');
} }
} }

View file

@ -93,13 +93,13 @@ final class PhabricatorOAuthLoginController
'the Phabricator account it is currently linked to.</p>', 'the Phabricator account it is currently linked to.</p>',
$provider_name, $provider_name,
$provider_name)); $provider_name));
$dialog->addCancelButton('/settings/page/'.$provider_key.'/'); $dialog->addCancelButton($provider->getSettingsPanelURI());
return id(new AphrontDialogResponse())->setDialog($dialog); return id(new AphrontDialogResponse())->setDialog($dialog);
} else { } else {
$this->saveOAuthInfo($oauth_info); // Refresh token. $this->saveOAuthInfo($oauth_info); // Refresh token.
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())
->setURI('/settings/page/'.$provider_key.'/'); ->setURI($provider->getSettingsPanelURI());
} }
} }
@ -119,7 +119,7 @@ final class PhabricatorOAuthLoginController
'must unlink the old account.</p>', 'must unlink the old account.</p>',
$provider_name, $provider_name,
$provider_name)); $provider_name));
$dialog->addCancelButton('/settings/page/'.$provider_key.'/'); $dialog->addCancelButton($provider->getSettingsPanelURI());
return id(new AphrontDialogResponse())->setDialog($dialog); return id(new AphrontDialogResponse())->setDialog($dialog);
} }
@ -136,7 +136,7 @@ final class PhabricatorOAuthLoginController
$dialog->addHiddenInput('state', $this->oauthState); $dialog->addHiddenInput('state', $this->oauthState);
$dialog->addHiddenInput('scope', $oauth_info->getTokenScope()); $dialog->addHiddenInput('scope', $oauth_info->getTokenScope());
$dialog->addSubmitButton('Link Accounts'); $dialog->addSubmitButton('Link Accounts');
$dialog->addCancelButton('/settings/page/'.$provider_key.'/'); $dialog->addCancelButton($provider->getSettingsPanelURI());
return id(new AphrontDialogResponse())->setDialog($dialog); return id(new AphrontDialogResponse())->setDialog($dialog);
} }
@ -146,7 +146,7 @@ final class PhabricatorOAuthLoginController
$this->saveOAuthInfo($oauth_info); $this->saveOAuthInfo($oauth_info);
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())
->setURI('/settings/page/'.$provider_key.'/'); ->setURI($provider->getSettingsPanelURI());
} }
// Login with known auth. // Login with known auth.

View file

@ -54,7 +54,7 @@ final class PhabricatorOAuthUnlinkController extends PhabricatorAuthController {
'<p><strong>You will not be able to login</strong> using this account '. '<p><strong>You will not be able to login</strong> using this account '.
'once you unlink it. Continue?</p>'); 'once you unlink it. Continue?</p>');
$dialog->addSubmitButton('Unlink Account'); $dialog->addSubmitButton('Unlink Account');
$dialog->addCancelButton('/settings/page/'.$provider_key.'/'); $dialog->addCancelButton($provider->getSettingsPanelURI());
return id(new AphrontDialogResponse())->setDialog($dialog); return id(new AphrontDialogResponse())->setDialog($dialog);
} }
@ -62,7 +62,7 @@ final class PhabricatorOAuthUnlinkController extends PhabricatorAuthController {
$oauth_info->delete(); $oauth_info->delete();
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())
->setURI('/settings/page/'.$provider_key.'/'); ->setURI($provider->getSettingsPanelURI());
} }
} }

View file

@ -38,6 +38,12 @@ abstract class PhabricatorOAuthProvider {
abstract public function getAuthURI(); abstract public function getAuthURI();
abstract public function getTestURIs(); abstract public function getTestURIs();
public function getSettingsPanelURI() {
$panel = new PhabricatorSettingsPanelOAuth();
$panel->setOAuthProvider($this);
return $panel->getPanelURI();
}
/** /**
* If the provider needs extra stuff in the auth request, return it here. * If the provider needs extra stuff in the auth request, return it here.
* For example, Google needs a response_type parameter. * For example, Google needs a response_type parameter.

View file

@ -293,7 +293,7 @@ final class DifferentialChangesetListView extends AphrontView {
if ($editor_link) { if ($editor_link) {
$meta['editor'] = $editor_link; $meta['editor'] = $editor_link;
} else { } else {
$meta['editorConfigure'] = '/settings/page/preferences/'; $meta['editorConfigure'] = '/settings/panel/display/';
} }
} }

View file

@ -51,7 +51,7 @@ final class PhabricatorEmailVerificationController
$settings_link = phutil_render_tag( $settings_link = phutil_render_tag(
'a', 'a',
array( array(
'href' => '/settings/page/email/', 'href' => '/settings/panel/email/',
), ),
'Return to Email Settings'); 'Return to Email Settings');
$settings_link = '<br /><p><strong>'.$settings_link.'</strong></p>'; $settings_link = '<br /><p><strong>'.$settings_link.'</strong></p>';

View file

@ -147,7 +147,7 @@ final class PhabricatorPeopleProfileController
if ($user->getPHID() == $viewer->getPHID()) { if ($user->getPHID() == $viewer->getPHID()) {
$nav->addSpacer(); $nav->addSpacer();
$nav->addFilter(null, 'Edit Profile...', '/settings/page/profile/'); $nav->addFilter(null, 'Edit Profile...', '/settings/panel/profile/');
} }
if ($viewer->getIsAdmin()) { if ($viewer->getIsAdmin()) {

View file

@ -33,7 +33,7 @@ final class PhabricatorApplicationSettings extends PhabricatorApplication {
public function getRoutes() { public function getRoutes() {
return array( return array(
'/settings/' => array( '/settings/' => array(
'(?:page/(?P<page>[^/]+)/)?' => 'PhabricatorSettingsMainController', '(?:panel/(?P<key>[^/]+)/)?' => 'PhabricatorSettingsMainController',
'adjust/' => 'PhabricatorSettingsAdjustController', 'adjust/' => 'PhabricatorSettingsAdjustController',
), ),
); );

View file

@ -19,128 +19,87 @@
final class PhabricatorSettingsMainController final class PhabricatorSettingsMainController
extends PhabricatorController { extends PhabricatorController {
private $page; private $key;
private $pages;
public function willProcessRequest(array $data) { public function willProcessRequest(array $data) {
$this->page = idx($data, 'page'); $this->key = idx($data, 'key');
} }
public function processRequest() { public function processRequest() {
$request = $this->getRequest(); $request = $this->getRequest();
$oauth_providers = PhabricatorOAuthProvider::getAllProviders(); $panels = $this->buildPanels();
$sidenav = $this->renderSideNav($oauth_providers); $nav = $this->renderSideNav($panels);
$this->page = $sidenav->selectFilter($this->page, 'account');
switch ($this->page) { $key = $nav->selectFilter($this->key, head($panels)->getPanelKey());
case 'account':
$delegate = new PhabricatorUserAccountSettingsPanelController($request);
break;
case 'profile':
$delegate = new PhabricatorUserProfileSettingsPanelController($request);
break;
case 'email':
$delegate = new PhabricatorUserEmailSettingsPanelController($request);
break;
case 'emailpref':
$delegate = new PhabricatorUserEmailPreferenceSettingsPanelController(
$request);
break;
case 'password':
$delegate = new PhabricatorUserPasswordSettingsPanelController(
$request);
break;
case 'conduit':
$delegate = new PhabricatorUserConduitSettingsPanelController($request);
break;
case 'sshkeys':
$delegate = new PhabricatorUserSSHKeysSettingsPanelController($request);
break;
case 'preferences':
$delegate = new PhabricatorUserPreferenceSettingsPanelController(
$request);
break;
case 'search':
$delegate = new PhabricatorUserSearchSettingsPanelController($request);
break;
case 'ldap':
$delegate = new PhabricatorUserLDAPSettingsPanelController($request);
break;
default:
$delegate = new PhabricatorUserOAuthSettingsPanelController($request);
$delegate->setOAuthProvider($oauth_providers[$this->page]);
break;
}
$response = $this->delegateToController($delegate);
if ($response instanceof AphrontView) { $panel = $panels[$key];
$sidenav->appendChild($response);
return $this->buildStandardPageResponse( $response = $panel->processRequest($request);
$sidenav, if ($response instanceof AphrontResponse) {
array(
'title' => 'Account Settings',
));
} else {
return $response; return $response;
} }
$nav->appendChild($response);
return $this->buildApplicationPage(
$nav,
array(
'title' => $panel->getPanelName(),
));
} }
private function renderSideNav($oauth_providers) { private function buildPanels() {
$sidenav = new AphrontSideNavFilterView(); $panel_specs = id(new PhutilSymbolLoader())
$sidenav ->setAncestorClass('PhabricatorSettingsPanel')
->setBaseURI(new PhutilURI('/settings/page/')) ->setConcreteOnly(true)
->addLabel('Account Information') ->selectAndLoadSymbols();
->addFilter('account', 'Account')
->addFilter('profile', 'Profile')
->addSpacer()
->addLabel('Email')
->addFilter('email', 'Email Addresses')
->addFilter('emailpref', 'Email Preferences')
->addSpacer()
->addLabel('Authentication');
if (PhabricatorEnv::getEnvConfig('account.editable') && $panels = array();
PhabricatorEnv::getEnvConfig('auth.password-auth-enabled')) { foreach ($panel_specs as $spec) {
$sidenav->addFilter('password', 'Password'); $class = newv($spec['name'], array());
$panels[] = $class->buildPanels();
} }
$sidenav->addFilter('conduit', 'Conduit Certificate'); $panels = array_mergev($panels);
$panels = mpull($panels, null, 'getPanelKey');
if (PhabricatorUserSSHKeysSettingsPanelController::isEnabled()) { $result = array();
$sidenav->addFilter('sshkeys', 'SSH Public Keys'); foreach ($panels as $key => $panel) {
} if (!$panel->isEnabled()) {
$sidenav->addSpacer();
$sidenav->addLabel('Application Settings');
$sidenav->addFilter('preferences', 'Display Preferences');
$sidenav->addFilter('search', 'Search Preferences');
$items = array();
foreach ($oauth_providers as $provider) {
if (!$provider->isProviderEnabled()) {
continue; continue;
} }
$key = $provider->getProviderKey(); if (!empty($result[$key])) {
$name = $provider->getProviderName(); throw new Exception(
$items[$key] = $name.' Account'; "Two settings panels share the same panel key ('{$key}'): ".
get_class($panel).', '.get_class($result[$key]).'.');
}
$result[$key] = $panel;
} }
$ldap_provider = new PhabricatorLDAPProvider(); $result = msort($result, 'getPanelSortKey');
if ($ldap_provider->isProviderEnabled()) {
$items['ldap'] = 'LDAP Account'; return $result;
} }
if ($items) { private function renderSideNav(array $panels) {
$sidenav->addSpacer(); $nav = new AphrontSideNavFilterView();
$sidenav->addLabel('Linked Accounts'); $nav->setBaseURI(new PhutilURI($this->getApplicationURI('/panel/')));
foreach ($items as $key => $name) {
$sidenav->addFilter($key, $name); $group = null;
foreach ($panels as $panel) {
if ($panel->getPanelGroup() != $group) {
if ($group !== null) {
$nav->addSpacer();
} }
$group = $panel->getPanelGroup();
$nav->addLabel($group);
} }
return $sidenav; $nav->addFilter($panel->getPanelKey(), $panel->getPanelName());
} }
return $nav;
}
} }

View file

@ -0,0 +1,156 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Defines a settings panel. Settings panels appear in the Settings application,
* and behave like lightweight controllers -- generally, they render some sort
* of form with options in it, and then update preferences when the user
* submits the form. By extending this class, you can add new settings
* panels.
*
* NOTE: This stuff is new and might not be completely stable.
*
* @task config Panel Configuration
* @task panel Panel Implementation
* @task internal Internals
*
* @group settings
*/
abstract class PhabricatorSettingsPanel {
/* -( Panel Configuration )------------------------------------------------ */
/**
* Return a unique string used in the URI to identify this panel, like
* "example".
*
* @return string Unique panel identifier (used in URIs).
* @task config
*/
abstract public function getPanelKey();
/**
* Return a human-readable description of the panel's contents, like
* "Example Settings".
*
* @return string Human-readable panel name.
* @task config
*/
abstract public function getPanelName();
/**
* Return a human-readable group name for this panel. For instance, if you
* had several related panels like "Volume Settings" and
* "Microphone Settings", you might put them in a group called "Audio".
*
* When displayed, panels are grouped with other panels that have the same
* group name.
*
* @return string Human-readable panel group name.
* @task config
*/
abstract public function getPanelGroup();
/**
* Return false to prevent this panel from being displayed or used. You can
* do, e.g., configuration checks here, to determine if the feature your
* panel controls is unavailble in this install. By default, all panels are
* enabled.
*
* @return bool True if the panel should be shown.
* @task config
*/
public function isEnabled() {
return true;
}
/**
* You can use this callback to generate multiple similar panels which all
* share the same implementation. For example, OAuth providers each have a
* separate panel, but the implementation for each panel is the same.
*
* To generate multiple panels, build them here and return a list. By default,
* the current panel (`$this`) is returned alone. For most panels, this
* is the right implementation.
*
* @return list<PhabricatorSettingsPanel> Zero or more panels.
* @task config
*/
public function buildPanels() {
return array($this);
}
/* -( Panel Implementation )----------------------------------------------- */
/**
* Process a user request for this settings panel. Implement this method like
* a lightweight controller. If you return an @{class:AphrontResponse}, the
* response will be used in whole. If you return anything else, it will be
* treated as a view and composed into a normal settings page.
*
* Generally, render your settings panel by returning a form, then return
* a redirect when the user saves settings.
*
* @param AphrontRequest Incoming request.
* @return wild Response to request, either as an
* @{class:AphrontResponse} or something which can
* be composed into a @{class:AphrontView}.
* @task panel
*/
abstract public function processRequest(AphrontRequest $request);
/**
* Get the URI for this panel.
*
* @param string? Optional path to append.
* @return string Relative URI for the panel.
* @task panel
*/
final public function getPanelURI($path = '') {
$key = $this->getPanelKey();
$key = phutil_escape_uri($key);
return '/settings/panel/'.$key.'/'.ltrim($path, '/');
}
/* -( Internals )---------------------------------------------------------- */
/**
* Generates a key to sort the list of panels.
*
* @return string Sortable key.
* @task internal
*/
final public function getPanelSortKey() {
return sprintf(
'%s'.chr(255).'%s',
$this->getPanelGroup(),
$this->getPanelName());
}
}

View file

@ -16,14 +16,24 @@
* limitations under the License. * limitations under the License.
*/ */
final class PhabricatorUserAccountSettingsPanelController final class PhabricatorSettingsPanelAccount
extends PhabricatorUserSettingsPanelController { extends PhabricatorSettingsPanel {
public function processRequest() { public function getPanelKey() {
return 'account';
}
$request = $this->getRequest(); public function getPanelName() {
return pht('Account');
}
public function getPanelGroup() {
return pht('Account Information');
}
public function processRequest(AphrontRequest $request) {
$user = $request->getUser(); $user = $request->getUser();
$editable = $this->getAccountEditable(); $editable = PhabricatorEnv::getEnvConfig('account.editable');
$e_realname = $editable ? true : null; $e_realname = $editable ? true : null;
$errors = array(); $errors = array();
@ -47,7 +57,7 @@ final class PhabricatorUserAccountSettingsPanelController
if (!$errors) { if (!$errors) {
$user->save(); $user->save();
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())
->setURI('/settings/page/account/?saved=true'); ->setURI($this->getPanelURI('?saved=true'));
} }
} }
@ -73,7 +83,6 @@ final class PhabricatorUserAccountSettingsPanelController
$form = new AphrontFormView(); $form = new AphrontFormView();
$form $form
->setUser($user) ->setUser($user)
->setEncType('multipart/form-data')
->appendChild( ->appendChild(
id(new AphrontFormStaticControl()) id(new AphrontFormStaticControl())
->setLabel('Username') ->setLabel('Username')
@ -100,11 +109,9 @@ final class PhabricatorUserAccountSettingsPanelController
$panel->setWidth(AphrontPanelView::WIDTH_FORM); $panel->setWidth(AphrontPanelView::WIDTH_FORM);
$panel->appendChild($form); $panel->appendChild($form);
return id(new AphrontNullView()) return array(
->appendChild(
array(
$notice, $notice,
$panel, $panel,
)); );
} }
} }

View file

@ -16,12 +16,22 @@
* limitations under the License. * limitations under the License.
*/ */
final class PhabricatorUserConduitSettingsPanelController final class PhabricatorSettingsPanelConduit
extends PhabricatorUserSettingsPanelController { extends PhabricatorSettingsPanel {
public function processRequest() { public function getPanelKey() {
return 'conduit';
}
$request = $this->getRequest(); public function getPanelName() {
return pht('Conduit');
}
public function getPanelGroup() {
return pht('Authentication');
}
public function processRequest(AphrontRequest $request) {
$user = $request->getUser(); $user = $request->getUser();
if ($request->isFormPost()) { if ($request->isFormPost()) {
@ -29,9 +39,9 @@ final class PhabricatorUserConduitSettingsPanelController
$dialog = new AphrontDialogView(); $dialog = new AphrontDialogView();
$dialog->setUser($user); $dialog->setUser($user);
$dialog->setTitle('Really regenerate session?'); $dialog->setTitle('Really regenerate session?');
$dialog->setSubmitURI('/settings/page/conduit/'); $dialog->setSubmitURI($this->getPanelURI());
$dialog->addSubmitButton('Regenerate'); $dialog->addSubmitButton('Regenerate');
$dialog->addCancelbutton('/settings/page/conduit/'); $dialog->addCancelbutton($this->getPanelURI());
$dialog->appendChild( $dialog->appendChild(
'<p>Really destroy the old certificate? Any established '. '<p>Really destroy the old certificate? Any established '.
'sessions will be terminated.'); 'sessions will be terminated.');
@ -52,7 +62,7 @@ final class PhabricatorUserConduitSettingsPanelController
$user->setConduitCertificate(null); $user->setConduitCertificate(null);
$user->save(); $user->save();
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())
->setURI('/settings/page/conduit/?regenerated=true'); ->setURI($this->getPanelURI('?regenerated=true'));
} }
if ($request->getStr('regenerated')) { if ($request->getStr('regenerated')) {
@ -89,7 +99,8 @@ final class PhabricatorUserConduitSettingsPanelController
$regen_form = new AphrontFormView(); $regen_form = new AphrontFormView();
$regen_form $regen_form
->setUser($user) ->setUser($user)
->setAction('/settings/page/conduit/') ->setAction($this->getPanelURI())
->setWorkflow(true)
->appendChild( ->appendChild(
'<p class="aphront-form-instructions">You can regenerate this '. '<p class="aphront-form-instructions">You can regenerate this '.
'certificate, which will invalidate the old certificate and create '. 'certificate, which will invalidate the old certificate and create '.
@ -103,12 +114,10 @@ final class PhabricatorUserConduitSettingsPanelController
$regen->appendChild($regen_form); $regen->appendChild($regen_form);
$regen->setWidth(AphrontPanelView::WIDTH_FORM); $regen->setWidth(AphrontPanelView::WIDTH_FORM);
return id(new AphrontNullView()) return array(
->appendChild(
array(
$notice, $notice,
$cert, $cert,
$regen, $regen,
)); );
} }
} }

View file

@ -16,12 +16,22 @@
* limitations under the License. * limitations under the License.
*/ */
final class PhabricatorUserPreferenceSettingsPanelController final class PhabricatorSettingsPanelDisplayPreferences
extends PhabricatorUserSettingsPanelController { extends PhabricatorSettingsPanel {
public function processRequest() { public function getPanelKey() {
return 'display';
}
$request = $this->getRequest(); public function getPanelName() {
return pht('Display Preferences');
}
public function getPanelGroup() {
return pht('Application Settings');
}
public function processRequest(AphrontRequest $request) {
$user = $request->getUser(); $user = $request->getUser();
$preferences = $user->loadPreferences(); $preferences = $user->loadPreferences();
@ -44,7 +54,7 @@ final class PhabricatorUserPreferenceSettingsPanelController
$preferences->save(); $preferences->save();
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())
->setURI('/settings/page/preferences/?saved=true'); ->setURI($this->getPanelURI('?saved=true'));
} }
$example_string = <<<EXAMPLE $example_string = <<<EXAMPLE
@ -67,7 +77,6 @@ EXAMPLE;
$form = id(new AphrontFormView()) $form = id(new AphrontFormView())
->setUser($user) ->setUser($user)
->setAction('/settings/page/preferences/')
->appendChild( ->appendChild(
id(new AphrontFormSelectControl()) id(new AphrontFormSelectControl())
->setLabel('Page Titles') ->setLabel('Page Titles')
@ -95,7 +104,7 @@ EXAMPLE;
->setLabel('Monospaced Font') ->setLabel('Monospaced Font')
->setName($pref_monospaced) ->setName($pref_monospaced)
->setCaption( ->setCaption(
'Overrides default fonts in tools like Differential. '. 'Overrides default fonts in tools like Differential.<br />'.
'(Default: '.$font_default.')') '(Default: '.$font_default.')')
->setValue($preferences->getPreference($pref_monospaced))) ->setValue($preferences->getPreference($pref_monospaced)))
->appendChild( ->appendChild(
@ -130,12 +139,10 @@ EXAMPLE;
->setErrors(array('Your preferences have been saved.')); ->setErrors(array('Your preferences have been saved.'));
} }
return id(new AphrontNullView()) return array(
->appendChild(
array(
$error_view, $error_view,
$panel, $panel,
)); );
} }
} }

View file

@ -16,14 +16,24 @@
* limitations under the License. * limitations under the License.
*/ */
final class PhabricatorUserEmailSettingsPanelController final class PhabricatorSettingsPanelEmailAddresses
extends PhabricatorUserSettingsPanelController { extends PhabricatorSettingsPanel {
public function processRequest() { public function getPanelKey() {
return 'email';
}
$request = $this->getRequest(); public function getPanelName() {
return pht('Email Addresses');
}
public function getPanelGroup() {
return pht('Email');
}
public function processRequest(AphrontRequest $request) {
$user = $request->getUser(); $user = $request->getUser();
$editable = $this->getAccountEditable(); $editable = PhabricatorEnv::getEnvConfig('account.editable');
$uri = $request->getRequestURI(); $uri = $request->getRequestURI();
$uri->setQueryParams(array()); $uri->setQueryParams(array());
@ -31,23 +41,23 @@ final class PhabricatorUserEmailSettingsPanelController
if ($editable) { if ($editable) {
$new = $request->getStr('new'); $new = $request->getStr('new');
if ($new) { if ($new) {
return $this->returnNewAddressResponse($uri, $new); return $this->returnNewAddressResponse($request, $uri, $new);
} }
$delete = $request->getInt('delete'); $delete = $request->getInt('delete');
if ($delete) { if ($delete) {
return $this->returnDeleteAddressResponse($uri, $delete); return $this->returnDeleteAddressResponse($request, $uri, $delete);
} }
} }
$verify = $request->getInt('verify'); $verify = $request->getInt('verify');
if ($verify) { if ($verify) {
return $this->returnVerifyAddressResponse($uri, $verify); return $this->returnVerifyAddressResponse($request, $uri, $verify);
} }
$primary = $request->getInt('primary'); $primary = $request->getInt('primary');
if ($primary) { if ($primary) {
return $this->returnPrimaryAddressResponse($uri, $primary); return $this->returnPrimaryAddressResponse($request, $uri, $primary);
} }
$emails = id(new PhabricatorUserEmail())->loadAllWhere( $emails = id(new PhabricatorUserEmail())->loadAllWhere(
@ -154,8 +164,11 @@ final class PhabricatorUserEmailSettingsPanelController
return $view; return $view;
} }
private function returnNewAddressResponse(PhutilURI $uri, $new) { private function returnNewAddressResponse(
$request = $this->getRequest(); AphrontRequest $request,
PhutilURI $uri,
$new) {
$user = $request->getUser(); $user = $request->getUser();
$e_email = true; $e_email = true;
@ -234,8 +247,11 @@ final class PhabricatorUserEmailSettingsPanelController
return id(new AphrontDialogResponse())->setDialog($dialog); return id(new AphrontDialogResponse())->setDialog($dialog);
} }
private function returnDeleteAddressResponse(PhutilURI $uri, $email_id) { private function returnDeleteAddressResponse(
$request = $this->getRequest(); AphrontRequest $request,
PhutilURI $uri,
$email_id) {
$user = $request->getUser(); $user = $request->getUser();
// NOTE: You can only delete your own email addresses, and you can not // NOTE: You can only delete your own email addresses, and you can not
@ -273,8 +289,11 @@ final class PhabricatorUserEmailSettingsPanelController
return id(new AphrontDialogResponse())->setDialog($dialog); return id(new AphrontDialogResponse())->setDialog($dialog);
} }
private function returnVerifyAddressResponse(PhutilURI $uri, $email_id) { private function returnVerifyAddressResponse(
$request = $this->getRequest(); AphrontRequest $request,
PhutilURI $uri,
$email_id) {
$user = $request->getUser(); $user = $request->getUser();
// NOTE: You can only send more email for your unverified addresses. // NOTE: You can only send more email for your unverified addresses.
@ -307,8 +326,11 @@ final class PhabricatorUserEmailSettingsPanelController
return id(new AphrontDialogResponse())->setDialog($dialog); return id(new AphrontDialogResponse())->setDialog($dialog);
} }
private function returnPrimaryAddressResponse(PhutilURI $uri, $email_id) { private function returnPrimaryAddressResponse(
$request = $this->getRequest(); AphrontRequest $request,
PhutilURI $uri,
$email_id) {
$user = $request->getUser(); $user = $request->getUser();
// NOTE: You can only make your own verified addresses primary. // NOTE: You can only make your own verified addresses primary.

View file

@ -16,11 +16,22 @@
* limitations under the License. * limitations under the License.
*/ */
final class PhabricatorUserEmailPreferenceSettingsPanelController final class PhabricatorSettingsPanelEmailPreferences
extends PhabricatorUserSettingsPanelController { extends PhabricatorSettingsPanel {
public function processRequest() { public function getPanelKey() {
$request = $this->getRequest(); return 'emailpreferences';
}
public function getPanelName() {
return pht('Email Preferences');
}
public function getPanelGroup() {
return pht('Email');
}
public function processRequest(AphrontRequest $request) {
$user = $request->getUser(); $user = $request->getUser();
$preferences = $user->loadPreferences(); $preferences = $user->loadPreferences();
@ -64,7 +75,7 @@ final class PhabricatorUserEmailPreferenceSettingsPanelController
$preferences->save(); $preferences->save();
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())
->setURI('/settings/page/emailpref/?saved=true'); ->setURI($this->getPanelURI('?saved=true'));
} }
$notice = null; $notice = null;

View file

@ -16,11 +16,27 @@
* limitations under the License. * limitations under the License.
*/ */
final class PhabricatorUserLDAPSettingsPanelController final class PhabricatorSettingsPanelLDAP
extends PhabricatorUserSettingsPanelController { extends PhabricatorSettingsPanel {
public function processRequest() { public function getPanelKey() {
$request = $this->getRequest(); return 'ldap';
}
public function getPanelName() {
return pht('LDAP');
}
public function getPanelGroup() {
return pht('Linked Accounts');
}
public function isEnabled() {
$ldap_provider = new PhabricatorLDAPProvider();
return $ldap_provider->isProviderEnabled();
}
public function processRequest(AphrontRequest $request) {
$user = $request->getUser(); $user = $request->getUser();
$ldap_info = id(new PhabricatorUserLDAPInfo())->loadOneWhere( $ldap_info = id(new PhabricatorUserLDAPInfo())->loadOneWhere(
@ -78,10 +94,8 @@ final class PhabricatorUserLDAPSettingsPanelController
$panel->appendChild($form); $panel->appendChild($form);
} }
return id(new AphrontNullView()) return array(
->appendChild(
array(
$panel, $panel,
)); );
} }
} }

View file

@ -16,8 +16,37 @@
* limitations under the License. * limitations under the License.
*/ */
final class PhabricatorUserOAuthSettingsPanelController final class PhabricatorSettingsPanelOAuth
extends PhabricatorUserSettingsPanelController { extends PhabricatorSettingsPanel {
public function getPanelKey() {
return 'oauth-'.$this->provider->getProviderKey();
}
public function getPanelName() {
return $this->provider->getProviderName();
}
public function getPanelGroup() {
return pht('Linked Accounts');
}
public function buildPanels() {
$panels = array();
$providers = PhabricatorOAuthProvider::getAllProviders();
foreach ($providers as $provider) {
$panel = clone $this;
$panel->setOAuthProvider($provider);
$panels[] = $panel;
}
return $panels;
}
public function isEnabled() {
return $this->provider->isProviderEnabled();
}
private $provider; private $provider;
@ -48,8 +77,7 @@ final class PhabricatorUserOAuthSettingsPanelController
return $form; return $form;
} }
public function processRequest() { public function processRequest(AphrontRequest $request) {
$request = $this->getRequest();
$user = $request->getUser(); $user = $request->getUser();
$provider = $this->provider; $provider = $this->provider;
$notice = null; $notice = null;
@ -62,7 +90,7 @@ final class PhabricatorUserOAuthSettingsPanelController
$provider->getProviderKey()); $provider->getProviderKey());
if ($request->isFormPost() && $oauth_info) { if ($request->isFormPost() && $oauth_info) {
$notice = $this->refreshProfileImage($oauth_info); $notice = $this->refreshProfileImage($request, $oauth_info);
} }
$form = new AphrontFormView(); $form = new AphrontFormView();
@ -198,8 +226,11 @@ final class PhabricatorUserOAuthSettingsPanelController
)); ));
} }
private function refreshProfileImage(PhabricatorUserOAuthInfo $oauth_info) { private function refreshProfileImage(
$user = $this->getRequest()->getUser(); AphrontRequest $request,
PhabricatorUserOAuthInfo $oauth_info) {
$user = $request->getUser();
$provider = $this->provider; $provider = $this->provider;
$error = false; $error = false;
$userinfo_uri = new PhutilURI($provider->getUserInfoURI()); $userinfo_uri = new PhutilURI($provider->getUserInfoURI());

View file

@ -16,22 +16,41 @@
* limitations under the License. * limitations under the License.
*/ */
final class PhabricatorUserPasswordSettingsPanelController final class PhabricatorSettingsPanelPassword
extends PhabricatorUserSettingsPanelController { extends PhabricatorSettingsPanel {
public function processRequest() { public function getPanelKey() {
return 'password';
$request = $this->getRequest();
$user = $request->getUser();
$editable = $this->getAccountEditable();
// There's no sense in showing a change password panel if the user
// can't change their password
if (!$editable ||
!PhabricatorEnv::getEnvConfig('auth.password-auth-enabled')) {
return new Aphront400Response();
} }
public function getPanelName() {
return pht('Password');
}
public function getPanelGroup() {
return pht('Authentication');
}
public function isEnabled() {
// There's no sense in showing a change password panel if the user
// can't change their password...
if (!PhabricatorEnv::getEnvConfig('account.editable')) {
return false;
}
// ...or this install doesn't support password authentication at all.
if (!PhabricatorEnv::getEnvConfig('auth.password-auth-enabled')) {
return false;
}
return true;
}
public function processRequest(AphrontRequest $request) {
$user = $request->getUser();
$min_len = PhabricatorEnv::getEnvConfig('account.minimum-password-length'); $min_len = PhabricatorEnv::getEnvConfig('account.minimum-password-length');
$min_len = (int)$min_len; $min_len = (int)$min_len;
@ -98,7 +117,7 @@ final class PhabricatorUserPasswordSettingsPanelController
// after we update their account. // after we update their account.
$next = '/'; $next = '/';
} else { } else {
$next = '/settings/page/password/?saved=true'; $next = $this->getPanelURI('?saved=true');
} }
return id(new AphrontRedirectResponse())->setURI($next); return id(new AphrontRedirectResponse())->setURI($next);
@ -160,11 +179,9 @@ final class PhabricatorUserPasswordSettingsPanelController
$panel->setWidth(AphrontPanelView::WIDTH_FORM); $panel->setWidth(AphrontPanelView::WIDTH_FORM);
$panel->appendChild($form); $panel->appendChild($form);
return id(new AphrontNullView()) return array(
->appendChild(
array(
$notice, $notice,
$panel, $panel,
)); );
} }
} }

View file

@ -16,12 +16,22 @@
* limitations under the License. * limitations under the License.
*/ */
final class PhabricatorUserProfileSettingsPanelController final class PhabricatorSettingsPanelProfile
extends PhabricatorUserSettingsPanelController { extends PhabricatorSettingsPanel {
public function processRequest() { public function getPanelKey() {
return 'profile';
}
$request = $this->getRequest(); public function getPanelName() {
return pht('Profile');
}
public function getPanelGroup() {
return pht('Account Information');
}
public function processRequest(AphrontRequest $request) {
$user = $request->getUser(); $user = $request->getUser();
$profile = id(new PhabricatorUserProfile())->loadOneWhere( $profile = id(new PhabricatorUserProfile())->loadOneWhere(
@ -95,7 +105,7 @@ final class PhabricatorUserProfileSettingsPanelController
$user->save(); $user->save();
$profile->save(); $profile->save();
$response = id(new AphrontRedirectResponse()) $response = id(new AphrontRedirectResponse())
->setURI('/settings/page/profile/?saved=true'); ->setURI($this->getPanelURI('?saved=true'));
return $response; return $response;
} }
} }
@ -143,7 +153,6 @@ final class PhabricatorUserProfileSettingsPanelController
$form = new AphrontFormView(); $form = new AphrontFormView();
$form $form
->setUser($request->getUser()) ->setUser($request->getUser())
->setAction('/settings/page/profile/')
->setEncType('multipart/form-data') ->setEncType('multipart/form-data')
->appendChild( ->appendChild(
id(new AphrontFormTextControl()) id(new AphrontFormTextControl())
@ -176,7 +185,7 @@ final class PhabricatorUserProfileSettingsPanelController
->appendChild( ->appendChild(
'<p class="aphront-form-instructions">Write something about yourself! '. '<p class="aphront-form-instructions">Write something about yourself! '.
'Make sure to include <strong>important information</strong> like '. 'Make sure to include <strong>important information</strong> like '.
'your favorite pokemon and which Starcraft race you play.</p>') 'your favorite Pokemon and which Starcraft race you play.</p>')
->appendChild( ->appendChild(
id(new AphrontFormTextAreaControl()) id(new AphrontFormTextAreaControl())
->setLabel('Blurb') ->setLabel('Blurb')
@ -207,12 +216,10 @@ final class PhabricatorUserProfileSettingsPanelController
$panel->appendChild($form); $panel->appendChild($form);
$panel->setWidth(AphrontPanelView::WIDTH_FORM); $panel->setWidth(AphrontPanelView::WIDTH_FORM);
return id(new AphrontNullView()) return array(
->appendChild(
array(
$error_view, $error_view,
$panel, $panel,
)); );
} }
} }

View file

@ -16,24 +16,33 @@
* limitations under the License. * limitations under the License.
*/ */
final class PhabricatorUserSSHKeysSettingsPanelController final class PhabricatorSettingsPanelSSHKeys
extends PhabricatorUserSettingsPanelController { extends PhabricatorSettingsPanel {
const PANEL_BASE_URI = '/settings/page/sshkeys/'; public function getPanelKey() {
return 'ssh';
}
public static function isEnabled() { public function getPanelName() {
return pht('SSH Public Keys');
}
public function getPanelGroup() {
return pht('Authentication');
}
public function isEnabled() {
return PhabricatorEnv::getEnvConfig('auth.sshkeys.enabled'); return PhabricatorEnv::getEnvConfig('auth.sshkeys.enabled');
} }
public function processRequest() { public function processRequest(AphrontRequest $request) {
$request = $this->getRequest();
$user = $request->getUser(); $user = $request->getUser();
$edit = $request->getStr('edit'); $edit = $request->getStr('edit');
$delete = $request->getStr('delete'); $delete = $request->getStr('delete');
if (!$edit && !$delete) { if (!$edit && !$delete) {
return $this->renderKeyListView(); return $this->renderKeyListView($request);
} }
$id = nonempty($edit, $delete); $id = nonempty($edit, $delete);
@ -43,7 +52,7 @@ final class PhabricatorUserSSHKeysSettingsPanelController
$key = id(new PhabricatorUserSSHKey())->loadOneWhere( $key = id(new PhabricatorUserSSHKey())->loadOneWhere(
'userPHID = %s AND id = %d', 'userPHID = %s AND id = %d',
$user->getPHID(), $user->getPHID(),
$id); (int)$id);
if (!$key) { if (!$key) {
return new Aphront404Response(); return new Aphront404Response();
} }
@ -53,7 +62,7 @@ final class PhabricatorUserSSHKeysSettingsPanelController
} }
if ($delete) { if ($delete) {
return $this->processDelete($key); return $this->processDelete($request, $key);
} }
$e_name = true; $e_name = true;
@ -113,7 +122,7 @@ final class PhabricatorUserSSHKeysSettingsPanelController
try { try {
$key->save(); $key->save();
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())
->setURI(self::PANEL_BASE_URI); ->setURI($this->getPanelURI());
} catch (AphrontQueryDuplicateKeyException $ex) { } catch (AphrontQueryDuplicateKeyException $ex) {
$e_key = 'Duplicate'; $e_key = 'Duplicate';
$errors[] = 'This public key is already associated with a user '. $errors[] = 'This public key is already associated with a user '.
@ -156,7 +165,7 @@ final class PhabricatorUserSSHKeysSettingsPanelController
->setError($e_key)) ->setError($e_key))
->appendChild( ->appendChild(
id(new AphrontFormSubmitControl()) id(new AphrontFormSubmitControl())
->addCancelButton(self::PANEL_BASE_URI) ->addCancelButton($this->getPanelURI())
->setValue($save)); ->setValue($save));
$panel = new AphrontPanelView(); $panel = new AphrontPanelView();
@ -172,8 +181,8 @@ final class PhabricatorUserSSHKeysSettingsPanelController
)); ));
} }
private function renderKeyListView() { private function renderKeyListView(AphrontRequest $request) {
$request = $this->getRequest();
$user = $request->getUser(); $user = $request->getUser();
$keys = id(new PhabricatorUserSSHKey())->loadAllWhere( $keys = id(new PhabricatorUserSSHKey())->loadAllWhere(
@ -186,7 +195,7 @@ final class PhabricatorUserSSHKeysSettingsPanelController
phutil_render_tag( phutil_render_tag(
'a', 'a',
array( array(
'href' => '/settings/page/sshkeys/?edit='.$key->getID(), 'href' => $this->getPanelURI('?edit='.$key->getID()),
), ),
phutil_escape_html($key->getName())), phutil_escape_html($key->getName())),
phutil_escape_html($key->getKeyComment()), phutil_escape_html($key->getKeyComment()),
@ -196,7 +205,7 @@ final class PhabricatorUserSSHKeysSettingsPanelController
javelin_render_tag( javelin_render_tag(
'a', 'a',
array( array(
'href' => '/settings/page/sshkeys/?delete='.$key->getID(), 'href' => $this->getPanelURI('?delete='.$key->getID()),
'class' => 'small grey button', 'class' => 'small grey button',
'sigil' => 'workflow', 'sigil' => 'workflow',
), ),
@ -230,7 +239,7 @@ final class PhabricatorUserSSHKeysSettingsPanelController
phutil_render_tag( phutil_render_tag(
'a', 'a',
array( array(
'href' => '/settings/page/sshkeys/?edit=true', 'href' => $this->getPanelURI('?edit=true'),
'class' => 'green button', 'class' => 'green button',
), ),
'Add New Public Key')); 'Add New Public Key'));
@ -240,8 +249,10 @@ final class PhabricatorUserSSHKeysSettingsPanelController
return $panel; return $panel;
} }
private function processDelete(PhabricatorUserSSHKey $key) { private function processDelete(
$request = $this->getRequest(); AphrontRequest $request,
PhabricatorUserSSHKey $key) {
$user = $request->getUser(); $user = $request->getUser();
$name = phutil_escape_html($key->getName()); $name = phutil_escape_html($key->getName());
@ -249,7 +260,7 @@ final class PhabricatorUserSSHKeysSettingsPanelController
if ($request->isDialogFormPost()) { if ($request->isDialogFormPost()) {
$key->delete(); $key->delete();
return id(new AphrontReloadResponse()) return id(new AphrontReloadResponse())
->setURI(self::PANEL_BASE_URI); ->setURI($this->getPanelURI());
} }
$dialog = id(new AphrontDialogView()) $dialog = id(new AphrontDialogView())
@ -261,7 +272,7 @@ final class PhabricatorUserSSHKeysSettingsPanelController
'and you will not longer be able to use the corresponding private key '. 'and you will not longer be able to use the corresponding private key '.
'to authenticate.</p>') 'to authenticate.</p>')
->addSubmitButton('Delete Public Key') ->addSubmitButton('Delete Public Key')
->addCancelButton(self::PANEL_BASE_URI); ->addCancelButton($this->getPanelURI());
return id(new AphrontDialogResponse()) return id(new AphrontDialogResponse())
->setDialog($dialog); ->setDialog($dialog);

View file

@ -16,12 +16,22 @@
* limitations under the License. * limitations under the License.
*/ */
final class PhabricatorUserSearchSettingsPanelController final class PhabricatorSettingsPanelSearchPreferences
extends PhabricatorUserSettingsPanelController { extends PhabricatorSettingsPanel {
public function processRequest() { public function getPanelKey() {
return 'search';
}
$request = $this->getRequest(); public function getPanelName() {
return pht('Search Preferences');
}
public function getPanelGroup() {
return pht('Application Settings');
}
public function processRequest(AphrontRequest $request) {
$user = $request->getUser(); $user = $request->getUser();
$preferences = $user->loadPreferences(); $preferences = $user->loadPreferences();
@ -37,12 +47,11 @@ final class PhabricatorUserSearchSettingsPanelController
$preferences->save(); $preferences->save();
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())
->setURI('/settings/page/search/?saved=true'); ->setURI($this->getPanelURI('?saved=true'));
} }
$form = id(new AphrontFormView()) $form = id(new AphrontFormView())
->setUser($user) ->setUser($user)
->setAction('/settings/page/search/')
->appendChild( ->appendChild(
id(new AphrontFormCheckboxControl()) id(new AphrontFormCheckboxControl())
->addCheckbox($pref_jump, ->addCheckbox($pref_jump,
@ -51,7 +60,7 @@ final class PhabricatorUserSearchSettingsPanelController
$preferences->getPreference($pref_jump, 1)) $preferences->getPreference($pref_jump, 1))
->addCheckbox($pref_shortcut, ->addCheckbox($pref_shortcut,
1, 1,
'\'/\' focuses search box.', "Press '/' to focus the search input.",
$preferences->getPreference($pref_shortcut, 1)) $preferences->getPreference($pref_shortcut, 1))
) )
->appendChild( ->appendChild(
@ -71,12 +80,10 @@ final class PhabricatorUserSearchSettingsPanelController
->setErrors(array('Your preferences have been saved.')); ->setErrors(array('Your preferences have been saved.'));
} }
return id(new AphrontNullView()) return array(
->appendChild(
array(
$error_view, $error_view,
$panel, $panel,
)); );
} }
} }

View file

@ -1,26 +0,0 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
abstract class PhabricatorUserSettingsPanelController
extends PhabricatorPeopleController {
public function getAccountEditable() {
return PhabricatorEnv::getEnvConfig('account.editable');
}
}