diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index e3af2516aa..b05d327542 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -684,6 +684,7 @@ phutil_register_library_map(array(
'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/PhabricatorConduitMethodCallLog.php',
'PhabricatorConduitTokenController' => 'applications/conduit/controller/PhabricatorConduitTokenController.php',
'PhabricatorConfigController' => 'applications/config/controller/PhabricatorConfigController.php',
+ 'PhabricatorConfigDefaultSource' => 'infrastructure/env/PhabricatorConfigDefaultSource.php',
'PhabricatorConfigDictionarySource' => 'infrastructure/env/PhabricatorConfigDictionarySource.php',
'PhabricatorConfigEditController' => 'applications/config/controller/PhabricatorConfigEditController.php',
'PhabricatorConfigEntry' => 'applications/config/storage/PhabricatorConfigEntry.php',
@@ -2019,6 +2020,7 @@ phutil_register_library_map(array(
'PhabricatorConduitMethodCallLog' => 'PhabricatorConduitDAO',
'PhabricatorConduitTokenController' => 'PhabricatorConduitController',
'PhabricatorConfigController' => 'PhabricatorController',
+ 'PhabricatorConfigDefaultSource' => 'PhabricatorConfigProxySource',
'PhabricatorConfigDictionarySource' => 'PhabricatorConfigSource',
'PhabricatorConfigEditController' => 'PhabricatorConfigController',
'PhabricatorConfigEntry' => 'PhabricatorConfigEntryDAO',
diff --git a/src/applications/config/controller/PhabricatorConfigEditController.php b/src/applications/config/controller/PhabricatorConfigEditController.php
index 0b9371be19..caeb4e0205 100644
--- a/src/applications/config/controller/PhabricatorConfigEditController.php
+++ b/src/applications/config/controller/PhabricatorConfigEditController.php
@@ -122,30 +122,13 @@ final class PhabricatorConfigEditController
->setValue($examples));
}
+ $form->appendChild(
+ id(new AphrontFormMarkupControl())
+ ->setLabel(pht('Default'))
+ ->setValue($this->renderDefaults($option)));
- // TODO: This isn't quite correct -- we should read from the entire
- // configuration stack, ignoring database configuration. For now, though,
- // it's a reasonable approximation.
- $default = $this->prettyPrintJSON($option->getDefault());
- $form
- ->appendChild(
- phutil_render_tag(
- 'p',
- array(
- 'class' => 'aphront-form-input',
- ),
- 'If left blank, the setting will return to its default value. '.
- 'Its default value is:'))
- ->appendChild(
- phutil_render_tag(
- 'pre',
- array(
- 'class' => 'aphront-form-input',
- ),
- phutil_escape_html($default)));
-
- $title = pht('Edit %s', $this->key);
- $short = pht('Edit');
+ $title = pht('Edit %s', $this->key);
+ $short = pht('Edit');
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addCrumb(
@@ -302,18 +285,73 @@ final class PhabricatorConfigEditController
}
$table = array();
+ $table[] = '
';
+ $table[] = '| '.pht('Example').' | ';
+ $table[] = ''.pht('Value').' | ';
+ $table[] = '
';
foreach ($examples as $example) {
list($value, $description) = $example;
if ($value === null) {
- $value = '(empty)';
+ $value = ''.pht('(empty)').'';
} else {
$value = phutil_escape_html($value);
}
$table[] = '';
- $table[] = '| '.$value.' | ';
- $table[] = ''.phutil_escape_html($description).' | ';
+ $table[] = ''.phutil_escape_html($description).' | ';
+ $table[] = ''.$value.' | ';
+ $table[] = '
';
+ }
+
+ require_celerity_resource('config-options-css');
+
+ return phutil_render_tag(
+ 'table',
+ array(
+ 'class' => 'config-option-table',
+ ),
+ implode("\n", $table));
+ }
+
+ private function renderDefaults(PhabricatorConfigOption $option) {
+ $stack = PhabricatorEnv::getConfigSourceStack();
+ $stack = $stack->getStack();
+
+ /*
+
+ TODO: Once DatabaseSource lands, do this:
+
+ foreach ($stack as $key => $source) {
+ unset($stack[$key]);
+ if ($source instanceof PhabricatorConfigDatabaseSource) {
+ break;
+ }
+ }
+
+ */
+
+
+ $table = array();
+ $table[] = '';
+ $table[] = '| '.pht('Source').' | ';
+ $table[] = ''.pht('Value').' | ';
+ $table[] = '
';
+ foreach ($stack as $key => $source) {
+ $value = $source->getKeys(
+ array(
+ $option->getKey(),
+ ));
+
+ if (!array_key_exists($option->getKey(), $value)) {
+ $value = ''.pht('(empty)').'';
+ } else {
+ $value = $this->prettyPrintJSON($value[$option->getKey()]);
+ }
+
+ $table[] = '';
+ $table[] = '| '.phutil_escape_html($source->getName()).' | ';
+ $table[] = ''.$value.' | ';
$table[] = '
';
}
@@ -322,7 +360,7 @@ final class PhabricatorConfigEditController
return phutil_render_tag(
'table',
array(
- 'class' => 'config-option-examples',
+ 'class' => 'config-option-table',
),
implode("\n", $table));
}
diff --git a/src/infrastructure/env/PhabricatorConfigDefaultSource.php b/src/infrastructure/env/PhabricatorConfigDefaultSource.php
new file mode 100644
index 0000000000..e8fc3bad13
--- /dev/null
+++ b/src/infrastructure/env/PhabricatorConfigDefaultSource.php
@@ -0,0 +1,16 @@
+setSource(new PhabricatorConfigDictionarySource($options));
+ }
+
+}
diff --git a/src/infrastructure/env/PhabricatorConfigProxySource.php b/src/infrastructure/env/PhabricatorConfigProxySource.php
index 953aebd5d5..d2804e5ab8 100644
--- a/src/infrastructure/env/PhabricatorConfigProxySource.php
+++ b/src/infrastructure/env/PhabricatorConfigProxySource.php
@@ -33,11 +33,22 @@ abstract class PhabricatorConfigProxySource
}
public function setKeys(array $keys) {
- return $this->getSource()->setKeys($keys);
+ $this->getSource()->setKeys($keys);
+ return $this;
}
public function deleteKeys(array $keys) {
- return $this->getSource()->deleteKeys();
+ $this->getSource()->deleteKeys();
+ return $this;
+ }
+
+ public function setName($name) {
+ $this->getSource()->setName($name);
+ return $this;
+ }
+
+ public function getName() {
+ return $this->getSource()->getName();
}
}
diff --git a/src/infrastructure/env/PhabricatorConfigSource.php b/src/infrastructure/env/PhabricatorConfigSource.php
index ce6d4acd53..bfbc68d5de 100644
--- a/src/infrastructure/env/PhabricatorConfigSource.php
+++ b/src/infrastructure/env/PhabricatorConfigSource.php
@@ -2,6 +2,17 @@
abstract class PhabricatorConfigSource {
+ private $name;
+
+ public function setName($name) {
+ $this->name = $name;
+ return $this;
+ }
+
+ public function getName() {
+ return $this->name;
+ }
+
abstract public function getKeys(array $keys);
abstract public function getAllKeys();
diff --git a/src/infrastructure/env/PhabricatorConfigStackSource.php b/src/infrastructure/env/PhabricatorConfigStackSource.php
index 0e8e49a9f6..2d6f735ffb 100644
--- a/src/infrastructure/env/PhabricatorConfigStackSource.php
+++ b/src/infrastructure/env/PhabricatorConfigStackSource.php
@@ -24,6 +24,10 @@ final class PhabricatorConfigStackSource
return array_shift($this->stack);
}
+ public function getStack() {
+ return $this->stack;
+ }
+
public function getKeys(array $keys) {
$result = array();
foreach ($this->stack as $source) {
diff --git a/src/infrastructure/env/PhabricatorEnv.php b/src/infrastructure/env/PhabricatorEnv.php
index 60e259dff6..07a01d6537 100644
--- a/src/infrastructure/env/PhabricatorEnv.php
+++ b/src/infrastructure/env/PhabricatorEnv.php
@@ -96,8 +96,7 @@ final class PhabricatorEnv {
private static function initializeCommonEnvironment() {
$env = self::getSelectedEnvironmentName();
- self::$sourceStack = new PhabricatorConfigStackSource();
- self::$sourceStack->pushSource(new PhabricatorConfigFileSource($env));
+ self::buildConfigurationSourceStack();
PhutilErrorHandler::initialize();
@@ -126,6 +125,24 @@ final class PhabricatorEnv {
->addTranslations($translation->getTranslations());
}
+ private static function buildConfigurationSourceStack() {
+ $stack = new PhabricatorConfigStackSource();
+ self::$sourceStack = $stack;
+
+ $stack->pushSource(
+ id(new PhabricatorConfigDefaultSource())
+ ->setName(pht('Global Default')));
+
+ $env = self::getSelectedEnvironmentName();
+ $stack->pushSource(
+ id(new PhabricatorConfigFileSource($env))
+ ->setName(pht("File '%s'", $env)));
+
+ $stack->pushSource(
+ id(new PhabricatorConfigLocalSource())
+ ->setName(pht("Local Config")));
+ }
+
public static function getSelectedEnvironmentName() {
$env_var = 'PHABRICATOR_ENV';
@@ -398,6 +415,9 @@ final class PhabricatorEnv {
return self::$sourceStack->getAllKeys();
}
+ public static function getConfigSourceStack() {
+ return self::$sourceStack;
+ }
/**
* @task internal
diff --git a/webroot/rsrc/css/application/config/config-options.css b/webroot/rsrc/css/application/config/config-options.css
index ff316bf108..87d54e3202 100644
--- a/webroot/rsrc/css/application/config/config-options.css
+++ b/webroot/rsrc/css/application/config/config-options.css
@@ -2,31 +2,39 @@
* @provides config-options-css
*/
-.config-option-examples {
+.config-option-table {
width: 100%;
border-collapse: collapse;
border: 1px solid #cccccc;
}
-.config-option-examples th,
-.config-option-examples td {
- padding: 4px 6px;
+.config-option-table th,
+.config-option-table td {
+ padding: 4px 12px;
border: 1px solid #cccccc;
}
-.config-option-examples th {
- background: #dfdfdf;
+.config-option-table th {
+ background: #e9e9e9;
text-align: right;
- font-weight: bold;
+ white-space: nowrap;
}
-.config-option-examples th em {
+.config-option-table th em {
font-weight: normal;
color: #666666;
}
-.config-option-examples td {
+.config-option-table td {
+ color: #333333;
+ width: 100%;
+}
+
+.config-option-table .column-labels th {
+ font-weight: bold;
color: #333333;
+ text-align: center;
+ background: #e0e0e0;
}