Merge pull request #19519 from MauricioFauth/plugins-globals-removal

Remove plugin global variables
This commit is contained in:
Maurício Meneghini Fauth 2025-01-14 16:47:39 -03:00 committed by GitHub
commit 98b0d33571
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 228 additions and 186 deletions

View File

@ -2115,7 +2115,7 @@ parameters:
Use dependency injection instead\.$#
'''
identifier: staticMethod.deprecated
count: 1
count: 3
path: src/Controllers/Database/ImportController.php
-
@ -2136,12 +2136,6 @@ parameters:
count: 1
path: src/Controllers/Database/ImportController.php
-
message: '#^Cannot cast mixed to string\.$#'
identifier: cast.string
count: 1
path: src/Controllers/Database/ImportController.php
-
message: '#^Parameter \#2 \$db of static method PhpMyAdmin\\Database\\MultiTableQuery\:\:displayResults\(\) expects string, mixed given\.$#'
identifier: argument.type
@ -3369,7 +3363,7 @@ parameters:
Use dependency injection instead\.$#
'''
identifier: staticMethod.deprecated
count: 1
count: 3
path: src/Controllers/Server/ImportController.php
-
@ -3390,12 +3384,6 @@ parameters:
count: 1
path: src/Controllers/Server/ImportController.php
-
message: '#^Cannot cast mixed to string\.$#'
identifier: cast.string
count: 1
path: src/Controllers/Server/ImportController.php
-
message: '#^Construct empty\(\) is not allowed\. Use more strict comparison\.$#'
identifier: empty.notAllowed
@ -4071,7 +4059,7 @@ parameters:
Use dependency injection instead\.$#
'''
identifier: staticMethod.deprecated
count: 1
count: 3
path: src/Controllers/Table/ImportController.php
-
@ -4092,12 +4080,6 @@ parameters:
count: 1
path: src/Controllers/Table/ImportController.php
-
message: '#^Cannot cast mixed to string\.$#'
identifier: cast.string
count: 1
path: src/Controllers/Table/ImportController.php
-
message: '#^Binary operation "\+\=" between int and mixed results in an error\.$#'
identifier: assignOp.invalid
@ -5745,13 +5727,7 @@ parameters:
Use dependency injection instead\.$#
'''
identifier: staticMethod.deprecated
count: 1
path: src/Database/Designer.php
-
message: '#^Cannot cast mixed to string\.$#'
identifier: cast.string
count: 1
count: 2
path: src/Database/Designer.php
-
@ -7494,7 +7470,7 @@ parameters:
Use dependency injection instead\.$#
'''
identifier: staticMethod.deprecated
count: 3
count: 4
path: src/Export/Options.php
-
@ -7521,7 +7497,7 @@ parameters:
-
message: '#^Cannot cast mixed to string\.$#'
identifier: cast.string
count: 4
count: 3
path: src/Export/Options.php
-
@ -10515,6 +10491,12 @@ parameters:
count: 1
path: src/Plugins.php
-
message: '#^Cannot cast mixed to string\.$#'
identifier: cast.string
count: 2
path: src/Plugins.php
-
message: '#^Construct empty\(\) is not allowed\. Use more strict comparison\.$#'
identifier: empty.notAllowed
@ -10533,54 +10515,18 @@ parameters:
count: 2
path: src/Plugins.php
-
message: '#^Method PhpMyAdmin\\Plugins\:\:getString\(\) should return string but returns mixed\.$#'
identifier: return.type
count: 1
path: src/Plugins.php
-
message: '#^Parameter \#1 \$link of static method PhpMyAdmin\\Html\\MySQLDocumentation\:\:show\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 2
path: src/Plugins.php
-
message: '#^Parameter \#1 \$name of static method PhpMyAdmin\\Plugins\:\:getString\(\) expects string\|null, mixed given\.$#'
identifier: argument.type
count: 2
path: src/Plugins.php
-
message: '#^Parameter \#1 \$string of function htmlspecialchars expects string, bool\|int\<0, max\>\|string given\.$#'
identifier: argument.type
count: 1
path: src/Plugins.php
-
message: '#^Parameter \#1 \$string of function htmlspecialchars expects string, mixed given\.$#'
identifier: argument.type
count: 2
path: src/Plugins.php
-
message: '#^Parameter \#2 \$anchor of static method PhpMyAdmin\\Html\\MySQLDocumentation\:\:showDocumentation\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Plugins.php
-
message: '#^Parameter \#2 \$replace of function str_replace expects array\<string\>\|string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Plugins.php
-
message: '#^Parameter \#3 \$subject of function str_replace expects array\<string\>\|string, bool\|int\<0, max\>\|string given\.$#'
identifier: argument.type
count: 1
path: src/Plugins.php
-
message: '#^Parameter \#5 \$anchor of static method PhpMyAdmin\\Html\\MySQLDocumentation\:\:show\(\) expects string, mixed given\.$#'
identifier: argument.type

View File

@ -927,6 +927,8 @@
<file src="src/Controllers/Database/ImportController.php">
<DeprecatedMethod>
<code><![CDATA[Config::getInstance()]]></code>
<code><![CDATA[Config::getInstance()]]></code>
<code><![CDATA[Config::getInstance()]]></code>
</DeprecatedMethod>
<MixedArrayAccess>
<code><![CDATA[$_SESSION[Ajax::SESSION_KEY]['handler']]]></code>
@ -1968,6 +1970,8 @@
<file src="src/Controllers/Server/ImportController.php">
<DeprecatedMethod>
<code><![CDATA[Config::getInstance()]]></code>
<code><![CDATA[Config::getInstance()]]></code>
<code><![CDATA[Config::getInstance()]]></code>
</DeprecatedMethod>
<MixedArrayAccess>
<code><![CDATA[$_SESSION[Ajax::SESSION_KEY]['handler']]]></code>
@ -2574,6 +2578,8 @@
<file src="src/Controllers/Table/ImportController.php">
<DeprecatedMethod>
<code><![CDATA[Config::getInstance()]]></code>
<code><![CDATA[Config::getInstance()]]></code>
<code><![CDATA[Config::getInstance()]]></code>
</DeprecatedMethod>
<MixedArrayAccess>
<code><![CDATA[$_SESSION[Ajax::SESSION_KEY]['handler']]]></code>
@ -3598,6 +3604,7 @@
<file src="src/Database/Designer.php">
<DeprecatedMethod>
<code><![CDATA[Config::getInstance()]]></code>
<code><![CDATA[Config::getInstance()]]></code>
</DeprecatedMethod>
<MixedAssignment>
<code><![CDATA[$params]]></code>
@ -3609,9 +3616,6 @@
<code><![CDATA[$params]]></code>
<code><![CDATA[$params]]></code>
</MixedReturnStatement>
<PossiblyInvalidCast>
<code><![CDATA[$_GET['export_type']]]></code>
</PossiblyInvalidCast>
</file>
<file src="src/Database/Designer/Common.php">
<DeprecatedMethod>
@ -4647,6 +4651,7 @@
<code><![CDATA[Config::getInstance()]]></code>
<code><![CDATA[Config::getInstance()]]></code>
<code><![CDATA[Config::getInstance()]]></code>
<code><![CDATA[Config::getInstance()]]></code>
<code><![CDATA[DatabaseInterface::getInstance()]]></code>
<code><![CDATA[DatabaseInterface::getInstance()]]></code>
</DeprecatedMethod>
@ -4659,9 +4664,6 @@
<PossiblyInvalidArgument>
<code><![CDATA[$_POST['filename_template'] ?? null]]></code>
</PossiblyInvalidArgument>
<PossiblyInvalidCast>
<code><![CDATA[$_GET['what']]]></code>
</PossiblyInvalidCast>
<RiskyTruthyFalsyComparison>
<code><![CDATA[$config->settings['Export'][$str]]]></code>
<code><![CDATA[empty($config->settings['SaveDir'])]]></code>
@ -6234,13 +6236,10 @@
<code><![CDATA[Config::getInstance()]]></code>
</DeprecatedMethod>
<MixedArgument>
<code><![CDATA[$GLOBALS[$match]]]></code>
<code><![CDATA[$doc[0]]]></code>
<code><![CDATA[$doc[1]]]></code>
<code><![CDATA[$doc[1]]]></code>
<code><![CDATA[$doc[2]]]></code>
<code><![CDATA[$val]]></code>
<code><![CDATA[$val]]></code>
</MixedArgument>
<MixedAssignment>
<code><![CDATA[$doc]]></code>
@ -6248,25 +6247,11 @@
<code><![CDATA[$val]]></code>
<code><![CDATA[$val]]></code>
</MixedAssignment>
<MixedInferredReturnType>
<code><![CDATA[string]]></code>
</MixedInferredReturnType>
<MixedMethodCall>
<code><![CDATA[new $class()]]></code>
</MixedMethodCall>
<MixedReturnStatement>
<code><![CDATA[$GLOBALS[$name] ?? $name ?? '']]></code>
<code><![CDATA[$GLOBALS[$name] ?? $name ?? '']]></code>
</MixedReturnStatement>
<PossiblyInvalidArgument>
<code><![CDATA[$_GET[$opt]]]></code>
<code><![CDATA[$_REQUEST[$opt]]]></code>
<code><![CDATA[$val]]></code>
<code><![CDATA[$val]]></code>
</PossiblyInvalidArgument>
<PossiblyInvalidCast>
<code><![CDATA[$config->settings[$section][$opt]]]></code>
<code><![CDATA[$config->settings[$section][$opt]]]></code>
</PossiblyInvalidCast>
<PossiblyNullOperand>
<code><![CDATA[$pitem->getName()]]></code>
@ -12386,6 +12371,9 @@
<code><![CDATA[$config->selectedServer]]></code>
<code><![CDATA[$config->selectedServer]]></code>
</InvalidPropertyAssignmentValue>
<PossiblyUnusedMethod>
<code><![CDATA[providerForGetTranslatedText]]></code>
</PossiblyUnusedMethod>
</file>
<file src="tests/unit/Plugins/Export/ExportOdtTest.php">
<DeprecatedMethod>

View File

@ -52,6 +52,8 @@ final class DesignerController implements InvocableController
$html = $this->databaseDesigner->getHtmlForSchemaExport(
$db,
(int) $request->getParsedBodyParamAsStringOrNull('selected_page'),
$request->getParam('format'),
$request->getParam('export_type'),
);
} elseif ($dialog === 'add_table') {
// Pass the db and table to the getTablesInfo so we only have the table we asked for

View File

@ -140,6 +140,8 @@ final class ExportController implements InvocableController
Current::$numTables,
0,
$exportList,
$request->getParam('format'),
$request->getParam('what'),
);
$this->response->render('database/export/index', array_merge($options, [

View File

@ -26,6 +26,7 @@ use PhpMyAdmin\Utils\ForeignKey;
use function __;
use function is_numeric;
use function is_string;
final class ImportController implements InvocableController
{
@ -92,12 +93,9 @@ final class ImportController implements InvocableController
$idKey = $_SESSION[Ajax::SESSION_KEY]['handler']::getIdKey();
$hiddenInputs = [$idKey => $uploadId, 'import_type' => 'database', 'db' => Current::$database];
$default = $request->hasQueryParam('format')
? (string) $request->getQueryParam('format')
: Plugins::getDefault('Import', 'format');
$choice = Plugins::getChoice($importList, $default);
$choice = Plugins::getChoice($importList, $this->getFormat($request->getParam('format')));
$options = Plugins::getOptions('Import', $importList);
$skipQueriesDefault = Plugins::getDefault('Import', 'skip_queries');
$skipQueriesDefault = $this->getSkipQueries($request->getParam('skip_queries'));
$isAllowInterruptChecked = Plugins::checkboxCheck('Import', 'allow_interrupt');
$maxUploadSize = (int) $config->get('max_upload_size');
@ -134,4 +132,22 @@ final class ImportController implements InvocableController
return $this->response->response();
}
private function getFormat(mixed $formatParam): string
{
if (is_string($formatParam) && $formatParam !== '') {
return $formatParam;
}
return Config::getInstance()->settings['Import']['format'];
}
private function getSkipQueries(mixed $skipQueriesParam): int
{
if (is_numeric($skipQueriesParam) && $skipQueriesParam >= 0) {
return (int) $skipQueriesParam;
}
return Config::getInstance()->settings['Import']['skip_queries'];
}
}

View File

@ -66,6 +66,8 @@ final class ExportController implements InvocableController
Current::$numTables,
0,
$exportList,
$request->getParam('format'),
$request->getParam('what'),
);
$this->response->render('server/export/index', array_merge($options, [

View File

@ -24,6 +24,7 @@ use PhpMyAdmin\Utils\ForeignKey;
use function __;
use function is_numeric;
use function is_string;
final class ImportController implements InvocableController
{
@ -74,12 +75,9 @@ final class ImportController implements InvocableController
$idKey = $_SESSION[Ajax::SESSION_KEY]['handler']::getIdKey();
$hiddenInputs = [$idKey => $uploadId, 'import_type' => 'server'];
$default = $request->hasQueryParam('format')
? (string) $request->getQueryParam('format')
: Plugins::getDefault('Import', 'format');
$choice = Plugins::getChoice($importList, $default);
$choice = Plugins::getChoice($importList, $this->getFormat($request->getParam('format')));
$options = Plugins::getOptions('Import', $importList);
$skipQueriesDefault = Plugins::getDefault('Import', 'skip_queries');
$skipQueriesDefault = $this->getSkipQueries($request->getParam('skip_queries'));
$isAllowInterruptChecked = Plugins::checkboxCheck('Import', 'allow_interrupt');
$maxUploadSize = (int) $config->get('max_upload_size');
@ -116,4 +114,22 @@ final class ImportController implements InvocableController
return $this->response->response();
}
private function getFormat(mixed $formatParam): string
{
if (is_string($formatParam) && $formatParam !== '') {
return $formatParam;
}
return Config::getInstance()->settings['Import']['format'];
}
private function getSkipQueries(mixed $skipQueriesParam): int
{
if (is_numeric($skipQueriesParam) && $skipQueriesParam >= 0) {
return (int) $skipQueriesParam;
}
return Config::getInstance()->settings['Import']['skip_queries'];
}
}

View File

@ -105,6 +105,8 @@ class ExportController implements InvocableController
Current::$numTables,
0,
$exportList,
$request->getParam('format'),
$request->getParam('what'),
);
$this->response->render('table/export/index', array_merge($options, [

View File

@ -29,6 +29,7 @@ use PhpMyAdmin\Utils\ForeignKey;
use function __;
use function is_numeric;
use function is_string;
final class ImportController implements InvocableController
{
@ -122,12 +123,9 @@ final class ImportController implements InvocableController
'table' => Current::$table,
];
$default = $request->hasQueryParam('format')
? (string) $request->getQueryParam('format')
: Plugins::getDefault('Import', 'format');
$choice = Plugins::getChoice($importList, $default);
$choice = Plugins::getChoice($importList, $this->getFormat($request->getParam('format')));
$options = Plugins::getOptions('Import', $importList);
$skipQueriesDefault = Plugins::getDefault('Import', 'skip_queries');
$skipQueriesDefault = $this->getSkipQueries($request->getParam('skip_queries'));
$isAllowInterruptChecked = Plugins::checkboxCheck('Import', 'allow_interrupt');
$maxUploadSize = (int) $config->get('max_upload_size');
@ -164,4 +162,22 @@ final class ImportController implements InvocableController
return $this->response->response();
}
private function getFormat(mixed $formatParam): string
{
if (is_string($formatParam) && $formatParam !== '') {
return $formatParam;
}
return Config::getInstance()->settings['Import']['format'];
}
private function getSkipQueries(mixed $skipQueriesParam): int
{
if (is_numeric($skipQueriesParam) && $skipQueriesParam >= 0) {
return (int) $skipQueriesParam;
}
return Config::getInstance()->settings['Import']['skip_queries'];
}
}

View File

@ -17,6 +17,7 @@ use PhpMyAdmin\Util;
use stdClass;
use function __;
use function is_string;
use function json_decode;
use function str_contains;
@ -101,7 +102,7 @@ class Designer
* @param string $db database name
* @param int $page the page to be exported
*/
public function getHtmlForSchemaExport(string $db, int $page): string
public function getHtmlForSchemaExport(string $db, int $page, mixed $formatParam, mixed $exportTypeParam): string
{
$exportList = Plugins::getSchema();
@ -112,10 +113,7 @@ class Designer
)->getDisplay();
}
$default = isset($_GET['export_type'])
? (string) $_GET['export_type']
: Plugins::getDefault('Schema', 'format');
$choice = Plugins::getChoice($exportList, $default);
$choice = Plugins::getChoice($exportList, $this->getFormat($formatParam, $exportTypeParam));
$options = Plugins::getOptions('Schema', $exportList);
return $this->template->render('database/designer/schema_export', [
@ -126,6 +124,19 @@ class Designer
]);
}
private function getFormat(mixed $formatParam, mixed $exportTypeParam): string
{
if (is_string($exportTypeParam) && $exportTypeParam !== '') {
return $exportTypeParam;
}
if (is_string($formatParam) && $formatParam !== '') {
return $formatParam;
}
return Config::getInstance()->settings['Schema']['format'];
}
/**
* Returns array of stored values of Designer Settings
*

View File

@ -99,6 +99,8 @@ final class Options
int|string $numTables,
int|string $unlimNumRows,
array $exportList,
mixed $formatParam,
mixed $whatParam,
): array {
$exportTemplatesFeature = $this->relation->getRelationParameters()->exportTemplatesFeature;
@ -116,8 +118,7 @@ final class Options
$templates = is_array($templates) ? $templates : [];
}
$default = isset($_GET['what']) ? (string) $_GET['what'] : Plugins::getDefault('Export', 'format');
$dropdown = Plugins::getChoice($exportList, $default);
$dropdown = Plugins::getChoice($exportList, $this->getFormat($formatParam, $whatParam));
$tableObject = new Table($table, $db, DatabaseInterface::getInstance());
$rows = [];
@ -202,6 +203,19 @@ final class Options
];
}
private function getFormat(mixed $formatParam, mixed $whatParam): string
{
if (is_string($whatParam) && $whatParam !== '') {
return $whatParam;
}
if (is_string($formatParam) && $formatParam !== '') {
return $formatParam;
}
return Config::getInstance()->settings['Export']['format'];
}
private function getFileNameTemplate(ExportType $exportType, string|null $filename = null): string
{
if ($filename !== null) {

View File

@ -32,15 +32,14 @@ use function class_exists;
use function count;
use function htmlspecialchars;
use function is_array;
use function is_string;
use function is_subclass_of;
use function mb_strtolower;
use function mb_strtoupper;
use function mb_substr;
use function method_exists;
use function preg_match_all;
use function sprintf;
use function str_contains;
use function str_replace;
use function str_starts_with;
use function strcasecmp;
use function usort;
@ -174,18 +173,6 @@ class Plugins
return $plugins;
}
/**
* Returns locale string for $name or $name if no locale is found
*
* @param string|null $name for local string
*
* @return string locale string for $name
*/
public static function getString(string|null $name): string
{
return $GLOBALS[$name] ?? $name ?? '';
}
/**
* Returns html input tag option 'checked' if plugin $opt
* should be set by config or request
@ -224,36 +211,21 @@ class Plugins
*/
public static function getDefault(string $section, string $opt): string
{
if (isset($_GET[$opt])) {
if (isset($_GET[$opt]) && is_string($_GET[$opt])) {
// If the form is being repopulated using $_GET data, that is priority
return htmlspecialchars($_GET[$opt]);
return $_GET[$opt];
}
if (isset($_REQUEST[$opt]) && ImportSettings::$timeoutPassed) {
return htmlspecialchars($_REQUEST[$opt]);
if (isset($_REQUEST[$opt]) && is_string($_REQUEST[$opt]) && ImportSettings::$timeoutPassed) {
return $_REQUEST[$opt];
}
$config = Config::getInstance();
if (! isset($config->settings[$section][$opt])) {
return '';
if (isset($config->settings[$section][$opt])) {
return (string) $config->settings[$section][$opt];
}
$matches = [];
/* Possibly replace localised texts */
if (preg_match_all('/(str[A-Z][A-Za-z0-9]*)/', (string) $config->settings[$section][$opt], $matches) < 1) {
return htmlspecialchars((string) $config->settings[$section][$opt]);
}
$val = $config->settings[$section][$opt];
foreach ($matches[0] as $match) {
if (! isset($GLOBALS[$match])) {
continue;
}
$val = str_replace($match, $GLOBALS[$match], $val);
}
return htmlspecialchars($val);
return '';
}
/**
@ -270,7 +242,7 @@ class Plugins
$properties = $plugin->getProperties();
$return[] = [
'name' => $pluginName,
'text' => self::getString($properties->getText()),
'text' => $plugin->getTranslatedText($properties->getText()),
'is_selected' => $pluginName === $default,
'is_binary' => $properties->getForceFile(),
];
@ -291,6 +263,7 @@ class Plugins
* @return string table row with option
*/
private static function getOneOption(
Plugin $plugin,
string $section,
string $pluginName,
OptionsPropertyItem $propertyGroup,
@ -313,7 +286,8 @@ class Plugins
}
if ($text != null) {
$ret .= '<h5 class="card-title mt-4 mb-2">' . self::getString($text) . '</h5>';
$ret .= '<h5 class="card-title mt-4 mb-2">'
. htmlspecialchars($plugin->getTranslatedText($text)) . '</h5>';
}
$ret .= '<ul class="list-group">';
@ -340,7 +314,7 @@ class Plugins
/** @var OptionsPropertyItem|null $subgroupHeader */
$subgroupHeader = $propertyItem->getSubgroupHeader();
if ($subgroupHeader !== null) {
$ret .= self::getOneOption($section, $pluginName, $subgroupHeader);
$ret .= self::getOneOption($plugin, $section, $pluginName, $subgroupHeader);
}
$ret .= '<li class="list-group-item"><ul class="list-group"';
@ -350,12 +324,12 @@ class Plugins
$ret .= '>';
}
$ret .= self::getOneOption($section, $pluginName, $propertyItem, true);
$ret .= self::getOneOption($plugin, $section, $pluginName, $propertyItem, true);
continue;
}
// single property item
$ret .= self::getHtmlForProperty($section, $pluginName, $propertyItem);
$ret .= self::getHtmlForProperty($plugin, $section, $pluginName, $propertyItem);
}
}
@ -402,6 +376,7 @@ class Plugins
* @psalm-param 'Export'|'Import'|'Schema' $section
*/
public static function getHtmlForProperty(
Plugin $plugin,
string $section,
string $pluginName,
OptionsPropertyItem $propertyItem,
@ -436,7 +411,7 @@ class Plugins
$ret .= '>';
$ret .= '<label class="form-check-label" for="checkbox_' . $pluginName . '_'
. $propertyItem->getName() . '">'
. self::getString($propertyItem->getText()) . '</label></div>';
. htmlspecialchars($plugin->getTranslatedText($propertyItem->getText() ?? '')) . '</label></div>';
break;
case DocPropertyItem::class:
echo DocPropertyItem::class;
@ -444,24 +419,25 @@ class Plugins
case HiddenPropertyItem::class:
$ret .= '<li class="list-group-item"><input type="hidden" name="' . $pluginName . '_'
. $propertyItem->getName() . '"'
. ' value="' . self::getDefault(
. ' value="'
. htmlspecialchars($plugin->getTranslatedText(self::getDefault(
$section,
$pluginName . '_' . $propertyItem->getName(),
)
)))
. '"></li>';
break;
case MessageOnlyPropertyItem::class:
$ret .= '<li class="list-group-item">' . "\n";
$ret .= self::getString($propertyItem->getText());
$ret .= htmlspecialchars($plugin->getTranslatedText($propertyItem->getText() ?? ''));
break;
case RadioPropertyItem::class:
/** @var RadioPropertyItem $pitem */
$pitem = $propertyItem;
$default = self::getDefault(
$default = htmlspecialchars($plugin->getTranslatedText(self::getDefault(
$section,
$pluginName . '_' . $pitem->getName(),
);
)));
$ret .= '<li class="list-group-item">';
@ -476,7 +452,7 @@ class Plugins
$ret .= '><label class="form-check-label" for="radio_' . $pluginName . '_'
. $pitem->getName() . '_' . $key . '">'
. self::getString($val) . '</label></div>';
. htmlspecialchars($plugin->getTranslatedText((string) $val)) . '</label></div>';
}
$ret .= '</li>';
@ -488,22 +464,22 @@ class Plugins
$ret .= '<li class="list-group-item">' . "\n";
$ret .= '<label for="select_' . $pluginName . '_'
. $pitem->getName() . '" class="form-label">'
. self::getString($pitem->getText()) . '</label>';
. htmlspecialchars($plugin->getTranslatedText($pitem->getText() ?? '')) . '</label>';
$ret .= '<select class="form-select" name="' . $pluginName . '_'
. $pitem->getName() . '"'
. ' id="select_' . $pluginName . '_'
. $pitem->getName() . '">';
$default = self::getDefault(
$default = htmlspecialchars($plugin->getTranslatedText(self::getDefault(
$section,
$pluginName . '_' . $pitem->getName(),
);
)));
foreach ($pitem->getValues() as $key => $val) {
$ret .= '<option value="' . $key . '"';
if ($key == $default) {
$ret .= ' selected';
}
$ret .= '>' . self::getString($val) . '</option>';
$ret .= '>' . htmlspecialchars($plugin->getTranslatedText((string) $val)) . '</option>';
}
$ret .= '</select>';
@ -514,13 +490,14 @@ class Plugins
$ret .= '<li class="list-group-item">' . "\n";
$ret .= '<label for="text_' . $pluginName . '_'
. $pitem->getName() . '" class="form-label">'
. self::getString($pitem->getText()) . '</label>';
. htmlspecialchars($plugin->getTranslatedText($pitem->getText() ?? '')) . '</label>';
$ret .= '<input class="form-control" type="text" name="' . $pluginName . '_'
. $pitem->getName() . '"'
. ' value="' . self::getDefault(
. ' value="'
. htmlspecialchars($plugin->getTranslatedText(self::getDefault(
$section,
$pluginName . '_' . $pitem->getName(),
) . '"'
))) . '"'
. ' id="text_' . $pluginName . '_'
. $pitem->getName() . '"'
. ($pitem->getSize() !== 0
@ -535,13 +512,14 @@ class Plugins
$ret .= '<li class="list-group-item">' . "\n";
$ret .= '<label for="number_' . $pluginName . '_'
. $propertyItem->getName() . '" class="form-label">'
. self::getString($propertyItem->getText()) . '</label>';
. htmlspecialchars($plugin->getTranslatedText($propertyItem->getText() ?? '')) . '</label>';
$ret .= '<input class="form-control" type="number" name="' . $pluginName . '_'
. $propertyItem->getName() . '"'
. ' value="' . self::getDefault(
. ' value="'
. htmlspecialchars($plugin->getTranslatedText(self::getDefault(
$section,
$pluginName . '_' . $propertyItem->getName(),
) . '"'
))) . '"'
. ' id="number_' . $pluginName . '_'
. $propertyItem->getName() . '"'
. ' min="0"'
@ -576,7 +554,7 @@ class Plugins
$ret .= '<div id="' . $pluginName
. '_options" class="format_specific_options">';
$ret .= '<h3>' . self::getString($text) . '</h3>';
$ret .= '<h3>' . htmlspecialchars($plugin->getTranslatedText($text)) . '</h3>';
$noOptions = true;
if ($options !== null && count($options) > 0) {
@ -590,7 +568,7 @@ class Plugins
}
}
$ret .= self::getOneOption($section, $pluginName, $propertyMainGroup);
$ret .= self::getOneOption($plugin, $section, $pluginName, $propertyMainGroup);
}
}

View File

@ -26,6 +26,8 @@ use PhpMyAdmin\Version;
use function __;
use function addcslashes;
use function array_keys;
use function array_values;
use function in_array;
use function is_string;
use function mb_strpos;
@ -59,15 +61,16 @@ class ExportLatex extends ExportPlugin
return 'latex';
}
/**
* Initialize the local variables that are used for export Latex.
*/
protected function init(): void
public function getTranslatedText(string $text): string
{
/* Messages used in default captions */
$GLOBALS['strLatexContent'] = __('Content of table @TABLE@');
$GLOBALS['strLatexContinued'] = __('(continued)');
$GLOBALS['strLatexStructure'] = __('Structure of table @TABLE@');
$messages = [
'strLatexContent' => __('Content of table @TABLE@'),
'strLatexContinued' => __('(continued)'),
'strLatexStructure' => __('Structure of table @TABLE@'),
];
return str_replace(array_keys($messages), array_values($messages), $text);
}
protected function setProperties(): ExportPluginProperties

View File

@ -342,4 +342,9 @@ abstract class ExportPlugin implements Plugin
?? StructureOrData::tryFrom(is_string($valueFromConfig) ? $valueFromConfig : '')
?? $defaultValue;
}
public function getTranslatedText(string $text): string
{
return $text;
}
}

View File

@ -68,4 +68,9 @@ abstract class ImportPlugin implements Plugin
}
abstract public function setImportOptions(ServerRequest $request): void;
public function getTranslatedText(string $text): string
{
return $text;
}
}

View File

@ -13,5 +13,8 @@ interface Plugin
public function getProperties(): PluginPropertyItem;
/** Returns locale string for $text or $text if no locale is found */
public function getTranslatedText(string $text): string;
public static function isAvailable(): bool;
}

View File

@ -92,4 +92,9 @@ abstract class SchemaPlugin implements Plugin
{
return true;
}
public function getTranslatedText(string $text): string
{
return $text;
}
}

View File

@ -36,7 +36,6 @@ class ImportControllerTest extends AbstractTestCase
Current::$lang = 'en';
$config = Config::getInstance();
$config->selectedServer = $config->getSettings()->Servers[1]->asArray();
$_GET['format'] = 'xml';
$dummyDbi = $this->createDbiDummy();
$dummyDbi->addSelectDb('test_db');
@ -92,7 +91,7 @@ class ImportControllerTest extends AbstractTestCase
]);
$request = ServerRequestFactory::create()->createServerRequest('GET', 'http://example.com/')
->withQueryParams(['db' => 'test_db', 'table' => 'test_table']);
->withQueryParams(['db' => 'test_db', 'table' => 'test_table', 'format' => 'xml']);
$response = new ResponseRenderer();
(new ImportController($response, $dbi, $pageSettings, new DbTableExists($dbi)))($request);

View File

@ -165,7 +165,7 @@ class DesignerTest extends AbstractTestCase
$dbi = DatabaseInterface::getInstance();
$this->designer = new Designer($dbi, new Relation($dbi), new Template());
$result = $this->designer->getHtmlForSchemaExport($db, $page);
$result = $this->designer->getHtmlForSchemaExport($db, $page, null, null);
// export type
self::assertStringContainsString('<select class="form-select" id="plugins" name="export_type">', $result);

View File

@ -82,7 +82,17 @@ class OptionsTest extends AbstractTestCase
$_POST['filename_template'] = 'user value for test';
//Call the test function
$actual = $this->export->getOptions($exportType, $db, $table, '', $numTablesStr, $unlimNumRowsStr, $exportList);
$actual = $this->export->getOptions(
$exportType,
$db,
$table,
'',
$numTablesStr,
$unlimNumRowsStr,
$exportList,
'sql',
null,
);
$expected = [
'export_type' => $exportType->value,

View File

@ -25,6 +25,7 @@ use PhpMyAdmin\Tests\AbstractTestCase;
use PhpMyAdmin\Tests\Stubs\DummyResult;
use PhpMyAdmin\Transformations;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Medium;
use ReflectionMethod;
use ReflectionProperty;
@ -775,4 +776,25 @@ class ExportLatexTest extends AbstractTestCase
ExportLatex::texEscape('$%{foo&bar}#_^'),
);
}
#[DataProvider('providerForGetTranslatedText')]
public function testGetTranslatedText(string $text, string $expected): void
{
self::assertSame($expected, $this->object->getTranslatedText($text));
}
/** @return iterable<array{string, string}> */
public static function providerForGetTranslatedText(): iterable
{
return [
['strTest strTest strTest', 'strTest strTest strTest'],
['strTest strLatexContent strTest', 'strTest Content of table @TABLE@ strTest'],
['strTest strLatexContinued strTest', 'strTest (continued) strTest'],
['strTest strLatexStructure strTest', 'strTest Structure of table @TABLE@ strTest'],
[
'strTest strLatexStructure strLatexContent strLatexContinued strTest',
'strTest Structure of table @TABLE@ Content of table @TABLE@ (continued) strTest',
],
];
}
}

View File

@ -69,9 +69,6 @@ class PluginsTest extends AbstractTestCase
$_GET[$option] = $actualGet;
}
$GLOBALS['strLatexContinued'] = '(continued)';
$GLOBALS['strLatexStructure'] = 'Structure of table @TABLE@';
/** @psalm-suppress InvalidArrayOffset, PossiblyInvalidArrayAssignment */
Config::getInstance()->settings[$section][$option] = $actualConfig;
$default = Plugins::getDefault($section, $option);
self::assertSame($expected, $default);
@ -86,7 +83,7 @@ class PluginsTest extends AbstractTestCase
['xml', null, 'xml', 'Export', 'format', null],
['', null, null, 'Export', 'format', null],
[
'Structure of table @TABLE@ strTest (continued)',
'strLatexStructure strTest strLatexContinued',
'strLatexStructure strTest strLatexContinued',
null,
'Export',