mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 14:00:56 +01:00
Make Settings modular and allow them to be EditEngine'd
Summary: Ref T4103. This starts breaking out settings in a modern way to prepare for global defaults. Test Plan: - Edited diff settings. - Saw them take effect in primary settings pane. - Set stuff to new automatic defaults. - Tried to edit another user's settings. - Edited a bot's settings as an administrator. {F1669077} Reviewers: chad Reviewed By: chad Maniphest Tasks: T4103 Differential Revision: https://secure.phabricator.com/D15995
This commit is contained in:
parent
2dc4096ea1
commit
5e6716399c
15 changed files with 566 additions and 4 deletions
|
@ -2822,6 +2822,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorObjectSelectorDialog' => 'view/control/PhabricatorObjectSelectorDialog.php',
|
||||
'PhabricatorOffsetPagedQuery' => 'infrastructure/query/PhabricatorOffsetPagedQuery.php',
|
||||
'PhabricatorOldWorldContentSource' => 'infrastructure/contentsource/PhabricatorOldWorldContentSource.php',
|
||||
'PhabricatorOlderInlinesSetting' => 'applications/settings/setting/PhabricatorOlderInlinesSetting.php',
|
||||
'PhabricatorOneTimeTriggerClock' => 'infrastructure/daemon/workers/clock/PhabricatorOneTimeTriggerClock.php',
|
||||
'PhabricatorOpcodeCacheSpec' => 'applications/cache/spec/PhabricatorOpcodeCacheSpec.php',
|
||||
'PhabricatorOwnerPathQuery' => 'applications/owners/query/PhabricatorOwnerPathQuery.php',
|
||||
|
@ -3348,11 +3349,15 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSecurityConfigOptions' => 'applications/config/option/PhabricatorSecurityConfigOptions.php',
|
||||
'PhabricatorSecuritySetupCheck' => 'applications/config/check/PhabricatorSecuritySetupCheck.php',
|
||||
'PhabricatorSelectEditField' => 'applications/transactions/editfield/PhabricatorSelectEditField.php',
|
||||
'PhabricatorSelectSetting' => 'applications/settings/setting/PhabricatorSelectSetting.php',
|
||||
'PhabricatorSendGridConfigOptions' => 'applications/config/option/PhabricatorSendGridConfigOptions.php',
|
||||
'PhabricatorSessionsSettingsPanel' => 'applications/settings/panel/PhabricatorSessionsSettingsPanel.php',
|
||||
'PhabricatorSetting' => 'applications/settings/setting/PhabricatorSetting.php',
|
||||
'PhabricatorSettingsAddEmailAction' => 'applications/settings/action/PhabricatorSettingsAddEmailAction.php',
|
||||
'PhabricatorSettingsAdjustController' => 'applications/settings/controller/PhabricatorSettingsAdjustController.php',
|
||||
'PhabricatorSettingsApplication' => 'applications/settings/application/PhabricatorSettingsApplication.php',
|
||||
'PhabricatorSettingsEditController' => 'applications/settings/controller/PhabricatorSettingsEditController.php',
|
||||
'PhabricatorSettingsEditEngine' => 'applications/settings/editor/PhabricatorSettingsEditEngine.php',
|
||||
'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php',
|
||||
'PhabricatorSettingsMainMenuBarExtension' => 'applications/settings/extension/PhabricatorSettingsMainMenuBarExtension.php',
|
||||
'PhabricatorSettingsPanel' => 'applications/settings/panel/PhabricatorSettingsPanel.php',
|
||||
|
@ -3363,6 +3368,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSetupIssueUIExample' => 'applications/uiexample/examples/PhabricatorSetupIssueUIExample.php',
|
||||
'PhabricatorSetupIssueView' => 'applications/config/view/PhabricatorSetupIssueView.php',
|
||||
'PhabricatorShortSite' => 'aphront/site/PhabricatorShortSite.php',
|
||||
'PhabricatorShowFiletreeSetting' => 'applications/settings/setting/PhabricatorShowFiletreeSetting.php',
|
||||
'PhabricatorSimpleEditType' => 'applications/transactions/edittype/PhabricatorSimpleEditType.php',
|
||||
'PhabricatorSite' => 'aphront/site/PhabricatorSite.php',
|
||||
'PhabricatorSlowvoteApplication' => 'applications/slowvote/application/PhabricatorSlowvoteApplication.php',
|
||||
|
@ -3568,6 +3574,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorUIExampleRenderController' => 'applications/uiexample/controller/PhabricatorUIExampleRenderController.php',
|
||||
'PhabricatorUIExamplesApplication' => 'applications/uiexample/application/PhabricatorUIExamplesApplication.php',
|
||||
'PhabricatorUSEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php',
|
||||
'PhabricatorUnifiedDiffsSetting' => 'applications/settings/setting/PhabricatorUnifiedDiffsSetting.php',
|
||||
'PhabricatorUnitTestContentSource' => 'infrastructure/contentsource/PhabricatorUnitTestContentSource.php',
|
||||
'PhabricatorUnitsTestCase' => 'view/__tests__/PhabricatorUnitsTestCase.php',
|
||||
'PhabricatorUnknownContentSource' => 'infrastructure/contentsource/PhabricatorUnknownContentSource.php',
|
||||
|
@ -3592,6 +3599,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorUserLogView' => 'applications/people/view/PhabricatorUserLogView.php',
|
||||
'PhabricatorUserPHIDResolver' => 'applications/phid/resolver/PhabricatorUserPHIDResolver.php',
|
||||
'PhabricatorUserPreferences' => 'applications/settings/storage/PhabricatorUserPreferences.php',
|
||||
'PhabricatorUserPreferencesEditor' => 'applications/settings/editor/PhabricatorUserPreferencesEditor.php',
|
||||
'PhabricatorUserPreferencesPHIDType' => 'applications/settings/phid/PhabricatorUserPreferencesPHIDType.php',
|
||||
'PhabricatorUserPreferencesQuery' => 'applications/settings/query/PhabricatorUserPreferencesQuery.php',
|
||||
'PhabricatorUserPreferencesTransaction' => 'applications/settings/storage/PhabricatorUserPreferencesTransaction.php',
|
||||
|
@ -7413,6 +7421,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorObjectSelectorDialog' => 'Phobject',
|
||||
'PhabricatorOffsetPagedQuery' => 'PhabricatorQuery',
|
||||
'PhabricatorOldWorldContentSource' => 'PhabricatorContentSource',
|
||||
'PhabricatorOlderInlinesSetting' => 'PhabricatorSelectSetting',
|
||||
'PhabricatorOneTimeTriggerClock' => 'PhabricatorTriggerClock',
|
||||
'PhabricatorOpcodeCacheSpec' => 'PhabricatorCacheSpec',
|
||||
'PhabricatorOwnerPathQuery' => 'Phobject',
|
||||
|
@ -8064,11 +8073,15 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSecurityConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||
'PhabricatorSecuritySetupCheck' => 'PhabricatorSetupCheck',
|
||||
'PhabricatorSelectEditField' => 'PhabricatorEditField',
|
||||
'PhabricatorSelectSetting' => 'PhabricatorSetting',
|
||||
'PhabricatorSendGridConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||
'PhabricatorSessionsSettingsPanel' => 'PhabricatorSettingsPanel',
|
||||
'PhabricatorSetting' => 'Phobject',
|
||||
'PhabricatorSettingsAddEmailAction' => 'PhabricatorSystemAction',
|
||||
'PhabricatorSettingsAdjustController' => 'PhabricatorController',
|
||||
'PhabricatorSettingsApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorSettingsEditController' => 'PhabricatorController',
|
||||
'PhabricatorSettingsEditEngine' => 'PhabricatorEditEngine',
|
||||
'PhabricatorSettingsMainController' => 'PhabricatorController',
|
||||
'PhabricatorSettingsMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
|
||||
'PhabricatorSettingsPanel' => 'Phobject',
|
||||
|
@ -8079,6 +8092,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSetupIssueUIExample' => 'PhabricatorUIExample',
|
||||
'PhabricatorSetupIssueView' => 'AphrontView',
|
||||
'PhabricatorShortSite' => 'PhabricatorSite',
|
||||
'PhabricatorShowFiletreeSetting' => 'PhabricatorSelectSetting',
|
||||
'PhabricatorSimpleEditType' => 'PhabricatorEditType',
|
||||
'PhabricatorSite' => 'AphrontSite',
|
||||
'PhabricatorSlowvoteApplication' => 'PhabricatorApplication',
|
||||
|
@ -8305,6 +8319,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorUIExampleRenderController' => 'PhabricatorController',
|
||||
'PhabricatorUIExamplesApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorUSEnglishTranslation' => 'PhutilTranslation',
|
||||
'PhabricatorUnifiedDiffsSetting' => 'PhabricatorSelectSetting',
|
||||
'PhabricatorUnitTestContentSource' => 'PhabricatorContentSource',
|
||||
'PhabricatorUnitsTestCase' => 'PhabricatorTestCase',
|
||||
'PhabricatorUnknownContentSource' => 'PhabricatorContentSource',
|
||||
|
@ -8351,6 +8366,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorDestructibleInterface',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
),
|
||||
'PhabricatorUserPreferencesEditor' => 'AlmanacEditor',
|
||||
'PhabricatorUserPreferencesPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhabricatorUserPreferencesQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorUserPreferencesTransaction' => 'PhabricatorApplicationTransaction',
|
||||
|
|
|
@ -503,6 +503,7 @@ final class PhabricatorUser
|
|||
if (!$preferences) {
|
||||
$preferences = new PhabricatorUserPreferences();
|
||||
$preferences->setUserPHID($this->getPHID());
|
||||
$preferences->attachUser($this);
|
||||
|
||||
$default_dict = array(
|
||||
PhabricatorUserPreferences::PREFERENCE_TITLES => 'glyph',
|
||||
|
|
|
@ -34,6 +34,8 @@ final class PhabricatorSettingsApplication extends PhabricatorApplication {
|
|||
'adjust/' => 'PhabricatorSettingsAdjustController',
|
||||
'timezone/(?P<offset>[^/]+)/'
|
||||
=> 'PhabricatorSettingsTimezoneController',
|
||||
'(?P<type>user)/(?P<username>[^/]+)/(?:panel/(?P<key>[^/]+)/)?'
|
||||
=> 'PhabricatorSettingsEditController',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorSettingsEditController
|
||||
extends PhabricatorController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$engine = id(new PhabricatorSettingsEditEngine())
|
||||
->setController($this);
|
||||
|
||||
switch ($request->getURIData('type')) {
|
||||
case 'user':
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($viewer)
|
||||
->withUsernames(array($request->getURIData('username')))
|
||||
->executeOne();
|
||||
|
||||
$preferences = $user->loadPreferences();
|
||||
|
||||
PhabricatorPolicyFilter::requireCapability(
|
||||
$viewer,
|
||||
$preferences,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$engine->setTargetObject($preferences);
|
||||
break;
|
||||
default:
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
return $engine->buildResponse();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorSettingsEditEngine
|
||||
extends PhabricatorEditEngine {
|
||||
|
||||
const ENGINECONST = 'settings.settings';
|
||||
|
||||
public function isEngineConfigurable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getEngineName() {
|
||||
return pht('Settings');
|
||||
}
|
||||
|
||||
public function getSummaryHeader() {
|
||||
return pht('Edit Settings Configurations');
|
||||
}
|
||||
|
||||
public function getSummaryText() {
|
||||
return pht('This engine is used to edit settings.');
|
||||
}
|
||||
|
||||
public function getEngineApplicationClass() {
|
||||
return 'PhabricatorSettingsApplication';
|
||||
}
|
||||
|
||||
protected function newEditableObject() {
|
||||
return new PhabricatorUserPreferences();
|
||||
}
|
||||
|
||||
protected function newObjectQuery() {
|
||||
return new PhabricatorUserPreferencesQuery();
|
||||
}
|
||||
|
||||
protected function getObjectCreateTitleText($object) {
|
||||
return pht('Create Settings');
|
||||
}
|
||||
|
||||
protected function getObjectCreateButtonText($object) {
|
||||
return pht('Create Settings');
|
||||
}
|
||||
|
||||
protected function getObjectEditTitleText($object) {
|
||||
return pht('Edit Settings');
|
||||
}
|
||||
|
||||
protected function getObjectEditShortText($object) {
|
||||
return pht('Edit Settings');
|
||||
}
|
||||
|
||||
protected function getObjectCreateShortText() {
|
||||
return pht('Create Settings');
|
||||
}
|
||||
|
||||
protected function getObjectName() {
|
||||
return pht('Settings');
|
||||
}
|
||||
|
||||
protected function getEditorURI() {
|
||||
return '/settings/edit/';
|
||||
}
|
||||
|
||||
protected function getObjectCreateCancelURI($object) {
|
||||
return '/settings/';
|
||||
}
|
||||
|
||||
protected function getObjectViewURI($object) {
|
||||
// TODO: This isn't correct...
|
||||
return '/settings/user/'.$this->getViewer()->getUsername().'/';
|
||||
}
|
||||
|
||||
protected function getCreateNewObjectPolicy() {
|
||||
return PhabricatorPolicies::POLICY_ADMIN;
|
||||
}
|
||||
|
||||
protected function buildCustomEditFields($object) {
|
||||
$viewer = $this->getViewer();
|
||||
$settings = PhabricatorSetting::getAllEnabledSettings($viewer);
|
||||
|
||||
$fields = array();
|
||||
foreach ($settings as $setting) {
|
||||
foreach ($setting->newCustomEditFields($object) as $field) {
|
||||
$fields[] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorUserPreferencesEditor
|
||||
extends AlmanacEditor {
|
||||
|
||||
public function getEditorObjectsDescription() {
|
||||
return pht('Settings');
|
||||
}
|
||||
|
||||
public function getTransactionTypes() {
|
||||
$types = parent::getTransactionTypes();
|
||||
|
||||
$types[] = PhabricatorUserPreferencesTransaction::TYPE_SETTING;
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
protected function getCustomTransactionOldValue(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
$setting_key = $xaction->getMetadataValue(
|
||||
PhabricatorUserPreferencesTransaction::PROPERTY_SETTING);
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorUserPreferencesTransaction::TYPE_SETTING:
|
||||
return $object->getPreference($setting_key);
|
||||
}
|
||||
|
||||
return parent::getCustomTransactionOldValue($object, $xaction);
|
||||
}
|
||||
|
||||
protected function getCustomTransactionNewValue(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
$actor = $this->getActor();
|
||||
|
||||
$setting_key = $xaction->getMetadataValue(
|
||||
PhabricatorUserPreferencesTransaction::PROPERTY_SETTING);
|
||||
|
||||
$settings = PhabricatorSetting::getAllEnabledSettings($actor);
|
||||
$setting = $settings[$setting_key];
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorUserPreferencesTransaction::TYPE_SETTING:
|
||||
$value = $xaction->getNewValue();
|
||||
$value = $setting->getTransactionNewValue($value);
|
||||
return $value;
|
||||
}
|
||||
|
||||
return parent::getCustomTransactionNewValue($object, $xaction);
|
||||
}
|
||||
|
||||
protected function applyCustomInternalTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
$setting_key = $xaction->getMetadataValue(
|
||||
PhabricatorUserPreferencesTransaction::PROPERTY_SETTING);
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorUserPreferencesTransaction::TYPE_SETTING:
|
||||
$new_value = $xaction->getNewValue();
|
||||
if ($new_value === null) {
|
||||
$object->unsetPreference($setting_key);
|
||||
} else {
|
||||
$object->setPreference($setting_key, $new_value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::applyCustomInternalTransaction($object, $xaction);
|
||||
}
|
||||
|
||||
protected function applyCustomExternalTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorUserPreferencesTransaction::TYPE_SETTING:
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::applyCustomExternalTransaction($object, $xaction);
|
||||
}
|
||||
|
||||
protected function validateTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
$type,
|
||||
array $xactions) {
|
||||
|
||||
$errors = parent::validateTransaction($object, $type, $xactions);
|
||||
|
||||
$actor = $this->getActor();
|
||||
$settings = PhabricatorSetting::getAllEnabledSettings($actor);
|
||||
|
||||
switch ($type) {
|
||||
case PhabricatorUserPreferencesTransaction::TYPE_SETTING:
|
||||
foreach ($xactions as $xaction) {
|
||||
$setting_key = $xaction->getMetadataValue(
|
||||
PhabricatorUserPreferencesTransaction::PROPERTY_SETTING);
|
||||
|
||||
$setting = idx($settings, $setting_key);
|
||||
if (!$setting) {
|
||||
$errors[] = new PhabricatorApplicationTransactionValidationError(
|
||||
$type,
|
||||
pht('Invalid'),
|
||||
pht(
|
||||
'There is no known application setting with key "%s".',
|
||||
$setting_key),
|
||||
$xaction);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$setting->validateTransactionValue($xaction->getNewValue());
|
||||
} catch (Exception $ex) {
|
||||
$errors[] = new PhabricatorApplicationTransactionValidationError(
|
||||
$type,
|
||||
pht('Invalid'),
|
||||
$ex->getMessage(),
|
||||
$xaction);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
}
|
|
@ -32,7 +32,6 @@ final class PhabricatorUserPreferencesPHIDType extends PhabricatorPHIDType {
|
|||
$viewer = $query->getViewer();
|
||||
foreach ($handles as $phid => $handle) {
|
||||
$preferences = $objects[$phid];
|
||||
|
||||
$handle->setName(pht('Settings %d', $preferences->getID()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorOlderInlinesSetting
|
||||
extends PhabricatorSelectSetting {
|
||||
|
||||
const SETTINGKEY = 'diff-ghosts';
|
||||
|
||||
const VALUE_GHOST_INLINES_ENABLED = 'default';
|
||||
const VALUE_GHOST_INLINES_DISABLED = 'disabled';
|
||||
|
||||
public function getSettingName() {
|
||||
return pht('Show Older Inlines');
|
||||
}
|
||||
|
||||
protected function getControlInstructions() {
|
||||
return pht(
|
||||
'When a revision is updated, Phabricator attempts to bring inline '.
|
||||
'comments on the older version forward to the new changes. You can '.
|
||||
'disable this behavior if you prefer comments stay anchored in one '.
|
||||
'place.');
|
||||
}
|
||||
|
||||
public function getSettingDefaultValue() {
|
||||
return self::VALUE_GHOST_INLINES_ENABLED;
|
||||
}
|
||||
|
||||
protected function getSelectOptions() {
|
||||
return array(
|
||||
self::VALUE_GHOST_INLINES_ENABLED => pht('Enabled'),
|
||||
self::VALUE_GHOST_INLINES_DISABLED => pht('Disabled'),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorSelectSetting
|
||||
extends PhabricatorSetting {
|
||||
|
||||
abstract protected function getSelectOptions();
|
||||
|
||||
final protected function newCustomEditField($object) {
|
||||
$setting_key = $this->getSettingKey();
|
||||
$default_value = $object->getDefaultValue($setting_key);
|
||||
|
||||
$options = $this->getSelectOptions();
|
||||
|
||||
if (isset($options[$default_value])) {
|
||||
$default_label = pht('Default (%s)', $options[$default_value]);
|
||||
} else {
|
||||
$default_label = pht('Default (Unknown, "%s")', $default_value);
|
||||
}
|
||||
|
||||
$options = array(
|
||||
'' => $default_label,
|
||||
) + $options;
|
||||
|
||||
return $this->newEditField($object, new PhabricatorSelectEditField())
|
||||
->setOptions($options);
|
||||
}
|
||||
|
||||
final public function validateTransactionValue($value) {
|
||||
if (!strlen($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$options = $this->getSelectOptions();
|
||||
|
||||
if (!isset($options[$value])) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Value "%s" is not valid for setting "%s": valid values are %s.',
|
||||
$value,
|
||||
$this->getSettingName(),
|
||||
implode(', ', array_keys($options))));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public function getTransactionNewValue($value) {
|
||||
if (!strlen($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (string)$value;
|
||||
}
|
||||
|
||||
}
|
96
src/applications/settings/setting/PhabricatorSetting.php
Normal file
96
src/applications/settings/setting/PhabricatorSetting.php
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorSetting extends Phobject {
|
||||
|
||||
private $viewer;
|
||||
|
||||
public function setViewer(PhabricatorUser $viewer) {
|
||||
$this->viewer = $viewer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getViewer() {
|
||||
return $this->viewer;
|
||||
}
|
||||
|
||||
abstract public function getSettingName();
|
||||
|
||||
protected function getControlInstructions() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function isEnabledForViewer(PhabricatorUser $viewer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSettingDefaultValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
final public function getSettingKey() {
|
||||
return $this->getPhobjectClassConstant('SETTINGKEY');
|
||||
}
|
||||
|
||||
public static function getAllSettings() {
|
||||
return id(new PhutilClassMapQuery())
|
||||
->setAncestorClass(__CLASS__)
|
||||
->setUniqueMethod('getSettingKey')
|
||||
->execute();
|
||||
}
|
||||
|
||||
public static function getAllEnabledSettings(PhabricatorUser $viewer) {
|
||||
$settings = self::getAllSettings();
|
||||
foreach ($settings as $key => $setting) {
|
||||
if (!$setting->isEnabledForViewer($viewer)) {
|
||||
unset($settings[$key]);
|
||||
}
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
final public function newCustomEditFields($object) {
|
||||
$fields = array();
|
||||
|
||||
$field = $this->newCustomEditField($object);
|
||||
if ($field) {
|
||||
$fields[] = $field;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
protected function newCustomEditField($object) {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function newEditField($object, PhabricatorEditField $template) {
|
||||
$setting_property = PhabricatorUserPreferencesTransaction::PROPERTY_SETTING;
|
||||
$setting_key = $this->getSettingKey();
|
||||
$value = $object->getPreference($setting_key);
|
||||
$xaction_type = PhabricatorUserPreferencesTransaction::TYPE_SETTING;
|
||||
$label = $this->getSettingName();
|
||||
|
||||
$template
|
||||
->setKey($setting_key)
|
||||
->setLabel($label)
|
||||
->setValue($value)
|
||||
->setTransactionType($xaction_type)
|
||||
->setMetadataValue($setting_property, $setting_key);
|
||||
|
||||
$instructions = $this->getControlInstructions();
|
||||
if (strlen($instructions)) {
|
||||
$template->setControlInstructions($instructions);
|
||||
}
|
||||
|
||||
return $template;
|
||||
}
|
||||
|
||||
public function validateTransactionValue($value) {
|
||||
return;
|
||||
}
|
||||
|
||||
public function getTransactionNewValue($value) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorShowFiletreeSetting
|
||||
extends PhabricatorSelectSetting {
|
||||
|
||||
const SETTINGKEY = 'diff-filetree';
|
||||
|
||||
const VALUE_DISABLE_FILETREE = 0;
|
||||
const VALUE_ENABLE_FILETREE = 1;
|
||||
|
||||
public function getSettingName() {
|
||||
return pht('Show Filetree');
|
||||
}
|
||||
|
||||
protected function getControlInstructions() {
|
||||
return pht(
|
||||
'When viewing a revision or commit, you can enable a sidebar showing '.
|
||||
'affected files. When this option is enabled, press {nav %s} to show '.
|
||||
'or hide the sidebar.',
|
||||
'f');
|
||||
}
|
||||
|
||||
public function getSettingDefaultValue() {
|
||||
return self::VALUE_DISABLE_FILETREE;
|
||||
}
|
||||
|
||||
protected function getSelectOptions() {
|
||||
return array(
|
||||
self::VALUE_DISABLE_FILETREE => pht('Disable Filetree'),
|
||||
self::VALUE_ENABLE_FILETREE => pht('Enable Filetree'),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorUnifiedDiffsSetting
|
||||
extends PhabricatorSelectSetting {
|
||||
|
||||
const SETTINGKEY = 'diff-unified';
|
||||
|
||||
const VALUE_ON_SMALL_SCREENS = 'default';
|
||||
const VALUE_ALWAYS_UNIFIED = 'unified';
|
||||
|
||||
public function getSettingName() {
|
||||
return pht('Show Unified Diffs');
|
||||
}
|
||||
|
||||
protected function getControlInstructions() {
|
||||
return pht(
|
||||
'Phabricator normally shows diffs in a side-by-side layout on large '.
|
||||
'screens and automatically switches to a unified view on small '.
|
||||
'screens (like mobile phones). If you prefer unified diffs even on '.
|
||||
'large screens, you can select them for use on all displays.');
|
||||
}
|
||||
|
||||
public function getSettingDefaultValue() {
|
||||
return self::VALUE_ON_SMALL_SCREENS;
|
||||
}
|
||||
|
||||
protected function getSelectOptions() {
|
||||
return array(
|
||||
self::VALUE_ON_SMALL_SCREENS => pht('On Small Screens'),
|
||||
self::VALUE_ALWAYS_UNIFIED => pht('Always'),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -92,6 +92,21 @@ final class PhabricatorUserPreferences
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getDefaultValue($key) {
|
||||
$setting = self::getSettingObject($key);
|
||||
|
||||
if (!$setting) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $setting->getSettingDefaultValue();
|
||||
}
|
||||
|
||||
private static function getSettingObject($key) {
|
||||
$settings = PhabricatorSetting::getAllSettings();
|
||||
return idx($settings, $key);
|
||||
}
|
||||
|
||||
public function getPinnedApplications(array $apps, PhabricatorUser $viewer) {
|
||||
$pref_pinned = self::PREFERENCE_APP_PINNED;
|
||||
$pinned = $this->getPreference($pref_pinned);
|
||||
|
@ -212,8 +227,7 @@ final class PhabricatorUserPreferences
|
|||
|
||||
|
||||
public function getApplicationTransactionEditor() {
|
||||
// TODO: Implement.
|
||||
throw new PhutilMethodNotImplementedException();
|
||||
return new PhabricatorUserPreferencesEditor();
|
||||
}
|
||||
|
||||
public function getApplicationTransactionObject() {
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
final class PhabricatorUserPreferencesTransaction
|
||||
extends PhabricatorApplicationTransaction {
|
||||
|
||||
const TYPE_SETTING = 'setting';
|
||||
|
||||
const PROPERTY_SETTING = 'setting.key';
|
||||
|
||||
public function getApplicationName() {
|
||||
return 'user';
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ final class AphrontFormSelectControl extends AphrontFormControl {
|
|||
$disabled = array_fuse($disabled);
|
||||
|
||||
$tags = array();
|
||||
$already_selected = false;
|
||||
foreach ($options as $value => $thing) {
|
||||
if (is_array($thing)) {
|
||||
$tags[] = phutil_tag(
|
||||
|
@ -65,10 +66,22 @@ final class AphrontFormSelectControl extends AphrontFormControl {
|
|||
),
|
||||
self::renderOptions($selected, $thing));
|
||||
} else {
|
||||
// When there are a list of options including similar values like
|
||||
// "0" and "" (the empty string), only select the first matching
|
||||
// value. Ideally this should be more precise about matching, but we
|
||||
// have 2,000 of these controls at this point so hold that for a
|
||||
// broader rewrite.
|
||||
if (!$already_selected && ($value == $selected)) {
|
||||
$is_selected = 'selected';
|
||||
$already_selected = true;
|
||||
} else {
|
||||
$is_selected = null;
|
||||
}
|
||||
|
||||
$tags[] = phutil_tag(
|
||||
'option',
|
||||
array(
|
||||
'selected' => ($value == $selected) ? 'selected' : null,
|
||||
'selected' => $is_selected,
|
||||
'value' => $value,
|
||||
'disabled' => isset($disabled[$value]) ? 'disabled' : null,
|
||||
),
|
||||
|
|
Loading…
Reference in a new issue