1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-09 16:32:39 +01:00

Allow administrators to configure global default settings

Summary:
Ref T4103. This just adds a single global default setting group, not full profiles.

Primarily, I'm not sure how administrators are supposed to set profiles for users, since most ways user accounts get created don't really support setting roles.. When we figure that out, it should be reasonably easy to extend this. There also isn't much of a need for this now, since pretty much everyone just wants to turn off mail.

Test Plan:
  - Edited personal settings.
  - Edited global settings.
  - Edited a bot's settings.
  - Tried to edit some other user's settings.
  - Saw defaults change appropriately as I edited global and personal settings.

{F1677266}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T4103

Differential Revision: https://secure.phabricator.com/D16048
This commit is contained in:
epriestley 2016-06-05 12:38:04 -07:00
parent c9ef7aeaa3
commit 421bf2e548
33 changed files with 464 additions and 96 deletions

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_user.user_preferences
CHANGE userPHID userPHID VARBINARY(64);

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_user.user_preferences
ADD builtinKey VARCHAR(32) COLLATE {$COLLATE_TEXT};

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_user.user_preferences
ADD UNIQUE KEY `key_builtin` (builtinKey);

View file

@ -3393,6 +3393,7 @@ phutil_register_library_map(array(
'PhabricatorSettingsDeveloperPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsDeveloperPanelGroup.php',
'PhabricatorSettingsEditEngine' => 'applications/settings/editor/PhabricatorSettingsEditEngine.php',
'PhabricatorSettingsEmailPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsEmailPanelGroup.php',
'PhabricatorSettingsListController' => 'applications/settings/controller/PhabricatorSettingsListController.php',
'PhabricatorSettingsLogsPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsLogsPanelGroup.php',
'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php',
'PhabricatorSettingsMainMenuBarExtension' => 'applications/settings/extension/PhabricatorSettingsMainMenuBarExtension.php',
@ -3650,6 +3651,7 @@ phutil_register_library_map(array(
'PhabricatorUserPreferencesEditor' => 'applications/settings/editor/PhabricatorUserPreferencesEditor.php',
'PhabricatorUserPreferencesPHIDType' => 'applications/settings/phid/PhabricatorUserPreferencesPHIDType.php',
'PhabricatorUserPreferencesQuery' => 'applications/settings/query/PhabricatorUserPreferencesQuery.php',
'PhabricatorUserPreferencesSearchEngine' => 'applications/settings/query/PhabricatorUserPreferencesSearchEngine.php',
'PhabricatorUserPreferencesTransaction' => 'applications/settings/storage/PhabricatorUserPreferencesTransaction.php',
'PhabricatorUserPreferencesTransactionQuery' => 'applications/settings/query/PhabricatorUserPreferencesTransactionQuery.php',
'PhabricatorUserProfile' => 'applications/people/storage/PhabricatorUserProfile.php',
@ -8170,6 +8172,7 @@ phutil_register_library_map(array(
'PhabricatorSettingsDeveloperPanelGroup' => 'PhabricatorSettingsPanelGroup',
'PhabricatorSettingsEditEngine' => 'PhabricatorEditEngine',
'PhabricatorSettingsEmailPanelGroup' => 'PhabricatorSettingsPanelGroup',
'PhabricatorSettingsListController' => 'PhabricatorController',
'PhabricatorSettingsLogsPanelGroup' => 'PhabricatorSettingsPanelGroup',
'PhabricatorSettingsMainController' => 'PhabricatorController',
'PhabricatorSettingsMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
@ -8470,6 +8473,7 @@ phutil_register_library_map(array(
'PhabricatorUserPreferencesEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorUserPreferencesPHIDType' => 'PhabricatorPHIDType',
'PhabricatorUserPreferencesQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorUserPreferencesSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorUserPreferencesTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorUserPreferencesTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorUserProfile' => 'PhabricatorUserDAO',

View file

@ -3,7 +3,11 @@
final class PhabricatorConduitTokensSettingsPanel
extends PhabricatorSettingsPanel {
public function isEditableByAdministrators() {
public function isManagementPanel() {
if ($this->getUser()->getIsMailingList()) {
return false;
}
return true;
}
@ -20,10 +24,6 @@ final class PhabricatorConduitTokensSettingsPanel
}
public function isEnabled() {
if ($this->getUser()->getIsMailingList()) {
return false;
}
return true;
}

View file

@ -2,7 +2,11 @@
final class DiffusionSetPasswordSettingsPanel extends PhabricatorSettingsPanel {
public function isEditableByAdministrators() {
public function isManagementPanel() {
if ($this->getUser()->getIsMailingList()) {
return false;
}
return true;
}
@ -19,10 +23,6 @@ final class DiffusionSetPasswordSettingsPanel extends PhabricatorSettingsPanel {
}
public function isEnabled() {
if ($this->getUser()->getIsMailingList()) {
return false;
}
return PhabricatorEnv::getEnvConfig('diffusion.allow-http-auth');
}

View file

@ -24,14 +24,34 @@ final class PhabricatorUserPreferencesCacheType
public function newValueForUsers($key, array $users) {
$viewer = $this->getViewer();
$user_phids = mpull($users, 'getPHID');
$users = mpull($users, null, 'getPHID');
$user_phids = array_keys($users);
$preferences = id(new PhabricatorUserPreferencesQuery())
->setViewer($viewer)
->withUserPHIDs($user_phids)
->execute();
$settings = mpull($preferences, 'getPreferences', 'getUserPHID');
$all_settings = PhabricatorSetting::getAllSettings();
$settings = array();
foreach ($preferences as $preference) {
$user_phid = $preference->getUserPHID();
foreach ($all_settings as $key => $setting) {
$value = $preference->getSettingValue($key);
// As an optimization, we omit the value from the cache if it is
// exactly the same as the hardcoded default.
$default_value = id(clone $setting)
->setViewer($users[$user_phid])
->getSettingDefaultValue();
if ($value === $default_value) {
continue;
}
$settings[$user_phid][$key] = $value;
}
}
$results = array();
foreach ($user_phids as $user_phid) {

View file

@ -124,7 +124,7 @@ final class PhabricatorPeopleProfileManageController
->setName(pht('Edit Settings'))
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit)
->setHref('/settings/'.$user->getID().'/'));
->setHref('/settings/user/'.$user->getUsername().'/'));
if ($user->getIsAdmin()) {
$empower_icon = 'fa-arrow-circle-o-down';

View file

@ -27,12 +27,14 @@ final class PhabricatorSettingsApplication extends PhabricatorApplication {
}
public function getRoutes() {
$panel_pattern = '(?:page/(?P<pageKey>[^/]+)/(?:(?P<formSaved>saved)/)?)?';
return array(
'/settings/' => array(
'(?:(?P<id>\d+)/)?'.
'(?:panel/(?P<pageKey>(?P<key>[^/]+))/'.
'(?:(?P<formSaved>saved)/)?'.
')?'
$this->getQueryRoutePattern() => 'PhabricatorSettingsListController',
'user/(?P<username>[^/]+)/'.$panel_pattern
=> 'PhabricatorSettingsMainController',
'builtin/(?P<builtin>global)/'.$panel_pattern
=> 'PhabricatorSettingsMainController',
'adjust/' => 'PhabricatorSettingsAdjustController',
'timezone/(?P<offset>[^/]+)/'

View file

@ -0,0 +1,48 @@
<?php
final class PhabricatorSettingsListController
extends PhabricatorController {
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
// If the viewer isn't an administrator, just redirect them to their own
// settings panel.
if (!$viewer->getIsAdmin()) {
$settings_uri = '/user/'.$viewer->getUsername().'/';
$settings_uri = $this->getApplicationURI($settings_uri);
return id(new AphrontRedirectResponse())
->setURI($settings_uri);
}
return id(new PhabricatorUserPreferencesSearchEngine())
->setController($this)
->buildResponse();
}
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$viewer = $this->getViewer();
if ($viewer->getIsAdmin()) {
$builtin_global = PhabricatorUserPreferences::BUILTIN_GLOBAL_DEFAULT;
$global_settings = id(new PhabricatorUserPreferencesQuery())
->setViewer($viewer)
->withBuiltinKeys(
array(
$builtin_global,
))
->execute();
if (!$global_settings) {
$action = id(new PHUIListItemView())
->setName(pht('Create Global Defaults'))
->setHref('/settings/builtin/'.$builtin_global.'/')
->setIcon('fa-plus');
$crumbs->addAction($action);
}
}
return $crumbs;
}
}

View file

@ -4,6 +4,8 @@ final class PhabricatorSettingsMainController
extends PhabricatorController {
private $user;
private $builtinKey;
private $preferences;
private function getUser() {
return $this->user;
@ -21,15 +23,39 @@ final class PhabricatorSettingsMainController
return ($viewer_phid == $user_phid);
}
private function isTemplate() {
return ($this->builtinKey !== null);
}
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$id = $request->getURIData('id');
$key = $request->getURIData('key');
if ($id) {
$username = $request->getURIData('username');
$builtin = $request->getURIData('builtin');
$key = $request->getURIData('pageKey');
if ($builtin) {
$this->builtinKey = $builtin;
$preferences = id(new PhabricatorUserPreferencesQuery())
->setViewer($viewer)
->withBuiltinKeys(array($builtin))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$preferences) {
$preferences = id(new PhabricatorUserPreferences())
->attachUser(null)
->setBuiltinKey($builtin);
}
} else {
$user = id(new PhabricatorPeopleQuery())
->setViewer($viewer)
->withIDs(array($id))
->withUsernames(array($username))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
@ -41,19 +67,27 @@ final class PhabricatorSettingsMainController
return new Aphront404Response();
}
$preferences = PhabricatorUserPreferences::loadUserPreferences($user);
$this->user = $user;
} else {
$this->user = $viewer;
}
$panels = $this->buildPanels();
if (!$preferences) {
return new Aphront404Response();
}
PhabricatorPolicyFilter::requireCapability(
$viewer,
$preferences,
PhabricatorPolicyCapability::CAN_EDIT);
$this->preferences = $preferences;
$panels = $this->buildPanels($preferences);
$nav = $this->renderSideNav($panels);
$key = $nav->selectFilter($key, head($panels)->getPanelKey());
$panel = $panels[$key]
->setUser($this->getUser())
->setViewer($viewer)
->setController($this)
->setNavigation($nav);
@ -79,22 +113,30 @@ final class PhabricatorSettingsMainController
}
private function buildPanels() {
private function buildPanels(PhabricatorUserPreferences $preferences) {
$viewer = $this->getViewer();
$panels = PhabricatorSettingsPanel::getAllDisplayPanels();
$result = array();
foreach ($panels as $key => $panel) {
$panel
->setViewer($viewer)
->setUser($this->user);
->setPreferences($preferences)
->setViewer($viewer);
if ($this->user) {
$panel->setUser($this->user);
}
if (!$panel->isEnabled()) {
continue;
}
if (!$this->isSelf()) {
if (!$panel->isEditableByAdministrators()) {
if ($this->isTemplate()) {
if (!$panel->isTemplatePanel()) {
continue;
}
} else {
if (!$this->isSelf() && !$panel->isManagementPanel()) {
continue;
}
}
@ -120,10 +162,11 @@ final class PhabricatorSettingsMainController
private function renderSideNav(array $panels) {
$nav = new AphrontSideNavFilterView();
if ($this->isSelf()) {
$base_uri = 'panel/';
if ($this->isTemplate()) {
$base_uri = 'builtin/'.$this->builtinKey.'/page/';
} else {
$base_uri = $this->getUser()->getID().'/panel/';
$user = $this->getUser();
$base_uri = 'user/'.$user->getUsername().'/page/';
}
$nav->setBaseURI(new PhutilURI($this->getApplicationURI($base_uri)));
@ -143,8 +186,11 @@ final class PhabricatorSettingsMainController
}
public function buildApplicationMenu() {
$panels = $this->buildPanels();
return $this->renderSideNav($panels)->getMenu();
if ($this->preferences) {
$panels = $this->buildPanels($this->preferences);
return $this->renderSideNav($panels)->getMenu();
}
return parent::buildApplicationMenu();
}
protected function buildApplicationCrumbs() {

View file

@ -67,7 +67,15 @@ final class PhabricatorSettingsEditEngine
}
protected function getObjectEditShortText($object) {
return pht('Edit Settings');
if (!$object->getUser()) {
return pht('Global Defaults');
} else {
if ($this->getIsSelfEdit()) {
return pht('Personal Settings');
} else {
return pht('Account Settings');
}
}
}
protected function getObjectCreateShortText() {
@ -85,7 +93,7 @@ final class PhabricatorSettingsEditEngine
}
protected function getEditorURI() {
return '/settings/edit/';
throw new PhutilMethodNotImplementedException();
}
protected function getObjectCreateCancelURI($object) {
@ -93,15 +101,22 @@ final class PhabricatorSettingsEditEngine
}
protected function getObjectViewURI($object) {
// TODO: This isn't correct...
return '/settings/user/'.$this->getViewer()->getUsername().'/';
return $object->getEditURI();
}
protected function getCreateNewObjectPolicy() {
return PhabricatorPolicies::POLICY_ADMIN;
}
public function getEffectiveObjectEditDoneURI($object) {
return parent::getEffectiveObjectViewURI($object).'saved/';
}
public function getEffectiveObjectEditCancelURI($object) {
if (!$object->getUser()) {
return '/settings/';
}
if ($this->getIsSelfEdit()) {
return null;
}

View file

@ -13,7 +13,11 @@ final class PhabricatorAccountSettingsPanel
return PhabricatorSettingsAccountPanelGroup::PANELGROUPKEY;
}
public function isEditableByAdministrators() {
public function isManagementPanel() {
return true;
}
public function isTemplatePanel() {
return true;
}

View file

@ -2,10 +2,6 @@
final class PhabricatorActivitySettingsPanel extends PhabricatorSettingsPanel {
public function isEditableByAdministrators() {
return true;
}
public function getPanelKey() {
return 'activity';
}
@ -61,4 +57,8 @@ final class PhabricatorActivitySettingsPanel extends PhabricatorSettingsPanel {
return array($panel, $pager_box);
}
public function isManagementPanel() {
return true;
}
}

View file

@ -13,4 +13,8 @@ final class PhabricatorConpherencePreferencesSettingsPanel
return PhabricatorSettingsApplicationsPanelGroup::PANELGROUPKEY;
}
public function isTemplatePanel() {
return true;
}
}

View file

@ -13,7 +13,11 @@ final class PhabricatorDateTimeSettingsPanel
return PhabricatorSettingsAccountPanelGroup::PANELGROUPKEY;
}
public function isEditableByAdministrators() {
public function isManagementPanel() {
return true;
}
public function isTemplatePanel() {
return true;
}

View file

@ -27,7 +27,7 @@ final class PhabricatorDesktopNotificationsSettingsPanel
public function processRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$preferences = $this->loadTargetPreferences();
$preferences = $this->getPreferences();
$notifications_key = PhabricatorDesktopNotificationsSetting::SETTINGKEY;
$notifications_value = $preferences->getSettingValue($notifications_key);

View file

@ -13,4 +13,8 @@ final class PhabricatorDeveloperPreferencesSettingsPanel
return PhabricatorSettingsDeveloperPanelGroup::PANELGROUPKEY;
}
public function isTemplatePanel() {
return true;
}
}

View file

@ -13,4 +13,8 @@ final class PhabricatorDiffPreferencesSettingsPanel
return PhabricatorSettingsApplicationsPanelGroup::PANELGROUPKEY;
}
public function isTemplatePanel() {
return true;
}
}

View file

@ -13,4 +13,8 @@ final class PhabricatorDisplayPreferencesSettingsPanel
return PhabricatorSettingsApplicationsPanelGroup::PANELGROUPKEY;
}
public function isTemplatePanel() {
return true;
}
}

View file

@ -7,13 +7,13 @@ abstract class PhabricatorEditEngineSettingsPanel
$viewer = $this->getViewer();
$user = $this->getUser();
if ($user->getPHID() === $viewer->getPHID()) {
if ($user && ($user->getPHID() === $viewer->getPHID())) {
$is_self = true;
} else {
$is_self = false;
}
if ($user->getPHID()) {
if ($user && $user->getPHID()) {
$profile_uri = '/people/manage/'.$user->getID().'/';
} else {
$profile_uri = null;
@ -26,7 +26,7 @@ abstract class PhabricatorEditEngineSettingsPanel
->setIsSelfEdit($is_self)
->setProfileURI($profile_uri);
$preferences = $this->loadTargetPreferences();
$preferences = $this->getPreferences();
$engine->setTargetObject($preferences);
@ -47,7 +47,7 @@ abstract class PhabricatorEditEngineSettingsPanel
$key = $this->getPanelKey();
$label = $this->getPanelName();
$panel_uri = $this->getPanelURI().'saved/';
$panel_uri = $this->getPanelURI();
return id(new PhabricatorEditPage())
->setKey($key)

View file

@ -13,7 +13,7 @@ final class PhabricatorEmailDeliverySettingsPanel
return PhabricatorSettingsEmailPanelGroup::PANELGROUPKEY;
}
public function isEditableByAdministrators() {
public function isManagementPanel() {
if ($this->getUser()->getIsMailingList()) {
return true;
}
@ -21,4 +21,8 @@ final class PhabricatorEmailDeliverySettingsPanel
return false;
}
public function isTemplatePanel() {
return true;
}
}

View file

@ -13,7 +13,7 @@ final class PhabricatorEmailFormatSettingsPanel
return PhabricatorSettingsEmailPanelGroup::PANELGROUPKEY;
}
public function isEditableByAdministrators() {
public function isManagementPanel() {
if ($this->getUser()->getIsMailingList()) {
return true;
}
@ -21,4 +21,8 @@ final class PhabricatorEmailFormatSettingsPanel
return false;
}
public function isTemplatePanel() {
return true;
}
}

View file

@ -15,7 +15,7 @@ final class PhabricatorEmailPreferencesSettingsPanel
return PhabricatorSettingsEmailPanelGroup::PANELGROUPKEY;
}
public function isEditableByAdministrators() {
public function isManagementPanel() {
if ($this->getUser()->getIsMailingList()) {
return true;
}
@ -23,11 +23,15 @@ final class PhabricatorEmailPreferencesSettingsPanel
return false;
}
public function isTemplatePanel() {
return true;
}
public function processRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$user = $this->getUser();
$preferences = $this->loadTargetPreferences();
$preferences = $this->getPreferences();
$value_email = PhabricatorEmailTagsSetting::VALUE_EMAIL;
@ -137,7 +141,7 @@ final class PhabricatorEmailPreferencesSettingsPanel
return $form_box;
}
private function getAllEditorsWithTags(PhabricatorUser $user) {
private function getAllEditorsWithTags(PhabricatorUser $user = null) {
$editors = id(new PhutilClassMapQuery())
->setAncestorClass('PhabricatorApplicationTransactionEditor')
->setFilterMethod('getMailTagsMap')
@ -146,7 +150,7 @@ final class PhabricatorEmailPreferencesSettingsPanel
foreach ($editors as $key => $editor) {
// Remove editors for applications which are not installed.
$app = $editor->getEditorApplicationClass();
if ($app !== null) {
if ($app !== null && $user !== null) {
if (!PhabricatorApplication::isClassInstalledForViewer($app, $user)) {
unset($editors[$key]);
}

View file

@ -15,9 +15,13 @@ final class PhabricatorHomePreferencesSettingsPanel
return PhabricatorSettingsApplicationsPanelGroup::PANELGROUPKEY;
}
public function isTemplatePanel() {
return true;
}
public function processRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$preferences = $this->loadTargetPreferences();
$preferences = $this->getPreferences();
$pinned_key = PhabricatorPinnedApplicationsSetting::SETTINGKEY;
$pinned = $preferences->getSettingValue($pinned_key);

View file

@ -2,7 +2,11 @@
final class PhabricatorSSHKeysSettingsPanel extends PhabricatorSettingsPanel {
public function isEditableByAdministrators() {
public function isManagementPanel() {
if ($this->getUser()->getIsMailingList()) {
return false;
}
return true;
}
@ -18,14 +22,6 @@ final class PhabricatorSSHKeysSettingsPanel extends PhabricatorSettingsPanel {
return PhabricatorSettingsAuthenticationPanelGroup::PANELGROUPKEY;
}
public function isEnabled() {
if ($this->getUser()->getIsMailingList()) {
return false;
}
return true;
}
public function processRequest(AphrontRequest $request) {
$user = $this->getUser();
$viewer = $request->getUser();

View file

@ -18,6 +18,7 @@ abstract class PhabricatorSettingsPanel extends Phobject {
private $controller;
private $navigation;
private $overrideURI;
private $preferences;
public function setUser(PhabricatorUser $user) {
$this->user = $user;
@ -60,6 +61,15 @@ abstract class PhabricatorSettingsPanel extends Phobject {
return $this->navigation;
}
public function setPreferences(PhabricatorUserPreferences $preferences) {
$this->preferences = $preferences;
return $this;
}
public function getPreferences() {
return $this->preferences;
}
final public static function getAllPanels() {
$panels = id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
@ -145,13 +155,24 @@ abstract class PhabricatorSettingsPanel extends Phobject {
/**
* Return true if this panel is available to administrators while editing
* system agent accounts.
* Return true if this panel is available to administrators while managing
* bot and mailing list accounts.
*
* @return bool True to enable edit by administrators.
* @return bool True to enable management on behalf of accounts.
* @task config
*/
public function isEditableByAdministrators() {
public function isManagementPanel() {
return false;
}
/**
* Return true if this panel is available while editing settings templates.
*
* @return bool True to allow editing in templates.
* @task config
*/
public function isTemplatePanel() {
return false;
}
@ -194,11 +215,13 @@ abstract class PhabricatorSettingsPanel extends Phobject {
$key = $this->getPanelKey();
$key = phutil_escape_uri($key);
if ($this->getUser()->getPHID() != $this->getViewer()->getPHID()) {
$user_id = $this->getUser()->getID();
return "/settings/{$user_id}/panel/{$key}/{$path}";
$user = $this->getUser();
if ($user) {
$username = $user->getUsername();
return "/settings/user/{$username}/page/{$key}/{$path}";
} else {
return "/settings/panel/{$key}/{$path}";
$builtin = $this->getPreferences()->getBuiltinKey();
return "/settings/builtin/{$builtin}/page/{$key}/{$path}";
}
}
@ -217,20 +240,6 @@ abstract class PhabricatorSettingsPanel extends Phobject {
->addString($this->getPanelName());
}
protected function loadTargetPreferences() {
$viewer = $this->getViewer();
$user = $this->getUser();
$preferences = PhabricatorUserPreferences::loadUserPreferences($user);
PhabricatorPolicyFilter::requireCapability(
$viewer,
$preferences,
PhabricatorPolicyCapability::CAN_EDIT);
return $preferences;
}
protected function newDialog() {
return $this->getController()->newDialog();
}

View file

@ -6,6 +6,8 @@ final class PhabricatorUserPreferencesQuery
private $ids;
private $phids;
private $userPHIDs;
private $builtinKeys;
private $hasUserPHID;
private $users = array();
public function withIDs(array $ids) {
@ -18,6 +20,11 @@ final class PhabricatorUserPreferencesQuery
return $this;
}
public function withHasUserPHID($is_user) {
$this->hasUserPHID = $is_user;
return $this;
}
public function withUserPHIDs(array $phids) {
$this->userPHIDs = $phids;
return $this;
@ -30,6 +37,11 @@ final class PhabricatorUserPreferencesQuery
return $this;
}
public function withBuiltinKeys(array $keys) {
$this->builtinKeys = $keys;
return $this;
}
public function newResultObject() {
return new PhabricatorUserPreferences();
}
@ -64,6 +76,7 @@ final class PhabricatorUserPreferencesQuery
$users = array();
}
$need_global = array();
foreach ($prefs as $key => $pref) {
$user_phid = $pref->getUserPHID();
if (!$user_phid) {
@ -71,6 +84,8 @@ final class PhabricatorUserPreferencesQuery
continue;
}
$need_global[] = $pref;
$user = idx($users, $user_phid);
if (!$user) {
$this->didRejectResult($pref);
@ -81,6 +96,23 @@ final class PhabricatorUserPreferencesQuery
$pref->attachUser($user);
}
// If we loaded any user preferences, load the global defaults and attach
// them if they exist.
if ($need_global) {
$global = id(new self())
->setViewer($this->getViewer())
->withBuiltinKeys(
array(
PhabricatorUserPreferences::BUILTIN_GLOBAL_DEFAULT,
))
->executeOne();
if ($global) {
foreach ($need_global as $pref) {
$pref->attachDefaultSettings($global);
}
}
}
return $prefs;
}
@ -108,6 +140,25 @@ final class PhabricatorUserPreferencesQuery
$this->userPHIDs);
}
if ($this->builtinKeys !== null) {
$where[] = qsprintf(
$conn,
'builtinKey IN (%Ls)',
$this->builtinKeys);
}
if ($this->hasUserPHID !== null) {
if ($this->hasUserPHID) {
$where[] = qsprintf(
$conn,
'userPHID IS NOT NULL');
} else {
$where[] = qsprintf(
$conn,
'userPHID IS NULL');
}
}
return $where;
}

View file

@ -0,0 +1,86 @@
<?php
final class PhabricatorUserPreferencesSearchEngine
extends PhabricatorApplicationSearchEngine {
public function getResultTypeDescription() {
return pht('User Preferences');
}
public function getApplicationClassName() {
return 'PhabricatorSettingApplication';
}
public function newQuery() {
return id(new PhabricatorUserPreferencesQuery())
->withHasUserPHID(false);
}
protected function buildQueryFromParameters(array $map) {
$query = $this->newQuery();
return $query;
}
protected function buildCustomSearchFields() {
return array();
}
protected function getURI($path) {
return '/settings/list/'.$path;
}
protected function getBuiltinQueryNames() {
$names = array(
'all' => pht('All Settings'),
);
return $names;
}
public function buildSavedQueryFromBuiltin($query_key) {
$query = $this->newSavedQuery();
$query->setQueryKey($query_key);
switch ($query_key) {
case 'all':
return $query;
}
return parent::buildSavedQueryFromBuiltin($query_key);
}
protected function renderResultList(
array $settings,
PhabricatorSavedQuery $query,
array $handles) {
assert_instances_of($settings, 'PhabricatorUserPreferences');
$viewer = $this->requireViewer();
$list = id(new PHUIObjectItemListView())
->setViewer($viewer);
foreach ($settings as $setting) {
$item = id(new PHUIObjectItemView())
->setHeader($setting->getDisplayName())
->setHref($setting->getEditURI())
->setImageURI(PhabricatorUser::getDefaultProfileImageURI())
->setIcon('fa-globe')
->addAttribute(pht('Edit global default settings for all users.'));
$list->addItem($item);
}
$list->addItem(
id(new PHUIObjectItemView())
->setHeader(pht('Personal Account Settings'))
->addAttribute(pht('Edit settings for your personal account.'))
->setImageURI($viewer->getProfileImageURI())
->setHref('/settings/user/'.$viewer->getUsername().'/'));
return id(new PhabricatorApplicationSearchResultView())
->setObjectList($list);
}
}

View file

@ -12,6 +12,11 @@ final class PhabricatorPinnedApplicationsSetting
public function getSettingDefaultValue() {
$viewer = $this->getViewer();
// If we're editing a template, just show every available application.
if (!$viewer) {
$viewer = PhabricatorUser::getOmnipotentUser();
}
$applications = id(new PhabricatorApplicationQuery())
->setViewer($viewer)
->withInstalled(true)

View file

@ -2,14 +2,17 @@
abstract class PhabricatorSetting extends Phobject {
private $viewer;
private $viewer = false;
public function setViewer(PhabricatorUser $viewer) {
public function setViewer(PhabricatorUser $viewer = null) {
$this->viewer = $viewer;
return $this;
}
public function getViewer() {
if ($this->viewer === false) {
throw new PhutilInvalidStateException('setViewer');
}
return $this->viewer;
}

View file

@ -7,10 +7,14 @@ final class PhabricatorUserPreferences
PhabricatorDestructibleInterface,
PhabricatorApplicationTransactionInterface {
const BUILTIN_GLOBAL_DEFAULT = 'global';
protected $userPHID;
protected $preferences = array();
protected $builtinKey;
private $user = self::ATTACHABLE;
private $defaultSettings;
protected function getConfiguration() {
return array(
@ -18,11 +22,19 @@ final class PhabricatorUserPreferences
self::CONFIG_SERIALIZATION => array(
'preferences' => self::SERIALIZATION_JSON,
),
self::CONFIG_COLUMN_SCHEMA => array(
'userPHID' => 'phid?',
'builtinKey' => 'text32?',
),
self::CONFIG_KEY_SCHEMA => array(
'userPHID' => array(
'key_user' => array(
'columns' => array('userPHID'),
'unique' => true,
),
'key_builtin' => array(
'columns' => array('builtinKey'),
'unique' => true,
),
),
) + parent::getConfiguration();
}
@ -47,6 +59,10 @@ final class PhabricatorUserPreferences
}
public function getDefaultValue($key) {
if ($this->defaultSettings) {
return $this->defaultSettings->getSettingValue($key);
}
$setting = self::getSettingObject($key);
if (!$setting) {
@ -64,9 +80,6 @@ final class PhabricatorUserPreferences
return $this->preferences[$key];
}
// TODO: If this setting set inherits from another preference set,
// we would look it up here.
return $this->getDefaultValue($key);
}
@ -75,6 +88,11 @@ final class PhabricatorUserPreferences
return idx($settings, $key);
}
public function attachDefaultSettings(PhabricatorUserPreferences $settings) {
$this->defaultSettings = $settings;
return $this;
}
public function attachUser(PhabricatorUser $user = null) {
$this->user = $user;
return $this;
@ -127,6 +145,21 @@ final class PhabricatorUserPreferences
->setNewValue($value);
}
public function getEditURI() {
if ($this->getUser()) {
return '/settings/user/'.$this->getUser()->getUsername().'/';
} else {
return '/settings/builtin/'.$this->getBuiltinKey().'/';
}
}
public function getDisplayName() {
if ($this->getBuiltinKey()) {
return pht('Global Default Settings');
}
return pht('Personal Settings');
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */

View file

@ -532,6 +532,10 @@ abstract class PhabricatorEditEngine
return $this->getObjectViewURI($object);
}
public function getEffectiveObjectEditDoneURI($object) {
return $this->getEffectiveObjectViewURI($object);
}
public function getEffectiveObjectEditCancelURI($object) {
$page = $this->getSelectedPage();
if ($page) {
@ -1169,7 +1173,7 @@ abstract class PhabricatorEditEngine
$object,
array $xactions) {
return id(new AphrontRedirectResponse())
->setURI($this->getEffectiveObjectViewURI($object));
->setURI($this->getEffectiveObjectEditDoneURI($object));
}
private function buildEditForm($object, array $fields) {