Merge pull request #18496 from MauricioFauth/common-class

Rename the Common class to Application
This commit is contained in:
Maurício Meneghini Fauth 2023-06-14 09:04:51 -03:00 committed by GitHub
commit 1b7fbb9806
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 201 additions and 142 deletions

View File

@ -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();

View File

@ -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',

View File

@ -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();
}

View File

@ -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');

View File

@ -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'];

View File

@ -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();

View File

@ -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'];

View File

@ -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;

View File

@ -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);

View File

@ -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'],

View File

@ -27,6 +27,33 @@
<code><![CDATA[$rule['justification_formula']]]></code>
</MixedOperand>
</file>
<file src="libraries/classes/Application.php">
<InvalidArrayOffset>
<code><![CDATA[$GLOBALS['back']]]></code>
</InvalidArrayOffset>
<MixedArgument>
<code><![CDATA[$GLOBALS['cfg']['Server']]]></code>
<code><![CDATA[$_SESSION[' PMA_token ']]]></code>
</MixedArgument>
<MixedAssignment>
<code><![CDATA[$GLOBALS['back']]]></code>
</MixedAssignment>
<PossiblyInvalidArgument>
<code><![CDATA[$_GET['url'] ?? '']]></code>
<code><![CDATA[$_REQUEST['back']]]></code>
<code><![CDATA[$_REQUEST['goto']]]></code>
</PossiblyInvalidArgument>
<PossiblyInvalidCast>
<code><![CDATA[$_GET['url'] ?? '']]></code>
<code><![CDATA[$_REQUEST['back']]]></code>
<code><![CDATA[$_REQUEST['goto']]]></code>
</PossiblyInvalidCast>
<RedundantCast>
<code><![CDATA[(string) $GLOBALS['lang']]]></code>
<code><![CDATA[(string) $_POST['token']]]></code>
<code><![CDATA[(string) $_POST['token']]]></code>
</RedundantCast>
</file>
<file src="libraries/classes/Bookmark.php">
<DeprecatedMethod>
<code>escapeString</code>
@ -207,35 +234,6 @@
<code>$prevErrorHandler</code>
</UnusedVariable>
</file>
<file src="libraries/classes/Common.php">
<InvalidArrayOffset>
<code><![CDATA[$GLOBALS['back']]]></code>
<code><![CDATA[$GLOBALS['theme']]]></code>
</InvalidArrayOffset>
<MixedArgument>
<code><![CDATA[$GLOBALS['cfg']['Server']]]></code>
<code><![CDATA[$_SESSION[' PMA_token ']]]></code>
</MixedArgument>
<MixedAssignment>
<code><![CDATA[$GLOBALS['back']]]></code>
<code><![CDATA[$GLOBALS['theme']]]></code>
</MixedAssignment>
<PossiblyInvalidArgument>
<code><![CDATA[$_GET['url'] ?? '']]></code>
<code><![CDATA[$_REQUEST['back']]]></code>
<code><![CDATA[$_REQUEST['goto']]]></code>
</PossiblyInvalidArgument>
<PossiblyInvalidCast>
<code><![CDATA[$_GET['url'] ?? '']]></code>
<code><![CDATA[$_REQUEST['back']]]></code>
<code><![CDATA[$_REQUEST['goto']]]></code>
</PossiblyInvalidCast>
<RedundantCast>
<code><![CDATA[(string) $GLOBALS['lang']]]></code>
<code><![CDATA[(string) $_POST['token']]]></code>
<code><![CDATA[(string) $_POST['token']]]></code>
</RedundantCast>
</file>
<file src="libraries/classes/Config.php">
<MixedArgument>
<code>$collationConnection</code>
@ -13074,6 +13072,14 @@
<code>providerForTestRules</code>
</PossiblyUnusedMethod>
</file>
<file src="test/classes/ApplicationTest.php">
<RedundantConditionGivenDocblockType>
<code>assertFalse</code>
<code>assertTrue</code>
<code>assertTrue</code>
<code>assertTrue</code>
</RedundantConditionGivenDocblockType>
</file>
<file src="test/classes/BrowseForeignersTest.php">
<MixedArgument>
<code>$result</code>
@ -13125,14 +13131,6 @@
<code>$filesInfos</code>
</MixedAssignment>
</file>
<file src="test/classes/CommonTest.php">
<RedundantConditionGivenDocblockType>
<code>assertFalse</code>
<code>assertTrue</code>
<code>assertTrue</code>
<code>assertTrue</code>
</RedundantConditionGivenDocblockType>
</file>
<file src="test/classes/Config/ConfigFileTest.php">
<MixedArrayAccess>
<code><![CDATA[$cfgDb['Servers'][1]['port']]]></code>

View File

@ -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();

View File

@ -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);

View File

@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
namespace PhpMyAdmin\Tests;
use PhpMyAdmin\Application;
use PhpMyAdmin\Config;
use PhpMyAdmin\ErrorHandler;
use PhpMyAdmin\Exceptions\ConfigException;
use PhpMyAdmin\Http\ServerRequest;
use PhpMyAdmin\Template;
use PHPUnit\Framework\Attributes\CoversClass;
use ReflectionProperty;
use Symfony\Component\DependencyInjection\ContainerBuilder;
#[CoversClass(Application::class)]
final class ApplicationTest extends AbstractTestCase
{
public function testInit(): void
{
$application = new Application();
$container = $this->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']);
}
}

View File

@ -1,46 +0,0 @@
<?php
declare(strict_types=1);
namespace PhpMyAdmin\Tests;
use PhpMyAdmin\Common;
use PHPUnit\Framework\Attributes\CoversClass;
#[CoversClass(Common::class)]
class CommonTest extends AbstractTestCase
{
public function testCheckTokenRequestParam(): void
{
$_SERVER['REQUEST_METHOD'] = 'GET';
Common::checkTokenRequestParam();
$this->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']);
}
}