@@ -2328,7 +2326,6 @@
@@ -2350,7 +2346,6 @@
@@ -2372,7 +2366,6 @@
@@ -2394,7 +2386,6 @@
@@ -2453,7 +2443,6 @@
@@ -2475,7 +2463,6 @@
@@ -3014,21 +3000,28 @@
-
get('PMA_IS_WINDOWS')]]>
+ config->get('PMA_IS_WINDOWS')]]>
-
+
+
+
-
@@ -14688,11 +14680,6 @@
-
diff --git a/psalm.xml b/psalm.xml
index a1b5ac3433..c3a7ff0cd8 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -49,7 +49,6 @@
complete_query: string,
compression: 'none'|'zip'|'gzip',
conn_error: string,
- ConfigFile: PhpMyAdmin\Config\ConfigFile,
csv_columns: bool,
csv_enclosed: string,
csv_escaped: string,
diff --git a/src/Config/PageSettings.php b/src/Config/PageSettings.php
index c8e99d3602..540f1e6dc7 100644
--- a/src/Config/PageSettings.php
+++ b/src/Config/PageSettings.php
@@ -65,15 +65,15 @@ class PageSettings
$this->groupName = $formGroupName;
- $cf = new ConfigFile(Config::getInstance()->baseSettings);
- $this->userPreferences->pageInit($cf);
+ $configFile = new ConfigFile(Config::getInstance()->baseSettings);
+ $this->userPreferences->pageInit($configFile);
- $formDisplay = new $formClass($cf);
+ $formDisplay = new $formClass($configFile);
// Process form
$error = null;
if (isset($_POST['submit_save']) && $_POST['submit_save'] == $formGroupName) {
- $error = $this->processPageSettings($formDisplay, $cf);
+ $error = $this->processPageSettings($formDisplay, $configFile);
}
// Display forms
diff --git a/src/Controllers/Preferences/ExportController.php b/src/Controllers/Preferences/ExportController.php
index 8069ef17ab..3225c85022 100644
--- a/src/Controllers/Preferences/ExportController.php
+++ b/src/Controllers/Preferences/ExportController.php
@@ -35,15 +35,14 @@ final class ExportController implements InvocableController
public function __invoke(ServerRequest $request): Response|null
{
- $GLOBALS['cf'] ??= null;
$GLOBALS['error'] ??= null;
$GLOBALS['tabHash'] ??= null;
$GLOBALS['hash'] ??= null;
- $GLOBALS['cf'] = new ConfigFile($this->config->baseSettings);
- $this->userPreferences->pageInit($GLOBALS['cf']);
+ $configFile = new ConfigFile($this->config->baseSettings);
+ $this->userPreferences->pageInit($configFile);
- $formDisplay = new ExportForm($GLOBALS['cf'], 1);
+ $formDisplay = new ExportForm($configFile, 1);
if ($request->hasBodyParam('revert')) {
// revert erroneous fields to their default values
@@ -58,7 +57,7 @@ final class ExportController implements InvocableController
// Load 2FA settings
$twoFactor = new TwoFactor(Config::getInstance()->selectedServer['user']);
// save settings
- $result = $this->userPreferences->save($GLOBALS['cf']->getConfigArray());
+ $result = $this->userPreferences->save($configFile->getConfigArray());
// save back the 2FA setting only
$twoFactor->save();
if ($result === true) {
diff --git a/src/Controllers/Preferences/FeaturesController.php b/src/Controllers/Preferences/FeaturesController.php
index f7b7f6b39d..354224386b 100644
--- a/src/Controllers/Preferences/FeaturesController.php
+++ b/src/Controllers/Preferences/FeaturesController.php
@@ -35,15 +35,14 @@ final class FeaturesController implements InvocableController
public function __invoke(ServerRequest $request): Response|null
{
- $GLOBALS['cf'] ??= null;
$GLOBALS['error'] ??= null;
$GLOBALS['tabHash'] ??= null;
$GLOBALS['hash'] ??= null;
- $GLOBALS['cf'] = new ConfigFile($this->config->baseSettings);
- $this->userPreferences->pageInit($GLOBALS['cf']);
+ $configFile = new ConfigFile($this->config->baseSettings);
+ $this->userPreferences->pageInit($configFile);
- $formDisplay = new FeaturesForm($GLOBALS['cf'], 1);
+ $formDisplay = new FeaturesForm($configFile, 1);
if ($request->hasBodyParam('revert')) {
// revert erroneous fields to their default values
@@ -58,7 +57,7 @@ final class FeaturesController implements InvocableController
// Load 2FA settings
$twoFactor = new TwoFactor(Config::getInstance()->selectedServer['user']);
// save settings
- $result = $this->userPreferences->save($GLOBALS['cf']->getConfigArray());
+ $result = $this->userPreferences->save($configFile->getConfigArray());
// save back the 2FA setting only
$twoFactor->save();
if ($result === true) {
diff --git a/src/Controllers/Preferences/ImportController.php b/src/Controllers/Preferences/ImportController.php
index 08d9ca992c..3da6a9ac11 100644
--- a/src/Controllers/Preferences/ImportController.php
+++ b/src/Controllers/Preferences/ImportController.php
@@ -35,15 +35,14 @@ final class ImportController implements InvocableController
public function __invoke(ServerRequest $request): Response|null
{
- $GLOBALS['cf'] ??= null;
$GLOBALS['error'] ??= null;
$GLOBALS['tabHash'] ??= null;
$GLOBALS['hash'] ??= null;
- $GLOBALS['cf'] = new ConfigFile($this->config->baseSettings);
- $this->userPreferences->pageInit($GLOBALS['cf']);
+ $configFile = new ConfigFile($this->config->baseSettings);
+ $this->userPreferences->pageInit($configFile);
- $formDisplay = new ImportForm($GLOBALS['cf'], 1);
+ $formDisplay = new ImportForm($configFile, 1);
if ($request->hasBodyParam('revert')) {
// revert erroneous fields to their default values
@@ -58,7 +57,7 @@ final class ImportController implements InvocableController
// Load 2FA settings
$twoFactor = new TwoFactor(Config::getInstance()->selectedServer['user']);
// save settings
- $result = $this->userPreferences->save($GLOBALS['cf']->getConfigArray());
+ $result = $this->userPreferences->save($configFile->getConfigArray());
// save back the 2FA setting only
$twoFactor->save();
if ($result === true) {
diff --git a/src/Controllers/Preferences/MainPanelController.php b/src/Controllers/Preferences/MainPanelController.php
index fdc96b7002..6c0ef35ec9 100644
--- a/src/Controllers/Preferences/MainPanelController.php
+++ b/src/Controllers/Preferences/MainPanelController.php
@@ -35,15 +35,14 @@ final class MainPanelController implements InvocableController
public function __invoke(ServerRequest $request): Response|null
{
- $GLOBALS['cf'] ??= null;
$GLOBALS['error'] ??= null;
$GLOBALS['tabHash'] ??= null;
$GLOBALS['hash'] ??= null;
- $GLOBALS['cf'] = new ConfigFile($this->config->baseSettings);
- $this->userPreferences->pageInit($GLOBALS['cf']);
+ $configFile = new ConfigFile($this->config->baseSettings);
+ $this->userPreferences->pageInit($configFile);
- $formDisplay = new MainForm($GLOBALS['cf'], 1);
+ $formDisplay = new MainForm($configFile, 1);
if ($request->hasBodyParam('revert')) {
// revert erroneous fields to their default values
@@ -58,7 +57,7 @@ final class MainPanelController implements InvocableController
// Load 2FA settings
$twoFactor = new TwoFactor(Config::getInstance()->selectedServer['user']);
// save settings
- $result = $this->userPreferences->save($GLOBALS['cf']->getConfigArray());
+ $result = $this->userPreferences->save($configFile->getConfigArray());
// save back the 2FA setting only
$twoFactor->save();
if ($result === true) {
diff --git a/src/Controllers/Preferences/ManageController.php b/src/Controllers/Preferences/ManageController.php
index fb7878d681..692fff87dc 100644
--- a/src/Controllers/Preferences/ManageController.php
+++ b/src/Controllers/Preferences/ManageController.php
@@ -58,15 +58,14 @@ final class ManageController implements InvocableController
public function __invoke(ServerRequest $request): Response|null
{
- $GLOBALS['cf'] ??= null;
$GLOBALS['error'] ??= null;
$GLOBALS['lang'] ??= null;
$GLOBALS['query'] ??= null;
$route = $request->getRoute();
- $GLOBALS['cf'] = new ConfigFile($this->config->baseSettings);
- $this->userPreferences->pageInit($GLOBALS['cf']);
+ $configFile = new ConfigFile($this->config->baseSettings);
+ $this->userPreferences->pageInit($configFile);
$GLOBALS['error'] = '';
if ($request->hasBodyParam('submit_export') && $request->getParsedBodyParam('export_type') === 'text_file') {
@@ -142,10 +141,10 @@ final class ManageController implements InvocableController
} else {
// sanitize input values: treat them as though
// they came from HTTP POST request
- $formDisplay = new UserFormList($GLOBALS['cf']);
- $newConfig = $GLOBALS['cf']->getFlatDefaultConfig();
+ $formDisplay = new UserFormList($configFile);
+ $newConfig = $configFile->getFlatDefaultConfig();
if ($request->hasBodyParam('import_merge')) {
- $newConfig = array_merge($newConfig, $GLOBALS['cf']->getConfigArray());
+ $newConfig = array_merge($newConfig, $configFile->getConfigArray());
}
$newConfig = array_merge($newConfig, $configuration);
@@ -154,7 +153,7 @@ final class ManageController implements InvocableController
$_POST[str_replace('/', '-', (string) $k)] = $v;
}
- $GLOBALS['cf']->resetConfigData();
+ $configFile->resetConfigData();
$allOk = $formDisplay->process(true, false);
$allOk = $allOk && ! $formDisplay->hasErrors();
$_POST = $postParamBackup;
@@ -200,7 +199,7 @@ final class ManageController implements InvocableController
}
// save settings
- $result = $this->userPreferences->save($GLOBALS['cf']->getConfigArray());
+ $result = $this->userPreferences->save($configFile->getConfigArray());
if ($result === true) {
if ($returnUrl) {
$GLOBALS['query'] = Util::splitURLQuery($returnUrl);
diff --git a/src/Controllers/Preferences/NavigationController.php b/src/Controllers/Preferences/NavigationController.php
index e11b055278..38796c923f 100644
--- a/src/Controllers/Preferences/NavigationController.php
+++ b/src/Controllers/Preferences/NavigationController.php
@@ -35,15 +35,14 @@ final class NavigationController implements InvocableController
public function __invoke(ServerRequest $request): Response|null
{
- $GLOBALS['cf'] ??= null;
$GLOBALS['error'] ??= null;
$GLOBALS['tabHash'] ??= null;
$GLOBALS['hash'] ??= null;
- $GLOBALS['cf'] = new ConfigFile($this->config->baseSettings);
- $this->userPreferences->pageInit($GLOBALS['cf']);
+ $configFile = new ConfigFile($this->config->baseSettings);
+ $this->userPreferences->pageInit($configFile);
- $formDisplay = new NaviForm($GLOBALS['cf'], 1);
+ $formDisplay = new NaviForm($configFile, 1);
if ($request->hasBodyParam('revert')) {
// revert erroneous fields to their default values
@@ -58,7 +57,7 @@ final class NavigationController implements InvocableController
// Load 2FA settings
$twoFactor = new TwoFactor(Config::getInstance()->selectedServer['user']);
// save settings
- $result = $this->userPreferences->save($GLOBALS['cf']->getConfigArray());
+ $result = $this->userPreferences->save($configFile->getConfigArray());
// save back the 2FA setting only
$twoFactor->save();
if ($result === true) {
diff --git a/src/Controllers/Preferences/SqlController.php b/src/Controllers/Preferences/SqlController.php
index f443b730e7..853c0081ed 100644
--- a/src/Controllers/Preferences/SqlController.php
+++ b/src/Controllers/Preferences/SqlController.php
@@ -35,15 +35,14 @@ final class SqlController implements InvocableController
public function __invoke(ServerRequest $request): Response|null
{
- $GLOBALS['cf'] ??= null;
$GLOBALS['error'] ??= null;
$GLOBALS['tabHash'] ??= null;
$GLOBALS['hash'] ??= null;
- $GLOBALS['cf'] = new ConfigFile($this->config->baseSettings);
- $this->userPreferences->pageInit($GLOBALS['cf']);
+ $configFile = new ConfigFile($this->config->baseSettings);
+ $this->userPreferences->pageInit($configFile);
- $formDisplay = new SqlForm($GLOBALS['cf'], 1);
+ $formDisplay = new SqlForm($configFile, 1);
if ($request->hasBodyParam('revert')) {
// revert erroneous fields to their default values
@@ -58,7 +57,7 @@ final class SqlController implements InvocableController
// Load 2FA settings
$twoFactor = new TwoFactor(Config::getInstance()->selectedServer['user']);
// save settings
- $result = $this->userPreferences->save($GLOBALS['cf']->getConfigArray());
+ $result = $this->userPreferences->save($configFile->getConfigArray());
// save back the 2FA setting only
$twoFactor->save();
if ($result === true) {
diff --git a/src/Controllers/Setup/ConfigController.php b/src/Controllers/Setup/ConfigController.php
index 926c500afa..ccab6a2b3f 100644
--- a/src/Controllers/Setup/ConfigController.php
+++ b/src/Controllers/Setup/ConfigController.php
@@ -4,37 +4,79 @@ declare(strict_types=1);
namespace PhpMyAdmin\Controllers\Setup;
+use Fig\Http\Message\StatusCodeInterface;
+use PhpMyAdmin\Config;
+use PhpMyAdmin\Controllers\InvocableController;
+use PhpMyAdmin\Http\Factory\ResponseFactory;
+use PhpMyAdmin\Http\Response;
+use PhpMyAdmin\Http\ServerRequest;
+use PhpMyAdmin\LanguageManager;
+use PhpMyAdmin\ResponseRenderer;
use PhpMyAdmin\Setup\ConfigGenerator;
+use PhpMyAdmin\Setup\SetupHelper;
+use PhpMyAdmin\Template;
+use function __;
+use function file_exists;
use function is_string;
-class ConfigController extends AbstractController
-{
- /**
- * @param mixed[] $params Request parameters
- *
- * @return string HTML
- */
- public function __invoke(array $params): string
- {
- $formset = isset($params['formset']) && is_string($params['formset']) ? $params['formset'] : '';
- $eol = isset($params['eol']) && $params['eol'] === 'win' ? 'win' : 'unix';
+use const CONFIG_FILE;
- $pages = $this->getPages();
+final class ConfigController implements InvocableController
+{
+ public function __construct(
+ private readonly ResponseFactory $responseFactory,
+ private readonly ResponseRenderer $responseRenderer,
+ private readonly Template $template,
+ private readonly Config $config,
+ ) {
+ }
+
+ public function __invoke(ServerRequest $request): Response
+ {
+ if (@file_exists(CONFIG_FILE) && ! $this->config->config->debug->demo) {
+ $response = $this->responseFactory->createResponse(StatusCodeInterface::STATUS_NOT_FOUND);
+
+ return $response->write($this->template->render('error/generic', [
+ 'lang' => $GLOBALS['lang'] ?? 'en',
+ 'dir' => LanguageManager::$textDir,
+ 'error_message' => __('Configuration already exists, setup is disabled!'),
+ ]));
+ }
+
+ $response = $this->responseFactory->createResponse();
+ foreach ($this->responseRenderer->getHeader()->getHttpHeaders() as $name => $value) {
+ $response = $response->withHeader($name, $value);
+ }
+
+ $pages = SetupHelper::getPages();
static $hasCheckPageRefresh = false;
if (! $hasCheckPageRefresh) {
$hasCheckPageRefresh = true;
}
- $config = ConfigGenerator::getConfigFile($this->config);
+ $configFile = SetupHelper::createConfigFile();
- return $this->template->render('setup/config/index', [
- 'formset' => $formset,
+ $config = ConfigGenerator::getConfigFile($configFile);
+
+ return $response->write($this->template->render('setup/config/index', [
+ 'formset' => $this->getFormSetParam($request->getQueryParam('formset')),
'pages' => $pages,
- 'eol' => $eol,
+ 'eol' => $this->getEolParam($request->getQueryParam('eol')),
'config' => $config,
'has_check_page_refresh' => $hasCheckPageRefresh,
- ]);
+ ]));
+ }
+
+ private function getFormSetParam(mixed $formSetParam): string
+ {
+ return is_string($formSetParam) ? $formSetParam : '';
+ }
+
+ /** @psalm-return 'win'|'unix' */
+ private function getEolParam(mixed $eolParam): string
+ {
+ return $eolParam === 'win' ? 'win' : 'unix';
}
}
diff --git a/src/Controllers/Setup/FormController.php b/src/Controllers/Setup/FormController.php
index e21314805e..2a6d211df6 100644
--- a/src/Controllers/Setup/FormController.php
+++ b/src/Controllers/Setup/FormController.php
@@ -4,47 +4,134 @@ declare(strict_types=1);
namespace PhpMyAdmin\Controllers\Setup;
+use Fig\Http\Message\StatusCodeInterface;
+use PhpMyAdmin\Config;
use PhpMyAdmin\Config\Forms\Setup\SetupFormList;
+use PhpMyAdmin\Controllers\InvocableController;
+use PhpMyAdmin\Http\Factory\ResponseFactory;
+use PhpMyAdmin\Http\Response;
+use PhpMyAdmin\Http\ServerRequest;
use PhpMyAdmin\LanguageManager;
-use PhpMyAdmin\Setup\FormProcessing;
+use PhpMyAdmin\ResponseRenderer;
+use PhpMyAdmin\Setup\SetupHelper;
+use PhpMyAdmin\Template;
+use PhpMyAdmin\Url;
use function __;
+use function file_exists;
+use function in_array;
+use function is_numeric;
use function is_string;
-use function ob_get_clean;
-use function ob_start;
-class FormController extends AbstractController
+use const CONFIG_FILE;
+
+final class FormController implements InvocableController
{
- /**
- * @param mixed[] $params Request parameters
- *
- * @return string HTML
- */
- public function __invoke(array $params): string
+ public function __construct(
+ private readonly ResponseFactory $responseFactory,
+ private readonly ResponseRenderer $responseRenderer,
+ private readonly Template $template,
+ private readonly Config $config,
+ ) {
+ }
+
+ public function __invoke(ServerRequest $request): Response
{
- $pages = $this->getPages();
+ if (@file_exists(CONFIG_FILE) && ! $this->config->config->debug->demo) {
+ $response = $this->responseFactory->createResponse(StatusCodeInterface::STATUS_NOT_FOUND);
- $formset = isset($params['formset']) && is_string($params['formset']) ? $params['formset'] : '';
+ return $response->write($this->template->render('error/generic', [
+ 'lang' => $GLOBALS['lang'] ?? 'en',
+ 'dir' => LanguageManager::$textDir,
+ 'error_message' => __('Configuration already exists, setup is disabled!'),
+ ]));
+ }
- $formClass = SetupFormList::get($formset);
+ $response = $this->responseFactory->createResponse();
+ foreach ($this->responseRenderer->getHeader()->getHttpHeaders() as $name => $value) {
+ $response = $response->withHeader($name, $value);
+ }
+
+ $pages = SetupHelper::getPages();
+
+ $formSet = $this->getFormSetParam($request->getQueryParam('formset'));
+
+ $formClass = SetupFormList::get($formSet);
if ($formClass === null) {
- return $this->template->render('error/generic', [
+ return $response->write($this->template->render('error/generic', [
'lang' => $GLOBALS['lang'] ?? 'en',
'dir' => LanguageManager::$textDir,
'error_message' => __('Incorrect form specified!'),
- ]);
+ ]));
}
- ob_start();
- $form = new $formClass($this->config);
- FormProcessing::process($form);
- $page = ob_get_clean();
+ $configFile = SetupHelper::createConfigFile();
+ $formDisplay = new $formClass($configFile);
- return $this->template->render('setup/form/index', [
- 'formset' => $formset,
- 'pages' => $pages,
- 'name' => $form::getName(),
- 'page' => $page,
+ if ($request->getQueryParam('mode') === 'revert') {
+ // revert erroneous fields to their default values
+ $formDisplay->fixErrors();
+
+ return $response->withStatus(StatusCodeInterface::STATUS_FOUND)
+ ->withHeader('Location', '../setup/index.php' . Url::getCommonRaw(['route' => '/setup']));
+ }
+
+ if (! $formDisplay->process(false)) {
+ // handle form view and failed POST
+ return $response->write($this->template->render('setup/form/index', [
+ 'formset' => $formSet,
+ 'pages' => $pages,
+ 'name' => $formDisplay::getName(),
+ 'page' => $formDisplay->getDisplay(),
+ ]));
+ }
+
+ // check for form errors
+ if (! $formDisplay->hasErrors()) {
+ return $response->withStatus(StatusCodeInterface::STATUS_FOUND)
+ ->withHeader('Location', '../setup/index.php' . Url::getCommonRaw(['route' => '/setup']));
+ }
+
+ $page = $this->getPageParam($request->getQueryParam('page'));
+ $id = $this->getIdParam($request->getQueryParam('id'));
+ if ($id === 0 && $page === 'servers') {
+ // we've just added a new server, get its id
+ $id = $formDisplay->getConfigFile()->getServerCount();
+ }
+
+ $errors = $this->template->render('setup/error', [
+ 'url_params' => ['page' => $page, 'formset' => $formSet, 'id' => $id],
+ 'errors' => $formDisplay->displayErrors(),
]);
+
+ return $response->write($this->template->render('setup/form/index', [
+ 'formset' => $formSet,
+ 'pages' => $pages,
+ 'name' => $formDisplay::getName(),
+ 'page' => $errors,
+ ]));
+ }
+
+ private function getFormSetParam(mixed $formSetParam): string
+ {
+ return is_string($formSetParam) ? $formSetParam : '';
+ }
+
+ /** @psalm-return 'form'|'config'|'servers'|'index' */
+ private function getPageParam(mixed $pageParam): string
+ {
+ return in_array($pageParam, ['form', 'config', 'servers'], true) ? $pageParam : 'index';
+ }
+
+ /** @psalm-return int<0, max> */
+ private function getIdParam(mixed $idParam): int
+ {
+ if (! is_numeric($idParam)) {
+ return 0;
+ }
+
+ $id = (int) $idParam;
+
+ return $id >= 1 ? $id : 0;
}
}
diff --git a/src/Controllers/Setup/HomeController.php b/src/Controllers/Setup/HomeController.php
index 4866bd8299..8b1cb2e4e8 100644
--- a/src/Controllers/Setup/HomeController.php
+++ b/src/Controllers/Setup/HomeController.php
@@ -4,39 +4,68 @@ declare(strict_types=1);
namespace PhpMyAdmin\Controllers\Setup;
+use Fig\Http\Message\StatusCodeInterface;
use PhpMyAdmin\Config;
use PhpMyAdmin\Config\ServerConfigChecks;
+use PhpMyAdmin\Controllers\InvocableController;
+use PhpMyAdmin\Http\Factory\ResponseFactory;
+use PhpMyAdmin\Http\Response;
+use PhpMyAdmin\Http\ServerRequest;
use PhpMyAdmin\LanguageManager;
+use PhpMyAdmin\ResponseRenderer;
use PhpMyAdmin\Setup\Index;
+use PhpMyAdmin\Setup\SetupHelper;
+use PhpMyAdmin\Template;
use function __;
use function array_keys;
+use function file_exists;
use function is_scalar;
use function is_string;
-class HomeController extends AbstractController
-{
- /**
- * @param mixed[] $params Request parameters
- *
- * @return string HTML
- */
- public function __invoke(array $params): string
- {
- $formset = isset($params['formset']) && is_string($params['formset']) ? $params['formset'] : '';
+use const CONFIG_FILE;
- $pages = $this->getPages();
+final class HomeController implements InvocableController
+{
+ public function __construct(
+ private readonly ResponseFactory $responseFactory,
+ private readonly ResponseRenderer $responseRenderer,
+ private readonly Template $template,
+ private readonly Config $config,
+ ) {
+ }
+
+ public function __invoke(ServerRequest $request): Response
+ {
+ if (@file_exists(CONFIG_FILE) && ! $this->config->config->debug->demo) {
+ $response = $this->responseFactory->createResponse(StatusCodeInterface::STATUS_NOT_FOUND);
+
+ return $response->write($this->template->render('error/generic', [
+ 'lang' => $GLOBALS['lang'] ?? 'en',
+ 'dir' => LanguageManager::$textDir,
+ 'error_message' => __('Configuration already exists, setup is disabled!'),
+ ]));
+ }
+
+ $response = $this->responseFactory->createResponse();
+ foreach ($this->responseRenderer->getHeader()->getHttpHeaders() as $name => $value) {
+ $response = $response->withHeader($name, $value);
+ }
+
+ $pages = SetupHelper::getPages();
// message handling
Index::messagesBegin();
// Check phpMyAdmin version
- if (isset($params['version_check'])) {
+ if ($request->hasQueryParam('version_check')) {
Index::versionCheck();
}
+ $configFile = SetupHelper::createConfigFile();
+
// Perform various security, compatibility and consistency checks
- $configChecker = new ServerConfigChecks($this->config);
+ $configChecker = new ServerConfigChecks($configFile);
$configChecker->performConfigChecks();
$text = __(
@@ -66,12 +95,12 @@ class HomeController extends AbstractController
}
$servers = [];
- foreach (array_keys($this->config->getServers()) as $id) {
+ foreach (array_keys($configFile->getServers()) as $id) {
$servers[$id] = [
'id' => $id,
- 'name' => $this->config->getServerName($id),
- 'auth_type' => $this->config->getValue('Servers/' . $id . '/auth_type'),
- 'dsn' => $this->config->getServerDSN($id),
+ 'name' => $configFile->getServerName($id),
+ 'auth_type' => $configFile->getValue('Servers/' . $id . '/auth_type'),
+ 'dsn' => $configFile->getServerDSN($id),
'params' => [
'token' => $_SESSION[' PMA_token '],
'edit' => ['page' => 'servers', 'mode' => 'edit', 'id' => $id],
@@ -85,17 +114,22 @@ class HomeController extends AbstractController
$hasCheckPageRefresh = true;
}
- return $this->template->render('setup/home/index', [
- 'formset' => $formset,
+ return $response->write($this->template->render('setup/home/index', [
+ 'formset' => $this->getFormSetParam($request->getQueryParam('formset')),
'languages' => $languages,
'messages' => $messages,
- 'server_count' => $this->config->getServerCount(),
+ 'server_count' => $configFile->getServerCount(),
'servers' => $servers,
'pages' => $pages,
'has_check_page_refresh' => $hasCheckPageRefresh,
'eol' => isset($_SESSION['eol']) && is_scalar($_SESSION['eol'])
? $_SESSION['eol']
- : (Config::getInstance()->get('PMA_IS_WINDOWS') ? 'win' : 'unix'),
- ]);
+ : ($this->config->get('PMA_IS_WINDOWS') ? 'win' : 'unix'),
+ ]));
+ }
+
+ private function getFormSetParam(mixed $formSetParam): string
+ {
+ return is_string($formSetParam) ? $formSetParam : '';
}
}
diff --git a/src/Controllers/Setup/MainController.php b/src/Controllers/Setup/MainController.php
index 71bc2703ff..9a92e06e56 100644
--- a/src/Controllers/Setup/MainController.php
+++ b/src/Controllers/Setup/MainController.php
@@ -4,94 +4,76 @@ declare(strict_types=1);
namespace PhpMyAdmin\Controllers\Setup;
-use Fig\Http\Message\StatusCodeInterface;
use PhpMyAdmin\Config;
-use PhpMyAdmin\Console;
use PhpMyAdmin\Controllers\InvocableController;
-use PhpMyAdmin\Header;
use PhpMyAdmin\Http\Factory\ResponseFactory;
use PhpMyAdmin\Http\Response;
use PhpMyAdmin\Http\ServerRequest;
-use PhpMyAdmin\LanguageManager;
+use PhpMyAdmin\ResponseRenderer;
use PhpMyAdmin\Template;
-use PhpMyAdmin\Url;
-use function __;
-use function file_exists;
use function in_array;
-use const CONFIG_FILE;
-
final class MainController implements InvocableController
{
public function __construct(
private readonly ResponseFactory $responseFactory,
+ private readonly ResponseRenderer $responseRenderer,
private readonly Template $template,
- private readonly Console $console,
+ private readonly Config $config,
) {
}
public function __invoke(ServerRequest $request): Response
{
- $config = Config::getInstance();
- if (@file_exists(CONFIG_FILE) && ! $config->config->debug->demo) {
- $response = $this->responseFactory->createResponse(StatusCodeInterface::STATUS_NOT_FOUND);
-
- return $response->write($this->template->render('error/generic', [
- 'lang' => $GLOBALS['lang'] ?? 'en',
- 'dir' => LanguageManager::$textDir,
- 'error_message' => __('Configuration already exists, setup is disabled!'),
- ]));
- }
-
- /** @var mixed $pageParam */
- $pageParam = $request->getQueryParam('page');
- $page = in_array($pageParam, ['form', 'config', 'servers'], true) ? $pageParam : 'index';
-
- $response = $this->responseFactory->createResponse();
- $header = new Header($this->template, $this->console, $config);
- foreach ($header->getHttpHeaders() as $name => $value) {
- // Sent security-related headers
- $response = $response->withHeader($name, $value);
- }
-
+ $page = $this->getPageParam($request->getQueryParam('page'));
if ($page === 'form') {
- return $response->write((new FormController($GLOBALS['ConfigFile'], $this->template))([
- 'formset' => $request->getQueryParam('formset'),
- ]));
+ return (new FormController(
+ $this->responseFactory,
+ $this->responseRenderer,
+ $this->template,
+ $this->config,
+ ))($request);
}
if ($page === 'config') {
- return $response->write((new ConfigController($GLOBALS['ConfigFile'], $this->template))([
- 'formset' => $request->getQueryParam('formset'),
- 'eol' => $request->getQueryParam('eol'),
- ]));
+ return (new ConfigController(
+ $this->responseFactory,
+ $this->responseRenderer,
+ $this->template,
+ $this->config,
+ ))($request);
+ }
+
+ if ($page === 'servers' && $request->getQueryParam('mode') === 'remove' && $request->isPost()) {
+ return (new ServerDestroyController(
+ $this->responseFactory,
+ $this->responseRenderer,
+ $this->template,
+ $this->config,
+ ))($request);
}
if ($page === 'servers') {
- $controller = new ServersController($GLOBALS['ConfigFile'], $this->template);
- /** @var mixed $mode */
- $mode = $request->getQueryParam('mode');
- if ($mode === 'remove' && $request->isPost()) {
- $controller->destroy(['id' => $request->getQueryParam('id')]);
- $response = $response->withStatus(StatusCodeInterface::STATUS_FOUND);
-
- return $response->withHeader(
- 'Location',
- '../setup/index.php' . Url::getCommonRaw(['route' => '/setup']),
- );
- }
-
- return $response->write($controller->index([
- 'formset' => $request->getQueryParam('formset'),
- 'mode' => $mode,
- 'id' => $request->getQueryParam('id'),
- ]));
+ return (new ServersController(
+ $this->responseFactory,
+ $this->responseRenderer,
+ $this->template,
+ $this->config,
+ ))($request);
}
- return $response->write((new HomeController($GLOBALS['ConfigFile'], $this->template))([
- 'formset' => $request->getQueryParam('formset'),
- 'version_check' => $request->getQueryParam('version_check'),
- ]));
+ return (new HomeController(
+ $this->responseFactory,
+ $this->responseRenderer,
+ $this->template,
+ $this->config,
+ ))($request);
+ }
+
+ /** @psalm-return 'form'|'config'|'servers'|'index' */
+ private function getPageParam(mixed $pageParam): string
+ {
+ return in_array($pageParam, ['form', 'config', 'servers'], true) ? $pageParam : 'index';
}
}
diff --git a/src/Controllers/Setup/ServerDestroyController.php b/src/Controllers/Setup/ServerDestroyController.php
new file mode 100644
index 0000000000..03f344a533
--- /dev/null
+++ b/src/Controllers/Setup/ServerDestroyController.php
@@ -0,0 +1,77 @@
+config->config->debug->demo) {
+ $response = $this->responseFactory->createResponse(StatusCodeInterface::STATUS_NOT_FOUND);
+
+ return $response->write($this->template->render('error/generic', [
+ 'lang' => $GLOBALS['lang'] ?? 'en',
+ 'dir' => LanguageManager::$textDir,
+ 'error_message' => __('Configuration already exists, setup is disabled!'),
+ ]));
+ }
+
+ $response = $this->responseFactory->createResponse();
+ foreach ($this->responseRenderer->getHeader()->getHttpHeaders() as $name => $value) {
+ $response = $response->withHeader($name, $value);
+ }
+
+ $configFile = SetupHelper::createConfigFile();
+
+ $id = $this->getIdParam($request->getQueryParam('id'));
+ $hasServer = $id >= 1 && $configFile->get('Servers/' . $id) !== null;
+ if ($hasServer) {
+ $configFile->removeServer($id);
+ }
+
+ return $response->withStatus(StatusCodeInterface::STATUS_FOUND)->withHeader(
+ 'Location',
+ '../setup/index.php' . Url::getCommonRaw(['route' => '/setup']),
+ );
+ }
+
+ /** @psalm-return int<0, max> */
+ private function getIdParam(mixed $idParam): int
+ {
+ if (! is_numeric($idParam)) {
+ return 0;
+ }
+
+ $id = (int) $idParam;
+
+ return $id >= 1 ? $id : 0;
+ }
+}
diff --git a/src/Controllers/Setup/ServersController.php b/src/Controllers/Setup/ServersController.php
index a935596496..01c70af115 100644
--- a/src/Controllers/Setup/ServersController.php
+++ b/src/Controllers/Setup/ServersController.php
@@ -4,65 +4,146 @@ declare(strict_types=1);
namespace PhpMyAdmin\Controllers\Setup;
+use Fig\Http\Message\StatusCodeInterface;
+use PhpMyAdmin\Config;
use PhpMyAdmin\Config\Forms\Setup\ServersForm;
-use PhpMyAdmin\Setup\FormProcessing;
+use PhpMyAdmin\Controllers\InvocableController;
+use PhpMyAdmin\Http\Factory\ResponseFactory;
+use PhpMyAdmin\Http\Response;
+use PhpMyAdmin\Http\ServerRequest;
+use PhpMyAdmin\LanguageManager;
+use PhpMyAdmin\ResponseRenderer;
+use PhpMyAdmin\Setup\SetupHelper;
+use PhpMyAdmin\Template;
+use PhpMyAdmin\Url;
+use function __;
+use function file_exists;
use function in_array;
use function is_numeric;
use function is_string;
-use function ob_get_clean;
-use function ob_start;
-class ServersController extends AbstractController
+use const CONFIG_FILE;
+
+final class ServersController implements InvocableController
{
- /**
- * @param mixed[] $params Request parameters
- *
- * @return string HTML
- */
- public function index(array $params): string
+ public function __construct(
+ private readonly ResponseFactory $responseFactory,
+ private readonly ResponseRenderer $responseRenderer,
+ private readonly Template $template,
+ private readonly Config $config,
+ ) {
+ }
+
+ public function __invoke(ServerRequest $request): Response
{
- $formset = isset($params['formset']) && is_string($params['formset']) ? $params['formset'] : '';
- $id = isset($params['id']) && is_numeric($params['id']) && (int) $params['id'] >= 1 ? (int) $params['id'] : 0;
- $mode = '';
- if (isset($params['mode']) && in_array($params['mode'], ['add', 'edit', 'revert'], true)) {
- $mode = $params['mode'];
+ if (@file_exists(CONFIG_FILE) && ! $this->config->config->debug->demo) {
+ $response = $this->responseFactory->createResponse(StatusCodeInterface::STATUS_NOT_FOUND);
+
+ return $response->write($this->template->render('error/generic', [
+ 'lang' => $GLOBALS['lang'] ?? 'en',
+ 'dir' => LanguageManager::$textDir,
+ 'error_message' => __('Configuration already exists, setup is disabled!'),
+ ]));
}
- $pages = $this->getPages();
+ $response = $this->responseFactory->createResponse();
+ foreach ($this->responseRenderer->getHeader()->getHttpHeaders() as $name => $value) {
+ $response = $response->withHeader($name, $value);
+ }
- $hasServer = $id >= 1 && $this->config->get('Servers/' . $id) !== null;
+ $configFile = SetupHelper::createConfigFile();
+
+ $id = $this->getIdParam($request->getQueryParam('id'));
+ $mode = $this->getModeParam($request->getQueryParam('mode'));
+
+ $pages = SetupHelper::getPages();
+
+ $hasServer = $id >= 1 && $configFile->get('Servers/' . $id) !== null;
if (! $hasServer && $mode !== 'revert' && $mode !== 'edit') {
$id = 0;
}
- ob_start();
- FormProcessing::process(new ServersForm($this->config, $id));
- $page = ob_get_clean();
+ $formDisplay = new ServersForm($configFile, $id);
- return $this->template->render('setup/servers/index', [
- 'formset' => $formset,
+ if ($mode === 'revert') {
+ // revert erroneous fields to their default values
+ $formDisplay->fixErrors();
+
+ return $response->withStatus(StatusCodeInterface::STATUS_FOUND)
+ ->withHeader('Location', '../setup/index.php' . Url::getCommonRaw(['route' => '/setup']));
+ }
+
+ $formSet = $this->getFormSetParam($request->getQueryParam('formset'));
+
+ if (! $formDisplay->process(false)) {
+ // handle form view and failed POST
+ return $response->write($this->template->render('setup/servers/index', [
+ 'formset' => $formSet,
+ 'pages' => $pages,
+ 'has_server' => $hasServer,
+ 'mode' => $mode,
+ 'server_id' => $id,
+ 'server_dsn' => $configFile->getServerDSN($id),
+ 'page' => $formDisplay->getDisplay(),
+ ]));
+ }
+
+ // check for form errors
+ if (! $formDisplay->hasErrors()) {
+ return $response->withStatus(StatusCodeInterface::STATUS_FOUND)
+ ->withHeader('Location', '../setup/index.php' . Url::getCommonRaw(['route' => '/setup']));
+ }
+
+ $page = $this->getPageParam($request->getQueryParam('page'));
+ if ($id === 0 && $page === 'servers') {
+ // we've just added a new server, get its id
+ $id = $formDisplay->getConfigFile()->getServerCount();
+ }
+
+ $errors = $this->template->render('setup/error', [
+ 'url_params' => ['page' => $page, 'formset' => $formSet, 'id' => $id],
+ 'errors' => $formDisplay->displayErrors(),
+ ]);
+
+ return $response->write($this->template->render('setup/servers/index', [
+ 'formset' => $formSet,
'pages' => $pages,
'has_server' => $hasServer,
'mode' => $mode,
'server_id' => $id,
- 'server_dsn' => $this->config->getServerDSN($id),
- 'page' => $page,
- ]);
+ 'server_dsn' => $configFile->getServerDSN($id),
+ 'page' => $errors,
+ ]));
}
- /** @param mixed[] $params Request parameters */
- public function destroy(array $params): void
+ private function getFormSetParam(mixed $formSetParam): string
{
- $id = isset($params['id']) && is_numeric($params['id']) && (int) $params['id'] >= 1 ? (int) $params['id'] : 0;
+ return is_string($formSetParam) ? $formSetParam : '';
+ }
- $hasServer = $id >= 1 && $this->config->get('Servers/' . $id) !== null;
+ /** @psalm-return 'add'|'edit'|'revert'|'' */
+ private function getModeParam(mixed $modeParam): string
+ {
+ return in_array($modeParam, ['add', 'edit', 'revert'], true) ? $modeParam : '';
+ }
- if (! $hasServer) {
- return;
+ /** @psalm-return int<0, max> */
+ private function getIdParam(mixed $idParam): int
+ {
+ if (! is_numeric($idParam)) {
+ return 0;
}
- $this->config->removeServer($id);
+ $id = (int) $idParam;
+
+ return $id >= 1 ? $id : 0;
+ }
+
+ /** @psalm-return 'form'|'config'|'servers'|'index' */
+ private function getPageParam(mixed $pageParam): string
+ {
+ return in_array($pageParam, ['form', 'config', 'servers'], true) ? $pageParam : 'index';
}
}
diff --git a/src/Controllers/Setup/ShowConfigController.php b/src/Controllers/Setup/ShowConfigController.php
index 9a6fe7f535..e1edafc55e 100644
--- a/src/Controllers/Setup/ShowConfigController.php
+++ b/src/Controllers/Setup/ShowConfigController.php
@@ -5,26 +5,50 @@ declare(strict_types=1);
namespace PhpMyAdmin\Controllers\Setup;
use Fig\Http\Message\StatusCodeInterface;
+use PhpMyAdmin\Config;
use PhpMyAdmin\Config\Forms\Setup\ConfigForm;
use PhpMyAdmin\Controllers\InvocableController;
use PhpMyAdmin\Core;
+use PhpMyAdmin\Http\Factory\ResponseFactory;
use PhpMyAdmin\Http\Response;
use PhpMyAdmin\Http\ServerRequest;
-use PhpMyAdmin\ResponseRenderer;
+use PhpMyAdmin\LanguageManager;
use PhpMyAdmin\Setup\ConfigGenerator;
+use PhpMyAdmin\Setup\SetupHelper;
+use PhpMyAdmin\Template;
use PhpMyAdmin\Url;
+use function __;
+use function file_exists;
use function is_string;
+use const CONFIG_FILE;
+
final class ShowConfigController implements InvocableController
{
+ public function __construct(
+ private readonly ResponseFactory $responseFactory,
+ private readonly Template $template,
+ private readonly Config $config,
+ ) {
+ }
+
public function __invoke(ServerRequest $request): Response
{
- $formDisplay = new ConfigForm($GLOBALS['ConfigFile']);
- $formDisplay->save(['Config']);
+ if (@file_exists(CONFIG_FILE) && ! $this->config->config->debug->demo) {
+ $response = $this->responseFactory->createResponse(StatusCodeInterface::STATUS_NOT_FOUND);
- $response = ResponseRenderer::getInstance();
- $response->disable();
+ return $response->write($this->template->render('error/generic', [
+ 'lang' => $GLOBALS['lang'] ?? 'en',
+ 'dir' => LanguageManager::$textDir,
+ 'error_message' => __('Configuration already exists, setup is disabled!'),
+ ]));
+ }
+
+ $configFile = SetupHelper::createConfigFile();
+
+ $formDisplay = new ConfigForm($configFile);
+ $formDisplay->save(['Config']);
/** @var mixed $eol */
$eol = $request->getParsedBodyParam('eol');
@@ -36,32 +60,26 @@ final class ShowConfigController implements InvocableController
$submitClear = $request->getParsedBodyParam('submit_clear');
if (is_string($submitClear) && $submitClear !== '') {
// Clear current config and return to main page
- $GLOBALS['ConfigFile']->resetConfigData();
- // drop post data
- $response->addHeader('Location', '../setup/index.php' . Url::getCommonRaw(['route' => '/setup']));
- $response->setStatusCode(StatusCodeInterface::STATUS_SEE_OTHER);
+ $configFile->resetConfigData();
- return $response->response();
+ return $this->responseFactory->createResponse(StatusCodeInterface::STATUS_FOUND)
+ ->withHeader('Location', '../setup/index.php' . Url::getCommonRaw(['route' => '/setup']));
}
/** @var mixed $submitDownload */
$submitDownload = $request->getParsedBodyParam('submit_download');
if (is_string($submitDownload) && $submitDownload !== '') {
+ $response = $this->responseFactory->createResponse();
// Output generated config file
Core::downloadHeader('config.inc.php', 'text/plain');
- $response->disable();
- echo ConfigGenerator::getConfigFile($GLOBALS['ConfigFile']);
- return $response->response();
+ return $response->write(ConfigGenerator::getConfigFile($configFile));
}
// Show generated config file in a