3 * Config file generator
6 declare(strict_types
=1);
8 namespace PhpMyAdmin\Setup
;
10 use PhpMyAdmin\Config\ConfigFile
;
11 use PhpMyAdmin\Version
;
13 use function array_is_list
;
14 use function array_keys
;
18 use function is_array
;
19 use function is_string
;
20 use function mb_strlen
;
21 use function preg_replace
;
22 use function sodium_bin2hex
;
23 use function sodium_crypto_secretbox_keygen
;
25 use function str_contains
;
27 use function var_export
;
29 use const DATE_RFC1123
;
30 use const SODIUM_CRYPTO_SECRETBOX_KEYBYTES
;
33 * Config file generation class
40 * @param ConfigFile $cf Config file instance
42 public static function getConfigFile(ConfigFile
$cf): string
44 $eol = isset($_SESSION['eol']) && $_SESSION['eol'] === 'win' ?
"\r\n" : "\n";
45 $conf = $cf->getConfig();
50 . ' * Generated configuration file' . $eol
51 . ' * Generated by: phpMyAdmin '
53 . ' setup script' . $eol
54 . ' * Date: ' . gmdate(DATE_RFC1123
) . $eol
55 . ' */' . $eol . $eol;
58 if (! empty($conf['Servers'])) {
59 $ret .= self
::getServerPart($cf, $eol, $conf['Servers']);
60 unset($conf['Servers']);
64 $persistKeys = $cf->getPersistKeysMap();
66 foreach ($conf as $k => $v) {
67 $k = preg_replace('/[^A-Za-z0-9_]/', '_', (string) $k);
68 $ret .= self
::getVarExport($k, $v, $eol);
69 if (! isset($persistKeys[$k])) {
73 unset($persistKeys[$k]);
76 // keep 1d array keys which are present in $persist_keys (config.values.php)
77 foreach (array_keys($persistKeys) as $k) {
78 if (str_contains($k, '/')) {
82 $k = preg_replace('/[^A-Za-z0-9_]/', '_', $k);
83 $ret .= self
::getVarExport($k, $cf->getDefault($k), $eol);
90 * Returns exported configuration variable
92 * @param string $varName configuration name
93 * @param mixed $varValue configuration value(s)
94 * @param string $eol line ending
96 private static function getVarExport(string $varName, mixed $varValue, string $eol): string
98 if ($varName === 'blowfish_secret') {
99 $secret = self
::getBlowfishSecretKey($varValue);
101 return sprintf('$cfg[\'blowfish_secret\'] = \sodium_hex2bin(\'%s\');%s', sodium_bin2hex($secret), $eol);
104 if (! is_array($varValue) ||
$varValue === []) {
105 return "\$cfg['" . $varName . "'] = "
106 . var_export($varValue, true) . ';' . $eol;
109 if (array_is_list($varValue)) {
110 return "\$cfg['" . $varName . "'] = "
111 . self
::exportZeroBasedArray($varValue, $eol)
116 // string keys: $cfg[key][subkey] = value
117 foreach ($varValue as $k => $v) {
118 $k = preg_replace('/[^A-Za-z0-9_]/', '_', $k);
119 $ret .= "\$cfg['" . $varName . "']['" . $k . "'] = "
120 . var_export($v, true) . ';' . $eol;
127 * Exports continuous 0-based array
129 * @param mixed[] $array Array to export
130 * @param string $eol Newline string
132 private static function exportZeroBasedArray(array $array, string $eol): string
135 foreach ($array as $v) {
136 $retv[] = var_export($v, true);
139 if (count($retv) <= 4) {
140 // up to 4 values - one line
141 return '[' . implode(', ', $retv) . ']';
144 // more than 4 values - value per line
145 return '[' . $eol . ' ' . implode(',' . $eol . ' ', $retv) . ']';
149 * Generate server part of config file
151 * @param ConfigFile $cf Config file
152 * @param string $eol Carriage return char
153 * @param mixed[] $servers Servers list
155 protected static function getServerPart(ConfigFile
$cf, string $eol, array $servers): string|
null
157 if ($cf->getServerCount() === 0) {
161 $ret = '/* Servers configuration */' . $eol . '$i = 0;' . $eol . $eol;
162 foreach ($servers as $id => $server) {
163 $ret .= '/* Server: '
164 . strtr($cf->getServerName($id) . ' [' . $id . '] ', '*/', '-')
167 foreach ($server as $k => $v) {
168 $k = preg_replace('/[^A-Za-z0-9_]/', '_', (string) $k);
169 $ret .= "\$cfg['Servers'][\$i]['" . $k . "'] = "
170 . (is_array($v) && array_is_list($v)
171 ? self
::exportZeroBasedArray($v, $eol)
172 : var_export($v, true))
179 $ret .= '/* End of servers configuration */' . $eol . $eol;
184 /** @psalm-return non-empty-string */
185 private static function getBlowfishSecretKey(mixed $key): string
187 if (is_string($key) && mb_strlen($key, '8bit') === SODIUM_CRYPTO_SECRETBOX_KEYBYTES
) {
191 return sodium_crypto_secretbox_keygen();