diff --git a/libraries/classes/Common.php b/libraries/classes/Application.php
similarity index 88%
rename from libraries/classes/Common.php
rename to libraries/classes/Application.php
index 3ac02f01b1..c35c09a75c 100644
--- a/libraries/classes/Common.php
+++ b/libraries/classes/Application.php
@@ -48,10 +48,18 @@ use function trigger_error;
use const CONFIG_FILE;
use const E_USER_ERROR;
-final class Common
+final class Application
{
private static ServerRequest|null $request = null;
+ public static function init(): self
+ {
+ /** @var Application $application */
+ $application = Core::getContainerBuilder()->get(self::class);
+
+ return $application;
+ }
+
/**
* Misc stuff and REQUIRED by ALL the scripts.
* MUST be included by every script
@@ -80,33 +88,28 @@ final class Common
* - db connection
* - authentication work
*/
- public static function run(bool $isSetupPage = false): void
+ public function run(bool $isSetupPage = false): void
{
- $GLOBALS['lang'] ??= null;
- $GLOBALS['theme'] ??= null;
- $GLOBALS['urlParams'] ??= null;
- $GLOBALS['token_mismatch'] ??= null;
+ $container = Core::getContainerBuilder();
$request = self::getRequest();
$route = $request->getRoute();
$isMinimumCommon = $isSetupPage || $route === '/import-status' || $route === '/url' || $route === '/messages';
- $container = Core::getContainerBuilder();
-
/** @var ErrorHandler $errorHandler */
$errorHandler = $container->get('error_handler');
$GLOBALS['errorHandler'] = $errorHandler;
try {
- self::checkRequiredPhpExtensions();
+ $this->checkRequiredPhpExtensions();
} catch (MissingExtensionException $exception) {
- echo self::getGenericError($exception->getMessage());
+ echo $this->getGenericError($exception->getMessage());
return;
}
- self::configurePhpSettings();
+ $this->configurePhpSettings();
/** @var Config $config */
$config = $container->get('config');
@@ -115,19 +118,19 @@ final class Common
try {
$config->loadAndCheck(CONFIG_FILE);
} catch (ConfigException $exception) {
- echo self::getGenericError($exception->getMessage());
+ echo $this->getGenericError($exception->getMessage());
return;
}
- $request = self::updateUriScheme($config, $request);
+ $request = $this->updateUriScheme($config, $request);
if ($route !== '/messages') {
try {
// Include session handling after the globals, to prevent overwriting.
Session::setUp($config, $errorHandler);
} catch (SessionHandlerException $exception) {
- echo self::getGenericError($exception->getMessage());
+ echo $this->getGenericError($exception->getMessage());
return;
}
@@ -147,10 +150,10 @@ final class Common
$GLOBALS['urlParams'] = [];
$container->setParameter('url_params', $GLOBALS['urlParams']);
- self::setGotoAndBackGlobals($container, $config);
- self::checkTokenRequestParam();
- self::setDatabaseAndTableFromRequest($container, $request);
- self::setSQLQueryGlobalFromRequest($container, $request);
+ $this->setGotoAndBackGlobals($container, $config);
+ $this->checkTokenRequestParam();
+ $this->setDatabaseAndTableFromRequest($container, $request);
+ $this->setSQLQueryGlobalFromRequest($container, $request);
//$_REQUEST['set_theme'] // checked later in this file LABEL_theme_setup
//$_REQUEST['server']; // checked later in this file
@@ -172,21 +175,21 @@ final class Common
$config->checkPermissions();
$config->checkErrors();
} catch (ConfigException $exception) {
- echo self::getGenericError($exception->getMessage());
+ echo $this->getGenericError($exception->getMessage());
return;
}
try {
- self::checkServerConfiguration();
- self::checkRequest();
+ $this->checkServerConfiguration();
+ $this->checkRequest();
} catch (RuntimeException $exception) {
- echo self::getGenericError($exception->getMessage());
+ echo $this->getGenericError($exception->getMessage());
return;
}
- self::setCurrentServerGlobal($container, $config, $request->getParam('server'));
+ $this->setCurrentServerGlobal($container, $config, $request->getParam('server'));
$GLOBALS['cfg'] = $config->settings;
$settings = $config->getSettings();
@@ -206,7 +209,7 @@ final class Common
}
if ($isSetupPage) {
- self::setupPageBootstrap($config);
+ $this->setupPageBootstrap($config);
Routing::callSetupController($request);
return;
@@ -237,7 +240,7 @@ final class Common
try {
$authPlugin = $authPluginFactory->create();
} catch (AuthenticationPluginException $exception) {
- echo self::getGenericError($exception->getMessage());
+ echo $this->getGenericError($exception->getMessage());
return;
}
@@ -253,7 +256,7 @@ final class Common
// phpcs:enable
}
- self::connectToDatabaseServer($GLOBALS['dbi'], $authPlugin, $currentServer);
+ $this->connectToDatabaseServer($GLOBALS['dbi'], $authPlugin, $currentServer);
$authPlugin->rememberCredentials();
$authPlugin->checkTwoFactor();
@@ -261,7 +264,7 @@ final class Common
Logging::logUser($config, $currentServer->user);
if ($GLOBALS['dbi']->getVersion() < $settings->mysqlMinVersion['internal']) {
- echo self::getGenericError(sprintf(
+ echo $this->getGenericError(sprintf(
__('You should upgrade to %s %s or later.'),
'MySQL',
$settings->mysqlMinVersion['human'],
@@ -322,7 +325,7 @@ final class Common
/**
* Checks that required PHP extensions are there.
*/
- private static function checkRequiredPhpExtensions(): void
+ private function checkRequiredPhpExtensions(): void
{
/**
* Warning about mbstring.
@@ -374,7 +377,7 @@ final class Common
/**
* Applies changes to PHP configuration.
*/
- private static function configurePhpSettings(): void
+ private function configurePhpSettings(): void
{
/**
* Set utf-8 encoding for PHP
@@ -397,7 +400,7 @@ final class Common
date_default_timezone_set(@date_default_timezone_get());
}
- private static function setGotoAndBackGlobals(ContainerInterface $container, Config $config): void
+ private function setGotoAndBackGlobals(ContainerInterface $container, Config $config): void
{
$GLOBALS['back'] ??= null;
$GLOBALS['urlParams'] ??= null;
@@ -442,7 +445,7 @@ final class Common
* GET Requests would never have token and therefore checking
* mis-match does not make sense.
*/
- public static function checkTokenRequestParam(): void
+ public function checkTokenRequestParam(): void
{
$GLOBALS['token_mismatch'] = true;
$GLOBALS['token_provided'] = false;
@@ -478,7 +481,7 @@ final class Common
Sanitize::removeRequestVars($allowList);
}
- private static function setDatabaseAndTableFromRequest(ContainerInterface $container, ServerRequest $request): void
+ private function setDatabaseAndTableFromRequest(ContainerInterface $container, ServerRequest $request): void
{
$GLOBALS['urlParams'] ??= null;
@@ -500,7 +503,7 @@ final class Common
/**
* Check whether PHP configuration matches our needs.
*/
- private static function checkServerConfiguration(): void
+ private function checkServerConfiguration(): void
{
/**
* As we try to handle charsets by ourself, mbstring overloads just
@@ -533,7 +536,7 @@ final class Common
/**
* Checks request and fails with fatal error if something problematic is found
*/
- private static function checkRequest(): void
+ private function checkRequest(): void
{
if (isset($_REQUEST['GLOBALS']) || isset($_FILES['GLOBALS'])) {
throw new RuntimeException(__('GLOBALS overwrite attempt'));
@@ -549,7 +552,7 @@ final class Common
throw new RuntimeException(__('possible exploit'));
}
- private static function connectToDatabaseServer(
+ private function connectToDatabaseServer(
DatabaseInterface $dbi,
AuthenticationPlugin $auth,
Server $currentServer,
@@ -589,13 +592,13 @@ final class Common
return self::$request;
}
- private static function setupPageBootstrap(Config $config): void
+ private function setupPageBootstrap(Config $config): void
{
// use default error handler
restore_error_handler();
// Save current language in a cookie, since it was not set in Common::run().
- $config->setCookie('pma_lang', (string) $GLOBALS['lang']);
+ $config->setCookie('pma_lang', $GLOBALS['lang']);
$config->set('is_setup', true);
$GLOBALS['ConfigFile'] = new ConfigFile();
@@ -619,7 +622,7 @@ final class Common
ob_start();
}
- private static function setSQLQueryGlobalFromRequest(ContainerInterface $container, ServerRequest $request): void
+ private function setSQLQueryGlobalFromRequest(ContainerInterface $container, ServerRequest $request): void
{
$sqlQuery = '';
if ($request->isPost()) {
@@ -634,7 +637,7 @@ final class Common
$container->setParameter('sql_query', $sqlQuery);
}
- private static function setCurrentServerGlobal(
+ private function setCurrentServerGlobal(
ContainerInterface $container,
Config $config,
mixed $serverParamFromRequest,
@@ -646,7 +649,7 @@ final class Common
$container->setParameter('url_params', $GLOBALS['urlParams']);
}
- private static function getGenericError(string $message): string
+ private function getGenericError(string $message): string
{
return (new Template())->render('error/generic', [
'lang' => $GLOBALS['lang'] ?? 'en',
@@ -655,7 +658,7 @@ final class Common
]);
}
- private static function updateUriScheme(Config $config, ServerRequest $request): ServerRequest
+ private function updateUriScheme(Config $config, ServerRequest $request): ServerRequest
{
$uriScheme = $config->isHttps() ? 'https' : 'http';
$uri = $request->getUri();
diff --git a/libraries/classes/DatabaseInterface.php b/libraries/classes/DatabaseInterface.php
index f77587ccf6..a1822de576 100644
--- a/libraries/classes/DatabaseInterface.php
+++ b/libraries/classes/DatabaseInterface.php
@@ -225,7 +225,7 @@ class DatabaseInterface implements DbalInterface
sprintf(
'SQL[%s?route=%s]: %0.3f(W:%d,C:%s,L:0x%02X) > %s',
basename($_SERVER['SCRIPT_NAME']),
- Common::getRequest()->getRoute(),
+ Application::getRequest()->getRoute(),
$this->lastQueryExecutionTime,
$this->getWarningCount($connectionType),
$cacheAffectedRows ? 'y' : 'n',
diff --git a/libraries/classes/DbTableExists.php b/libraries/classes/DbTableExists.php
index b141e930a2..1aa9ff79cf 100644
--- a/libraries/classes/DbTableExists.php
+++ b/libraries/classes/DbTableExists.php
@@ -108,7 +108,7 @@ final class DbTableExists
/** @var SqlController $controller */
$controller = Core::getContainerBuilder()->get(SqlController::class);
- $controller(Common::getRequest());
+ $controller(Application::getRequest());
ResponseRenderer::getInstance()->callExit();
}
diff --git a/libraries/classes/Export.php b/libraries/classes/Export.php
index f3bd74c1da..3ea5c91e88 100644
--- a/libraries/classes/Export.php
+++ b/libraries/classes/Export.php
@@ -1067,7 +1067,7 @@ class Export
public function showPage(string $exportType): void
{
$GLOBALS['active_page'] ??= null;
- $request = Common::getRequest();
+ $request = Application::getRequest();
$container = Core::getContainerBuilder();
if ($exportType === 'server') {
$GLOBALS['active_page'] = Url::getFromRoute('/server/export');
diff --git a/libraries/classes/Footer.php b/libraries/classes/Footer.php
index 31578c3159..ad70d0b669 100644
--- a/libraries/classes/Footer.php
+++ b/libraries/classes/Footer.php
@@ -129,7 +129,7 @@ class Footer
$GLOBALS['server'] ??= null;
$params = [];
- $params['route'] = Common::getRequest()->getRoute();
+ $params['route'] = Application::getRequest()->getRoute();
if (isset($GLOBALS['db']) && strlen($GLOBALS['db']) > 0) {
$params['db'] = $GLOBALS['db'];
diff --git a/libraries/classes/Menu.php b/libraries/classes/Menu.php
index 4f7a7b4b4e..4824398f4c 100644
--- a/libraries/classes/Menu.php
+++ b/libraries/classes/Menu.php
@@ -207,7 +207,7 @@ class Menu
*/
private function getTableTabs(): array
{
- $route = Common::getRequest()->getRoute();
+ $route = Application::getRequest()->getRoute();
$isSystemSchema = Utilities::isSystemSchema($this->db);
$tableIsView = $this->dbi->getTable($this->db, $this->table)
@@ -319,7 +319,7 @@ class Menu
*/
private function getDbTabs(): array
{
- $route = Common::getRequest()->getRoute();
+ $route = Application::getRequest()->getRoute();
$isSystemSchema = Utilities::isSystemSchema($this->db);
$numTables = count($this->dbi->getTables($this->db));
@@ -434,7 +434,7 @@ class Menu
*/
private function getServerTabs(): array
{
- $route = Common::getRequest()->getRoute();
+ $route = Application::getRequest()->getRoute();
$isSuperUser = $this->dbi->isSuperUser();
$isCreateOrGrantUser = $this->dbi->isGrantUser() || $this->dbi->isCreateUser();
diff --git a/libraries/classes/Plugins/Auth/AuthenticationCookie.php b/libraries/classes/Plugins/Auth/AuthenticationCookie.php
index 51628beefc..c19810ed46 100644
--- a/libraries/classes/Plugins/Auth/AuthenticationCookie.php
+++ b/libraries/classes/Plugins/Auth/AuthenticationCookie.php
@@ -7,7 +7,7 @@ declare(strict_types=1);
namespace PhpMyAdmin\Plugins\Auth;
-use PhpMyAdmin\Common;
+use PhpMyAdmin\Application;
use PhpMyAdmin\Config;
use PhpMyAdmin\Core;
use PhpMyAdmin\Exceptions\SessionHandlerException;
@@ -142,7 +142,7 @@ class AuthenticationCookie extends AuthenticationPlugin
}
$formParams = [];
- $formParams['route'] = Common::getRequest()->getRoute();
+ $formParams['route'] = Application::getRequest()->getRoute();
if (strlen($GLOBALS['db'])) {
$formParams['db'] = $GLOBALS['db'];
@@ -461,7 +461,7 @@ class AuthenticationCookie extends AuthenticationPlugin
// any parameters to pass?
$urlParams = [];
- $urlParams['route'] = Common::getRequest()->getRoute();
+ $urlParams['route'] = Application::getRequest()->getRoute();
if (strlen($GLOBALS['db']) > 0) {
$urlParams['db'] = $GLOBALS['db'];
diff --git a/libraries/classes/Plugins/TwoFactor/WebAuthn.php b/libraries/classes/Plugins/TwoFactor/WebAuthn.php
index 6b4fc979c2..e4d0874932 100644
--- a/libraries/classes/Plugins/TwoFactor/WebAuthn.php
+++ b/libraries/classes/Plugins/TwoFactor/WebAuthn.php
@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace PhpMyAdmin\Plugins\TwoFactor;
-use PhpMyAdmin\Common;
+use PhpMyAdmin\Application;
use PhpMyAdmin\Http\ServerRequest;
use PhpMyAdmin\Plugins\TwoFactorPlugin;
use PhpMyAdmin\ResponseRenderer;
@@ -75,7 +75,7 @@ class WebAuthn extends TwoFactorPlugin
private function getRequest(): ServerRequest
{
if ($this->serverRequest === null) {
- $this->serverRequest = Common::getRequest();
+ $this->serverRequest = Application::getRequest();
}
return $this->serverRequest;
diff --git a/libraries/classes/Table/Indexes.php b/libraries/classes/Table/Indexes.php
index f09263b0f0..b3c0c103b3 100644
--- a/libraries/classes/Table/Indexes.php
+++ b/libraries/classes/Table/Indexes.php
@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace PhpMyAdmin\Table;
-use PhpMyAdmin\Common;
+use PhpMyAdmin\Application;
use PhpMyAdmin\Controllers\Table\StructureController;
use PhpMyAdmin\Core;
use PhpMyAdmin\DatabaseInterface;
@@ -96,7 +96,7 @@ final class Indexes
} else {
/** @var StructureController $controller */
$controller = Core::getContainerBuilder()->get(StructureController::class);
- $controller(Common::getRequest());
+ $controller(Application::getRequest());
}
} else {
$this->response->setRequestStatus(false);
diff --git a/libraries/services.php b/libraries/services.php
index fe28313e42..bf920494f7 100644
--- a/libraries/services.php
+++ b/libraries/services.php
@@ -3,6 +3,7 @@
declare(strict_types=1);
use PhpMyAdmin\Advisory\Advisor;
+use PhpMyAdmin\Application;
use PhpMyAdmin\BrowseForeigners;
use PhpMyAdmin\CheckUserPrivileges;
use PhpMyAdmin\Config;
@@ -62,6 +63,7 @@ return [
'class' => Advisor::class,
'arguments' => ['$dbi' => '@dbi', '$expression' => '@expression_language'],
],
+ Application::class => ['class' => Application::class],
'browse_foreigners' => [
'class' => BrowseForeigners::class,
'arguments' => ['@template', '@config'],
diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index 3ee15dd163..d94ff2d5cc 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -27,6 +27,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
escapeString
@@ -207,35 +234,6 @@
$prevErrorHandler
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
$collationConnection
@@ -13074,6 +13072,14 @@
providerForTestRules
+
+
+ assertFalse
+ assertTrue
+ assertTrue
+ assertTrue
+
+
$result
@@ -13125,14 +13131,6 @@
$filesInfos
-
-
- assertFalse
- assertTrue
- assertTrue
- assertTrue
-
-
diff --git a/public/index.php b/public/index.php
index c65b83d1ba..783bf83545 100644
--- a/public/index.php
+++ b/public/index.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-use PhpMyAdmin\Common;
+use PhpMyAdmin\Application;
// phpcs:disable PSR1.Files.SideEffects
if (! defined('ROOT_PATH')) {
@@ -29,4 +29,4 @@ if (! @is_readable(AUTOLOAD_FILE)) {
require AUTOLOAD_FILE;
-Common::run();
+Application::init()->run();
diff --git a/public/setup/index.php b/public/setup/index.php
index 1a2adccd60..45e7d488d2 100644
--- a/public/setup/index.php
+++ b/public/setup/index.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-use PhpMyAdmin\Common;
+use PhpMyAdmin\Application;
// phpcs:disable PSR1.Files.SideEffects
if (! defined('ROOT_PATH')) {
@@ -29,4 +29,4 @@ if (! @is_readable(AUTOLOAD_FILE)) {
require AUTOLOAD_FILE;
-Common::run(true);
+Application::init()->run(true);
diff --git a/test/classes/ApplicationTest.php b/test/classes/ApplicationTest.php
new file mode 100644
index 0000000000..55b32538f8
--- /dev/null
+++ b/test/classes/ApplicationTest.php
@@ -0,0 +1,102 @@
+createMock(ContainerBuilder::class);
+ $container->expects($this->once())->method('get')
+ ->with($this->identicalTo(Application::class))->willReturn($application);
+ $GLOBALS['containerBuilder'] = $container;
+ $this->assertSame($application, Application::init());
+ }
+
+ public function testRunWithConfigError(): void
+ {
+ $GLOBALS['errorHandler'] = null;
+ $errorHandler = $this->createStub(ErrorHandler::class);
+
+ $GLOBALS['config'] = null;
+ $config = $this->createMock(Config::class);
+ $config->expects($this->once())->method('loadAndCheck')
+ ->willThrowException(new ConfigException('Failed to load phpMyAdmin configuration.'));
+
+ $container = $this->createStub(ContainerBuilder::class);
+ $container->method('get')->willReturnMap([
+ ['error_handler', 1, $errorHandler],
+ ['config', 1, $config],
+ ]);
+ $GLOBALS['containerBuilder'] = $container;
+
+ $request = $this->createStub(ServerRequest::class);
+ (new ReflectionProperty(Application::class, 'request'))->setValue($request);
+
+ $expected = (new Template())->render('error/generic', [
+ 'lang' => 'en',
+ 'dir' => 'ltr',
+ 'error_message' => 'Failed to load phpMyAdmin configuration.',
+ ]);
+
+ $application = new Application();
+ $application->run();
+
+ $output = $this->getActualOutputForAssertion();
+ $this->assertSame($expected, $output);
+ $this->assertSame($config, $GLOBALS['config']);
+ $this->assertSame($errorHandler, $GLOBALS['errorHandler']);
+
+ (new ReflectionProperty(Application::class, 'request'))->setValue(null);
+ }
+
+ public function testCheckTokenRequestParam(): void
+ {
+ $application = new Application();
+
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $application->checkTokenRequestParam();
+ $this->assertTrue($GLOBALS['token_mismatch']);
+ $this->assertFalse($GLOBALS['token_provided']);
+
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ $_POST['test'] = 'test';
+ $application->checkTokenRequestParam();
+ $this->assertTrue($GLOBALS['token_mismatch']);
+ $this->assertFalse($GLOBALS['token_provided']);
+ $this->assertArrayNotHasKey('test', $_POST);
+
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ $_POST['token'] = 'token';
+ $_POST['test'] = 'test';
+ $_SESSION[' PMA_token '] = 'mismatch';
+ $application->checkTokenRequestParam();
+ $this->assertTrue($GLOBALS['token_mismatch']);
+ $this->assertTrue($GLOBALS['token_provided']);
+ $this->assertArrayNotHasKey('test', $_POST);
+
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ $_POST['token'] = 'token';
+ $_POST['test'] = 'test';
+ $_SESSION[' PMA_token '] = 'token';
+ $application->checkTokenRequestParam();
+ $this->assertFalse($GLOBALS['token_mismatch']);
+ $this->assertTrue($GLOBALS['token_provided']);
+ $this->assertArrayHasKey('test', $_POST);
+ $this->assertEquals('test', $_POST['test']);
+ }
+}
diff --git a/test/classes/CommonTest.php b/test/classes/CommonTest.php
deleted file mode 100644
index 6d55d810c9..0000000000
--- a/test/classes/CommonTest.php
+++ /dev/null
@@ -1,46 +0,0 @@
-assertTrue($GLOBALS['token_mismatch']);
- $this->assertFalse($GLOBALS['token_provided']);
-
- $_SERVER['REQUEST_METHOD'] = 'POST';
- $_POST['test'] = 'test';
- Common::checkTokenRequestParam();
- $this->assertTrue($GLOBALS['token_mismatch']);
- $this->assertFalse($GLOBALS['token_provided']);
- $this->assertArrayNotHasKey('test', $_POST);
-
- $_SERVER['REQUEST_METHOD'] = 'POST';
- $_POST['token'] = 'token';
- $_POST['test'] = 'test';
- $_SESSION[' PMA_token '] = 'mismatch';
- Common::checkTokenRequestParam();
- $this->assertTrue($GLOBALS['token_mismatch']);
- $this->assertTrue($GLOBALS['token_provided']);
- $this->assertArrayNotHasKey('test', $_POST);
-
- $_SERVER['REQUEST_METHOD'] = 'POST';
- $_POST['token'] = 'token';
- $_POST['test'] = 'test';
- $_SESSION[' PMA_token '] = 'token';
- Common::checkTokenRequestParam();
- $this->assertFalse($GLOBALS['token_mismatch']);
- $this->assertTrue($GLOBALS['token_provided']);
- $this->assertArrayHasKey('test', $_POST);
- $this->assertEquals('test', $_POST['test']);
- }
-}