Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/config/check/PhabricatorSetupCheckExtraConfig.php b/src/applications/config/check/PhabricatorSetupCheckExtraConfig.php
index 22038e7cf6..44455cb203 100644
--- a/src/applications/config/check/PhabricatorSetupCheckExtraConfig.php
+++ b/src/applications/config/check/PhabricatorSetupCheckExtraConfig.php
@@ -1,32 +1,146 @@
<?php
final class PhabricatorSetupCheckExtraConfig extends PhabricatorSetupCheck {
protected function executeChecks() {
+ $ancient_config = self::getAncientConfig();
+
$all_keys = PhabricatorEnv::getAllConfigKeys();
$all_keys = array_keys($all_keys);
sort($all_keys);
$defined_keys = PhabricatorApplicationConfigOptions::loadAllOptions();
foreach ($all_keys as $key) {
if (isset($defined_keys[$key])) {
continue;
}
- $summary = pht("This option is not recognized. It may be misspelled.");
- $message = pht(
- "The configuration option '%s' is not recognized. It may be ".
- "misspelled, or it might have existed in an older version of ".
- "Phabricator. It has no effect, and should be corrected or deleted.",
- $key);
-
- $this
- ->newIssue('config.unknown.'.$key)
- ->setShortName(pht('Unknown Config'))
- ->setName(pht('Unknown Configuration Option "%s"', $key))
- ->setSummary($summary)
- ->setMessage($message)
- ->addPhabricatorConfig($key);
+
+ if (isset($ancient_config[$key])) {
+ $summary = pht(
+ 'This option has been removed. You may delete it at your '.
+ 'convenience.');
+ $message = pht(
+ "The configuration option '%s' has been removed. You may delete ".
+ "it at your convenience.".
+ "\n\n%s",
+ $key,
+ $ancient_config[$key]);
+ $short = pht('Obsolete Config');
+ $name = pht('Obsolete Configuration Option "%s"', $key);
+ } else {
+ $summary = pht("This option is not recognized. It may be misspelled.");
+ $message = pht(
+ "The configuration option '%s' is not recognized. It may be ".
+ "misspelled, or it might have existed in an older version of ".
+ "Phabricator. It has no effect, and should be corrected or deleted.",
+ $key);
+ $short = pht('Unknown Config');
+ $name = pht('Unknown Configuration Option "%s"', $key);
+ }
+
+ $issue = $this->newIssue('config.unknown.'.$key)
+ ->setShortName($short)
+ ->setName($name)
+ ->setSummary($summary);
+
+ $stack = PhabricatorEnv::getConfigSourceStack();
+ $stack = $stack->getStack();
+
+ $found = array();
+ $found_local = false;
+ $found_database = false;
+
+ foreach ($stack as $source_key => $source) {
+ $value = $source->getKeys(array($key));
+ if ($value) {
+ $found[] = $source->getName();
+ if ($source instanceof PhabricatorConfigDatabaseSource) {
+ $found_database = true;
+ }
+ if ($source instanceof PhabricatorConfigLocalSource) {
+ $found_local = true;
+ }
+ }
+ }
+
+ $message = $message."\n\n".pht(
+ "This configuration value is defined in in these %d ".
+ "configuration source(s): %s.",
+ count($found),
+ implode(', ', $found));
+ $issue->setMessage($message);
+
+ if ($found_local) {
+ $command = csprintf('phabricator/ $ ./bin/config delete %s', $key);
+ $issue->addCommand($command);
+ }
+
+ if ($found_database) {
+ $issue->addPhabricatorConfig($key);
+ }
}
}
+
+ /**
+ * Return a map of deleted config options. Keys are option keys; values are
+ * explanations of what happened to the option.
+ */
+ public static function getAncientConfig() {
+ $reason_auth = pht(
+ 'This option has been migrated to the "Auth" application. Your old '.
+ 'configuration is still in effect, but now stored in "Auth" instead of '.
+ 'configuration. Going forward, you can manage authentication from '.
+ 'the web UI.');
+
+ $auth_config = array(
+ 'controller.oauth-registration',
+ 'auth.password-auth-enabled',
+ 'facebook.auth-enabled',
+ 'facebook.registration-enabled',
+ 'facebook.auth-permanent',
+ 'facebook.application-id',
+ 'facebook.application-secret',
+ 'facebook.require-https-auth',
+ 'github.auth-enabled',
+ 'github.registration-enabled',
+ 'github.auth-permanent',
+ 'github.application-id',
+ 'github.application-secret',
+ 'google.auth-enabled',
+ 'google.registration-enabled',
+ 'google.auth-permanent',
+ 'google.application-id',
+ 'google.application-secret',
+ 'ldap.auth-enabled',
+ 'ldap.hostname',
+ 'ldap.port',
+ 'ldap.base_dn',
+ 'ldap.search_attribute',
+ 'ldap.search-first',
+ 'ldap.username-attribute',
+ 'ldap.real_name_attributes',
+ 'ldap.activedirectory_domain',
+ 'ldap.version',
+ 'ldap.referrals',
+ 'ldap.anonymous-user-name',
+ 'ldap.anonymous-user-password',
+ 'ldap.start-tls',
+ 'disqus.auth-enabled',
+ 'disqus.registration-enabled',
+ 'disqus.auth-permanent',
+ 'disqus.application-id',
+ 'disqus.application-secret',
+ 'phabricator.oauth-uri',
+ 'phabricator.auth-enabled',
+ 'phabricator.registration-enabled',
+ 'phabricator.auth-permanent',
+ 'phabricator.application-id',
+ 'phabricator.application-secret',
+ );
+
+ $ancient_config = array_fill_keys($auth_config, $reason_auth);
+
+ return $ancient_config;
+ }
}
diff --git a/src/applications/config/controller/PhabricatorConfigEditController.php b/src/applications/config/controller/PhabricatorConfigEditController.php
index 1dcfc3796f..fcc73511fd 100644
--- a/src/applications/config/controller/PhabricatorConfigEditController.php
+++ b/src/applications/config/controller/PhabricatorConfigEditController.php
@@ -1,516 +1,511 @@
<?php
final class PhabricatorConfigEditController
extends PhabricatorConfigController {
private $key;
public function willProcessRequest(array $data) {
$this->key = $data['key'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$options = PhabricatorApplicationConfigOptions::loadAllOptions();
if (empty($options[$this->key])) {
+ $ancient = PhabricatorSetupCheckExtraConfig::getAncientConfig();
+ if (isset($ancient[$this->key])) {
+ $desc = pht(
+ "This configuration has been removed. You can safely delete ".
+ "it.\n\n%s",
+ $ancient[$this->key]);
+ } else {
+ $desc = pht(
+ "This configuration option is unknown. It may be misspelled, ".
+ "or have existed in a previous version of Phabricator.");
+ }
+
// This may be a dead config entry, which existed in the past but no
// longer exists. Allow it to be edited so it can be reviewed and
// deleted.
$option = id(new PhabricatorConfigOption())
->setKey($this->key)
->setType('wild')
->setDefault(null)
- ->setDescription(
- pht(
- "This configuration option is unknown. It may be misspelled, ".
- "or have existed in a previous version of Phabricator."));
+ ->setDescription($desc);
$group = null;
$group_uri = $this->getApplicationURI();
} else {
$option = $options[$this->key];
$group = $option->getGroup();
$group_uri = $this->getApplicationURI('group/'.$group->getKey().'/');
}
$issue = $request->getStr('issue');
if ($issue) {
// If the user came here from an open setup issue, send them back.
$done_uri = $this->getApplicationURI('issue/'.$issue.'/');
} else {
$done_uri = $group_uri;
}
// Check if the config key is already stored in the database.
// Grab the value if it is.
$config_entry = id(new PhabricatorConfigEntry())
->loadOneWhere(
'configKey = %s AND namespace = %s',
$this->key,
'default');
if (!$config_entry) {
$config_entry = id(new PhabricatorConfigEntry())
->setConfigKey($this->key)
->setNamespace('default')
->setIsDeleted(true);
}
$e_value = null;
$errors = array();
if ($request->isFormPost() && !$option->getLocked()) {
$result = $this->readRequest(
$option,
$request);
list($e_value, $value_errors, $display_value, $xaction) = $result;
$errors = array_merge($errors, $value_errors);
if (!$errors) {
$editor = id(new PhabricatorConfigEditor())
->setActor($user)
->setContinueOnNoEffect(true)
->setContentSourceFromRequest($request);
try {
$editor->applyTransactions($config_entry, array($xaction));
return id(new AphrontRedirectResponse())->setURI($done_uri);
} catch (PhabricatorConfigValidationException $ex) {
$e_value = pht('Invalid');
$errors[] = $ex->getMessage();
}
}
} else {
$display_value = $this->getDisplayValue($option, $config_entry);
}
$form = new AphrontFormView();
$form->setFlexible(true);
$error_view = null;
if ($errors) {
$error_view = id(new AphrontErrorView())
->setTitle(pht('You broke everything!'))
->setErrors($errors);
} else if ($option->getHidden()) {
$msg = pht(
"This configuration is hidden and can not be edited or viewed from ".
"the web interface.");
$error_view = id(new AphrontErrorView())
->setTitle(pht('Configuration Hidden'))
->setSeverity(AphrontErrorView::SEVERITY_WARNING)
->appendChild(phutil_tag('p', array(), $msg));
} else if ($option->getLocked()) {
$msg = pht(
"This configuration is locked and can not be edited from the web ".
"interface.");
$error_view = id(new AphrontErrorView())
->setTitle(pht('Configuration Locked'))
->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
->appendChild(phutil_tag('p', array(), $msg));
}
if ($option->getHidden()) {
$control = null;
} else {
$control = $this->renderControl(
$option,
$display_value,
$e_value);
}
$engine = new PhabricatorMarkupEngine();
$engine->setViewer($user);
$engine->addObject($option, 'description');
$engine->process();
$description = phutil_tag(
'div',
array(
'class' => 'phabricator-remarkup',
),
$engine->getOutput($option, 'description'));
$form
->setUser($user)
->addHiddenInput('issue', $request->getStr('issue'))
->appendChild(
id(new AphrontFormMarkupControl())
->setLabel(pht('Description'))
->setValue($description))
->appendChild($control);
$submit_control = id(new AphrontFormSubmitControl())
->addCancelButton($done_uri);
if (!$option->getLocked()) {
$submit_control->setValue(pht('Save Config Entry'));
}
$form->appendChild($submit_control);
$examples = $this->renderExamples($option);
if ($examples) {
$form->appendChild(
id(new AphrontFormMarkupControl())
->setLabel(pht('Examples'))
->setValue($examples));
}
if (!$option->getHidden()) {
$form->appendChild(
id(new AphrontFormMarkupControl())
->setLabel(pht('Default'))
->setValue($this->renderDefaults($option)));
}
$title = pht('Edit %s', $this->key);
$short = pht('Edit');
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setName(pht('Config'))
->setHref($this->getApplicationURI()));
if ($group) {
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setName($group->getName())
->setHref($group_uri));
}
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setName($this->key)
->setHref('/config/edit/'.$this->key));
$xactions = id(new PhabricatorConfigTransactionQuery())
->withObjectPHIDs(array($config_entry->getPHID()))
->setViewer($user)
->execute();
$xaction_view = id(new PhabricatorApplicationTransactionView())
->setUser($user)
->setTransactions($xactions);
return $this->buildApplicationPage(
array(
$crumbs,
id(new PhabricatorHeaderView())->setHeader($title),
$error_view,
$form,
$xaction_view,
),
array(
'title' => $title,
'device' => true,
));
}
private function readRequest(
PhabricatorConfigOption $option,
AphrontRequest $request) {
$xaction = new PhabricatorConfigTransaction();
$xaction->setTransactionType(PhabricatorConfigTransaction::TYPE_EDIT);
$e_value = null;
$errors = array();
$value = $request->getStr('value');
if (!strlen($value)) {
$value = null;
$xaction->setNewValue(
array(
'deleted' => true,
'value' => null,
));
return array($e_value, $errors, $value, $xaction);
}
if ($option->isCustomType()) {
$info = $option->getCustomObject()->readRequest($option, $request);
list($e_value, $errors, $set_value, $value) = $info;
} else {
$type = $option->getType();
$set_value = null;
switch ($type) {
case 'int':
if (preg_match('/^-?[0-9]+$/', trim($value))) {
$set_value = (int)$value;
} else {
$e_value = pht('Invalid');
$errors[] = pht('Value must be an integer.');
}
break;
case 'string':
case 'enum':
$set_value = (string)$value;
break;
case 'list<string>':
$set_value = $request->getStrList('value');
break;
case 'set':
$set_value = array_fill_keys($request->getStrList('value'), true);
break;
case 'bool':
switch ($value) {
case 'true':
$set_value = true;
break;
case 'false':
$set_value = false;
break;
default:
$e_value = pht('Invalid');
$errors[] = pht('Value must be boolean, "true" or "false".');
break;
}
break;
case 'class':
if (!class_exists($value)) {
$e_value = pht('Invalid');
$errors[] = pht('Class does not exist.');
} else {
$base = $option->getBaseClass();
if (!is_subclass_of($value, $base)) {
$e_value = pht('Invalid');
$errors[] = pht('Class is not of valid type.');
} else {
$set_value = $value;
}
}
break;
default:
$json = json_decode($value, true);
if ($json === null && strtolower($value) != 'null') {
$e_value = pht('Invalid');
$errors[] = pht(
'The given value must be valid JSON. This means, among '.
'other things, that you must wrap strings in double-quotes.');
} else {
$set_value = $json;
}
break;
}
}
if (!$errors) {
$xaction->setNewValue(
array(
'deleted' => false,
'value' => $set_value,
));
} else {
$xaction = null;
}
return array($e_value, $errors, $value, $xaction);
}
private function getDisplayValue(
PhabricatorConfigOption $option,
PhabricatorConfigEntry $entry) {
if ($entry->getIsDeleted()) {
return null;
}
if ($option->isCustomType()) {
return $option->getCustomObject()->getDisplayValue($option, $entry);
} else {
$type = $option->getType();
$value = $entry->getValue();
switch ($type) {
case 'int':
case 'string':
case 'enum':
case 'class':
return $value;
case 'bool':
return $value ? 'true' : 'false';
case 'list<string>':
return implode("\n", nonempty($value, array()));
case 'set':
return implode("\n", nonempty(array_keys($value), array()));
default:
return PhabricatorConfigJSON::prettyPrintJSON($value);
}
}
}
private function renderControl(
PhabricatorConfigOption $option,
$display_value,
$e_value) {
if ($option->isCustomType()) {
$control = $option->getCustomObject()->renderControl(
$option,
$display_value,
$e_value);
} else {
$type = $option->getType();
switch ($type) {
case 'int':
case 'string':
$control = id(new AphrontFormTextControl());
break;
case 'bool':
$control = id(new AphrontFormSelectControl())
->setOptions(
array(
'' => pht('(Use Default)'),
'true' => idx($option->getBoolOptions(), 0),
'false' => idx($option->getBoolOptions(), 1),
));
break;
case 'enum':
$options = array_mergev(
array(
array('' => pht('(Use Default)')),
$option->getEnumOptions(),
));
$control = id(new AphrontFormSelectControl())
->setOptions($options);
break;
case 'class':
$symbols = id(new PhutilSymbolLoader())
->setType('class')
->setAncestorClass($option->getBaseClass())
->setConcreteOnly(true)
->selectSymbolsWithoutLoading();
$names = ipull($symbols, 'name', 'name');
asort($names);
$names = array(
'' => pht('(Use Default)'),
) + $names;
$control = id(new AphrontFormSelectControl())
->setOptions($names);
break;
case 'list<string>':
case 'set':
$control = id(new AphrontFormTextAreaControl())
->setCaption(pht('Separate values with newlines or commas.'));
break;
default:
$control = id(new AphrontFormTextAreaControl())
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
->setCustomClass('PhabricatorMonospaced')
->setCaption(pht('Enter value in JSON.'));
break;
}
$control
->setLabel(pht('Value'))
->setError($e_value)
->setValue($display_value)
->setName('value');
}
if ($option->getLocked()) {
$control->setDisabled(true);
}
return $control;
}
private function renderExamples(PhabricatorConfigOption $option) {
$examples = $option->getExamples();
if (!$examples) {
return null;
}
$table = array();
$table[] = hsprintf(
'<tr class="column-labels"><th>%s</th><th>%s</th></tr>',
pht('Example'),
pht('Value'));
foreach ($examples as $example) {
list($value, $description) = $example;
if ($value === null) {
$value = phutil_tag('em', array(), pht('(empty)'));
} else {
$value = phutil_escape_html_newlines($value);
}
$table[] = hsprintf(
'<tr><th>%s</th><td>%s</td></tr>',
$description,
$value);
}
require_celerity_resource('config-options-css');
return phutil_tag(
'table',
array(
'class' => 'config-option-table',
),
$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[] = hsprintf(
'<tr class="column-labels"><th>%s</th><th>%s</th></tr>',
pht('Source'),
pht('Value'));
foreach ($stack as $key => $source) {
$value = $source->getKeys(
array(
$option->getKey(),
));
if (!array_key_exists($option->getKey(), $value)) {
$value = phutil_tag('em', array(), pht('(empty)'));
} else {
$value = PhabricatorConfigJSON::prettyPrintJSON(
$value[$option->getKey()]);
}
$table[] = hsprintf(
'<tr><th>%s</th><td>%s</td></tr>',
$source->getName(),
$value);
}
require_celerity_resource('config-options-css');
return phutil_tag(
'table',
array(
'class' => 'config-option-table',
),
$table);
}
}
diff --git a/src/applications/config/management/PhabricatorConfigManagementDeleteWorkflow.php b/src/applications/config/management/PhabricatorConfigManagementDeleteWorkflow.php
index d765b5ffe9..cf1f05be74 100644
--- a/src/applications/config/management/PhabricatorConfigManagementDeleteWorkflow.php
+++ b/src/applications/config/management/PhabricatorConfigManagementDeleteWorkflow.php
@@ -1,56 +1,49 @@
<?php
final class PhabricatorConfigManagementDeleteWorkflow
extends PhabricatorConfigManagementWorkflow {
protected function didConstruct() {
$this
->setName('delete')
->setExamples('**delete** __key__')
->setSynopsis('Delete a local configuration value.')
->setArguments(
array(
array(
'name' => 'args',
'wildcard' => true,
),
));
}
public function execute(PhutilArgumentParser $args) {
$console = PhutilConsole::getConsole();
$argv = $args->getArg('args');
if (count($argv) == 0) {
throw new PhutilArgumentUsageException(
"Specify a configuration key to delete.");
}
$key = $argv[0];
if (count($argv) > 1) {
throw new PhutilArgumentUsageException(
"Too many arguments: expected one key.");
}
- $options = PhabricatorApplicationConfigOptions::loadAllOptions();
- if (empty($options[$key])) {
- throw new PhutilArgumentUsageException(
- "No such configuration key '{$key}'! Use `config list` to list all ".
- "keys.");
- }
-
$config = new PhabricatorConfigLocalSource();
$values = $config->getKeys(array($key));
if (!$values) {
throw new PhutilArgumentUsageException(
"Configuration key '{$key}' is not set in local configuration!");
}
$config->deleteKeys(array($key));
$console->writeOut(
pht("Deleted '%s' from local configuration.", $key)."\n");
}
}
diff --git a/src/applications/config/view/PhabricatorSetupIssueView.php b/src/applications/config/view/PhabricatorSetupIssueView.php
index 5736c66c43..ffa21ecd40 100644
--- a/src/applications/config/view/PhabricatorSetupIssueView.php
+++ b/src/applications/config/view/PhabricatorSetupIssueView.php
@@ -1,360 +1,360 @@
<?php
final class PhabricatorSetupIssueView extends AphrontView {
private $issue;
public function setIssue(PhabricatorSetupIssue $issue) {
$this->issue = $issue;
return $this;
}
public function getIssue() {
return $this->issue;
}
public function render() {
$issue = $this->getIssue();
$description = array();
$description[] = phutil_tag(
'div',
array(
'class' => 'setup-issue-instructions',
),
phutil_escape_html_newlines($issue->getMessage()));
$configs = $issue->getPHPConfig();
if ($configs) {
$description[] = $this->renderPHPConfig($configs);
}
$configs = $issue->getPhabricatorConfig();
if ($configs) {
$description[] = $this->renderPhabricatorConfig($configs);
}
$related_configs = $issue->getRelatedPhabricatorConfig();
if ($related_configs) {
$description[] = $this->renderPhabricatorConfig($related_configs,
$related = true);
}
$commands = $issue->getCommands();
if ($commands) {
$run_these = pht("Run these %d command(s):", count($commands));
$description[] = phutil_tag(
'div',
array(
'class' => 'setup-issue-config',
),
array(
phutil_tag('p', array(), $run_these),
phutil_tag('pre', array(), phutil_implode_html("\n", $commands)),
));
}
$extensions = $issue->getPHPExtensions();
if ($extensions) {
$install_these = pht(
"Install these %d PHP extension(s):", count($extensions));
$install_info = pht(
"You can usually install a PHP extension using %s or %s. Common ".
"package names are %s or %s. Try commands like these:",
phutil_tag('tt', array(), 'apt-get'),
phutil_tag('tt', array(), 'yum'),
hsprintf('<tt>php-<em>%s</em></tt>', pht('extname')),
hsprintf('<tt>php5-<em>%s</em></tt>', pht('extname')));
// TODO: We should do a better job of detecting how to install extensions
// on the current system.
$install_commands = hsprintf(
"\$ sudo apt-get install php5-<em>extname</em> ".
"# Debian / Ubuntu\n".
"\$ sudo yum install php-<em>extname</em> ".
"# Red Hat / Derivatives");
$fallback_info = pht(
"If those commands don't work, try Google. The process of installing ".
"PHP extensions is not specific to Phabricator, and any instructions ".
"you can find for installing them on your system should work. On Mac ".
"OS X, you might want to try Homebrew.");
$restart_info = pht(
"After installing new PHP extensions, <strong>restart your webserver ".
"for the changes to take effect</strong>.",
hsprintf(''));
$description[] = phutil_tag(
'div',
array(
'class' => 'setup-issue-config',
),
array(
phutil_tag('p', array(), $install_these),
phutil_tag('pre', array(), implode("\n", $extensions)),
phutil_tag('p', array(), $install_info),
phutil_tag('pre', array(), $install_commands),
phutil_tag('p', array(), $fallback_info),
phutil_tag('p', array(), $restart_info),
));
}
$next = phutil_tag(
'div',
array(
'class' => 'setup-issue-next',
),
pht('To continue, resolve this problem and reload the page.'));
$name = phutil_tag(
'div',
array(
'class' => 'setup-issue-name',
),
$issue->getName());
return phutil_tag(
'div',
array(
'class' => 'setup-issue',
),
array(
$name,
$description,
$next,
));
}
private function renderPhabricatorConfig(array $configs, $related = false) {
$issue = $this->getIssue();
$table_info = phutil_tag(
'p',
array(),
pht(
"The current Phabricator configuration has these %d value(s):",
count($configs)));
$options = PhabricatorApplicationConfigOptions::loadAllOptions();
$hidden = array();
foreach ($options as $key => $option) {
if ($option->getHidden()) {
$hidden[$key] = true;
}
}
$table = null;
$dict = array();
foreach ($configs as $key) {
if (isset($hidden[$key])) {
$dict[$key] = null;
} else {
$dict[$key] = PhabricatorEnv::getUnrepairedEnvConfig($key);
}
}
$table = $this->renderValueTable($dict, $hidden);
if ($this->getIssue()->getIsFatal()) {
$update_info = phutil_tag(
'p',
array(),
pht(
"To update these %d value(s), run these command(s) from the command ".
"line:",
count($configs)));
$update = array();
foreach ($configs as $key) {
$update[] = hsprintf(
'<tt>phabricator/ $</tt> ./bin/config set %s <em>value</em>',
$key);
}
$update = phutil_tag('pre', array(), phutil_implode_html("\n", $update));
} else {
$update = array();
foreach ($configs as $config) {
- if (!idx($options, $config) || $options[$config]->getLocked()) {
+ if (idx($options, $config) && $options[$config]->getLocked()) {
continue;
}
$link = phutil_tag(
'a',
array(
'href' => '/config/edit/'.$config.'/?issue='.$issue->getIssueKey(),
),
pht('Edit %s', $config));
$update[] = phutil_tag('li', array(), $link);
}
if ($update) {
$update = phutil_tag('ul', array(), $update);
if (!$related) {
$update_info = phutil_tag(
'p',
array(),
pht("You can update these %d value(s) here:", count($configs)));
} else {
$update_info = phutil_tag(
'p',
array(),
pht("These %d configuration value(s) are related:", count($configs)));
}
} else {
$update = null;
$update_info = null;
}
}
return phutil_tag(
'div',
array(
'class' => 'setup-issue-config',
),
array(
$table_info,
$table,
$update_info,
$update,
));
}
private function renderPHPConfig(array $configs) {
$table_info = phutil_tag(
'p',
array(),
pht(
"The current PHP configuration has these %d value(s):",
count($configs)));
$dict = array();
foreach ($configs as $key) {
$dict[$key] = ini_get($key);
}
$table = $this->renderValueTable($dict);
ob_start();
phpinfo();
$phpinfo = ob_get_clean();
$rex = '@Loaded Configuration File\s*</td><td class="v">(.*?)</td>@i';
$matches = null;
$ini_loc = null;
if (preg_match($rex, $phpinfo, $matches)) {
$ini_loc = trim($matches[1]);
}
$rex = '@Additional \.ini files parsed\s*</td><td class="v">(.*?)</td>@i';
$more_loc = array();
if (preg_match($rex, $phpinfo, $matches)) {
$more_loc = trim($matches[1]);
if ($more_loc == '(none)') {
$more_loc = array();
} else {
$more_loc = preg_split('/\s*,\s*/', $more_loc);
}
}
$info = array();
if (!$ini_loc) {
$info[] = phutil_tag(
'p',
array(),
pht(
"To update these %d value(s), edit your PHP configuration file.",
count($configs)));
} else {
$info[] = phutil_tag(
'p',
array(),
pht(
"To update these %d value(s), edit your PHP configuration file, ".
"located here:",
count($configs)));
$info[] = phutil_tag(
'pre',
array(),
$ini_loc);
}
if ($more_loc) {
$info[] = phutil_tag(
'p',
array(),
pht(
"PHP also loaded these configuration file(s):",
count($more_loc)));
$info[] = phutil_tag(
'pre',
array(),
implode("\n", $more_loc));
}
$info[] = phutil_tag(
'p',
array(),
pht(
'You can find more information about PHP configuration values in the '.
'<a href="%s">PHP Documentation</a>.',
'http://php.net/manual/ini.list.php',
hsprintf('')));
$info[] = phutil_tag(
'p',
array(),
pht(
"After editing the PHP configuration, <strong>restart your ".
"webserver for the changes to take effect</strong>.",
hsprintf('')));
return phutil_tag(
'div',
array(
'class' => 'setup-issue-config',
),
array(
$table_info,
$table,
$info,
));
}
private function renderValueTable(array $dict, array $hidden = array()) {
$rows = array();
foreach ($dict as $key => $value) {
if (isset($hidden[$key])) {
$value = phutil_tag('em', array(), 'hidden');
} else {
$value = $this->renderValueForDisplay($value);
}
$cols = array(
phutil_tag('th', array(), $key),
phutil_tag('td', array(), $value),
);
$rows[] = phutil_tag('tr', array(), $cols);
}
return phutil_tag('table', array(), $rows);
}
private function renderValueForDisplay($value) {
if ($value === null) {
return phutil_tag('em', array(), 'null');
} else if ($value === false) {
return phutil_tag('em', array(), 'false');
} else if ($value === true) {
return phutil_tag('em', array(), 'true');
} else if ($value === '') {
return phutil_tag('em', array(), 'empty string');
} else {
return PhabricatorConfigJSON::prettyPrintJSON($value);
}
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Apr 29, 4:36 PM (22 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
108453
Default Alt Text
(32 KB)

Event Timeline