Merge pull request #19424 from kamil-tekiela/getFilenameAndMimetype

Refactor getFilenameAndMimetype
This commit is contained in:
Maurício Meneghini Fauth 2024-12-05 11:05:35 -03:00 committed by GitHub
commit 534a06462a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 64 additions and 157 deletions

View File

@ -2844,18 +2844,6 @@ parameters:
count: 3
path: src/Controllers/Export/ExportController.php
-
message: '#^Call to an undefined method object\:\:exportFooter\(\)\.$#'
identifier: method.notFound
count: 1
path: src/Controllers/Export/ExportController.php
-
message: '#^Call to an undefined method object\:\:exportHeader\(\)\.$#'
identifier: method.notFound
count: 1
path: src/Controllers/Export/ExportController.php
-
message: '''
#^Call to deprecated method getInstance\(\) of class PhpMyAdmin\\Config\:
@ -2880,7 +2868,7 @@ parameters:
-
message: '#^Construct empty\(\) is not allowed\. Use more strict comparison\.$#'
identifier: empty.notAllowed
count: 5
count: 4
path: src/Controllers/Export/ExportController.php
-
@ -2931,18 +2919,6 @@ parameters:
count: 1
path: src/Controllers/Export/ExportController.php
-
message: '#^Parameter \#1 \$exportPlugin of method PhpMyAdmin\\Export\\Export\:\:getFinalFilenameAndMimetypeForFilename\(\) expects PhpMyAdmin\\Plugins\\ExportPlugin, object given\.$#'
identifier: argument.type
count: 1
path: src/Controllers/Export/ExportController.php
-
message: '#^Parameter \#1 \$exportType of method PhpMyAdmin\\Export\\Export\:\:getFilenameAndMimetype\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Controllers/Export/ExportController.php
-
message: '#^Parameter \#1 \$exportType of method PhpMyAdmin\\Export\\Export\:\:getHtmlForDisplayedExportFooter\(\) expects string, mixed given\.$#'
identifier: argument.type
@ -2986,7 +2962,13 @@ parameters:
path: src/Controllers/Export/ExportController.php
-
message: '#^Parameter \#2 \$compression of method PhpMyAdmin\\Export\\Export\:\:getFinalFilenameAndMimetypeForFilename\(\) expects string, mixed given\.$#'
message: '#^Parameter \#2 \$compression of method PhpMyAdmin\\Export\\Export\:\:getFinalFilename\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 2
path: src/Controllers/Export/ExportController.php
-
message: '#^Parameter \#2 \$compression of method PhpMyAdmin\\Export\\Export\:\:getMimeType\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Controllers/Export/ExportController.php
@ -2998,13 +2980,7 @@ parameters:
path: src/Controllers/Export/ExportController.php
-
message: '#^Parameter \#2 \$exportPlugin of static method PhpMyAdmin\\Export\\Export\:\:exportRaw\(\) expects PhpMyAdmin\\Plugins\\ExportPlugin, object given\.$#'
identifier: argument.type
count: 1
path: src/Controllers/Export/ExportController.php
-
message: '#^Parameter \#2 \$rememberTemplate of method PhpMyAdmin\\Export\\Export\:\:getFilenameAndMimetype\(\) expects string, mixed given\.$#'
message: '#^Parameter \#2 \$exportType of method PhpMyAdmin\\Export\\Export\:\:rememberFilename\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Controllers/Export/ExportController.php
@ -3015,42 +2991,18 @@ parameters:
count: 1
path: src/Controllers/Export/ExportController.php
-
message: '#^Parameter \#3 \$exportPlugin of method PhpMyAdmin\\Export\\Export\:\:exportServer\(\) expects PhpMyAdmin\\Plugins\\ExportPlugin, object given\.$#'
identifier: argument.type
count: 1
path: src/Controllers/Export/ExportController.php
-
message: '#^Parameter \#3 \$exportPlugin of method PhpMyAdmin\\Export\\Export\:\:getFilenameAndMimetype\(\) expects PhpMyAdmin\\Plugins\\ExportPlugin, object given\.$#'
identifier: argument.type
count: 1
path: src/Controllers/Export/ExportController.php
-
message: '#^Parameter \#3 \$saveFilename of method PhpMyAdmin\\Export\\Export\:\:closeFile\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Controllers/Export/ExportController.php
-
message: '#^Parameter \#4 \$compression of method PhpMyAdmin\\Export\\Export\:\:getFilenameAndMimetype\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Controllers/Export/ExportController.php
-
message: '#^Parameter \#4 \$errorUrl of method PhpMyAdmin\\Export\\Export\:\:exportServer\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Controllers/Export/ExportController.php
-
message: '#^Parameter \#4 \$exportPlugin of method PhpMyAdmin\\Export\\Export\:\:exportTable\(\) expects PhpMyAdmin\\Plugins\\ExportPlugin, object given\.$#'
identifier: argument.type
count: 2
path: src/Controllers/Export/ExportController.php
-
message: '#^Parameter \#4 \$tableStructure of method PhpMyAdmin\\Export\\Export\:\:exportDatabase\(\) expects array\<string\>, array\<mixed\> given\.$#'
identifier: argument.type
@ -3075,12 +3027,6 @@ parameters:
count: 2
path: src/Controllers/Export/ExportController.php
-
message: '#^Parameter \#6 \$exportPlugin of method PhpMyAdmin\\Export\\Export\:\:exportDatabase\(\) expects PhpMyAdmin\\Plugins\\ExportPlugin, object given\.$#'
identifier: argument.type
count: 2
path: src/Controllers/Export/ExportController.php
-
message: '#^Parameter \#6 \$exportType of method PhpMyAdmin\\Export\\Export\:\:exportTable\(\) expects string, mixed given\.$#'
identifier: argument.type
@ -8700,7 +8646,7 @@ parameters:
Use dependency injection instead\.$#
'''
identifier: staticMethod.deprecated
count: 3
count: 2
path: src/Export/Export.php
-

View File

@ -1470,16 +1470,6 @@
</PossiblyUnusedMethod>
</file>
<file src="src/Controllers/Export/ExportController.php">
<ArgumentTypeCoercion>
<code><![CDATA[$exportPlugin]]></code>
<code><![CDATA[$exportPlugin]]></code>
<code><![CDATA[$exportPlugin]]></code>
<code><![CDATA[$exportPlugin]]></code>
<code><![CDATA[$exportPlugin]]></code>
<code><![CDATA[$exportPlugin]]></code>
<code><![CDATA[$exportPlugin]]></code>
<code><![CDATA[$exportPlugin]]></code>
</ArgumentTypeCoercion>
<DeprecatedMethod>
<code><![CDATA[Config::getInstance()]]></code>
</DeprecatedMethod>
@ -1516,7 +1506,6 @@
<code><![CDATA[$GLOBALS['sql_query']]]></code>
<code><![CDATA[$GLOBALS['sql_query']]]></code>
<code><![CDATA[$dbSelect]]></code>
<code><![CDATA[$rememberTemplate]]></code>
</MixedArgument>
<MixedArgumentTypeCoercion>
<code><![CDATA[$GLOBALS['table_data']]]></code>
@ -1637,14 +1626,9 @@
<code><![CDATA[$GLOBALS['xml_structure_or_data']]]></code>
<code><![CDATA[$GLOBALS['yaml_structure_or_data']]]></code>
<code><![CDATA[$dbSelect]]></code>
<code><![CDATA[$rememberTemplate]]></code>
<code><![CDATA[$tableNames]]></code>
<code><![CDATA[$tableStructure]]></code>
</MixedAssignment>
<MixedMethodCall>
<code><![CDATA[exportFooter]]></code>
<code><![CDATA[exportHeader]]></code>
</MixedMethodCall>
<PossiblyInvalidArgument>
<code><![CDATA[$GLOBALS['charset']]]></code>
<code><![CDATA[$GLOBALS['compression']]]></code>
@ -5306,7 +5290,6 @@
<DeprecatedMethod>
<code><![CDATA[Config::getInstance()]]></code>
<code><![CDATA[Config::getInstance()]]></code>
<code><![CDATA[Config::getInstance()]]></code>
</DeprecatedMethod>
<InvalidArrayOffset>
<code><![CDATA[$GLOBALS['save_filename']]]></code>

View File

@ -21,6 +21,7 @@ use PhpMyAdmin\Message;
use PhpMyAdmin\Plugins;
use PhpMyAdmin\Plugins\Export\ExportSql;
use PhpMyAdmin\Plugins\Export\ExportXml;
use PhpMyAdmin\Plugins\ExportPlugin;
use PhpMyAdmin\ResponseRenderer;
use PhpMyAdmin\Sanitize;
use PhpMyAdmin\SqlParser\Parser;
@ -80,7 +81,7 @@ final class ExportController implements InvocableController
/** @var array|null $aliasesParam */
$aliasesParam = $request->getParsedBodyParam('aliases');
$structureOrDataForced = (bool) $request->getParsedBodyParamAsStringOrNull('structure_or_data_forced');
$rememberTemplate = $request->getParsedBodyParam('remember_template');
$rememberTemplate = $request->getParsedBodyParamAsString('remember_template', '');
$dbSelect = $request->getParsedBodyParam('db_select');
$tableStructure = $request->getParsedBodyParam('table_structure');
$lockTables = $request->hasBodyParam('lock_tables');
@ -103,7 +104,7 @@ final class ExportController implements InvocableController
]);
// Check export type
if ($exportPlugin === null) {
if (! $exportPlugin instanceof ExportPlugin) {
$this->response->setRequestStatus(false);
$this->response->addHTML(Message::error(__('Bad type!'))->getDisplay());
@ -235,26 +236,24 @@ final class ExportController implements InvocableController
// Generate filename and mime type if needed
$mimeType = '';
if ($GLOBALS['asfile']) {
if (empty($rememberTemplate)) {
$rememberTemplate = '';
$filenameTemplate = $request->getParsedBodyParamAsString('filename_template');
if ((bool) $rememberTemplate) {
$this->export->rememberFilename($config, $GLOBALS['export_type'], $filenameTemplate);
}
[$filename, $mimeType] = $this->export->getFilenameAndMimetype(
$GLOBALS['export_type'],
$rememberTemplate,
$filename = $this->export->getFinalFilename(
$exportPlugin,
$GLOBALS['compression'],
$request->getParsedBodyParamAsString('filename_template'),
Sanitize::sanitizeFilename(Util::expandUserString($filenameTemplate), true),
);
$mimeType = $this->export->getMimeType($exportPlugin, $GLOBALS['compression']);
}
// For raw query export, filename will be export.extension
if ($GLOBALS['export_type'] === 'raw') {
[$filename] = $this->export->getFinalFilenameAndMimetypeForFilename(
$exportPlugin,
$GLOBALS['compression'],
'export',
);
$filename = $this->export->getFinalFilename($exportPlugin, $GLOBALS['compression'], 'export');
}
// Open file on server if needed

View File

@ -19,7 +19,6 @@ use PhpMyAdmin\MessageType;
use PhpMyAdmin\Plugins;
use PhpMyAdmin\Plugins\ExportPlugin;
use PhpMyAdmin\Plugins\SchemaPlugin;
use PhpMyAdmin\Sanitize;
use PhpMyAdmin\Table\Table;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
@ -279,20 +278,11 @@ class Export
return (int) $memoryLimit;
}
/**
* Returns the filename and MIME type for a compression and an export plugin
*
* @param ExportPlugin $exportPlugin the export plugin
* @param string $compression compression asked
* @param string $filename the filename
*
* @return string[] the filename and mime type
*/
public function getFinalFilenameAndMimetypeForFilename(
public function getFinalFilename(
ExportPlugin $exportPlugin,
string $compression,
string $filename,
): array {
): string {
// Grab basic dump extension and mime type
// Check if the user already added extension;
// get the substring where the extension would be if it was included
@ -303,62 +293,39 @@ class Export
$filename .= $requiredExtension;
}
$mediaType = $exportPlugin->getProperties()->getMimeType();
// If dump is going to be compressed, set correct mime_type and add
// compression to extension
// If dump is going to be compressed, add compression to extension
if ($compression === 'gzip') {
$filename .= '.gz';
$mediaType = 'application/x-gzip';
} elseif ($compression === 'zip') {
$filename .= '.zip';
$mediaType = 'application/zip';
}
return [$filename, $mediaType];
return $filename;
}
/**
* Return the filename and MIME type for export file
*
* @param string $exportType type of export
* @param string $rememberTemplate whether to remember template
* @param ExportPlugin $exportPlugin the export plugin
* @param string $compression compression asked
* @param string $filenameTemplate the filename template
*
* @return string[] the filename template and mime type
*/
public function getFilenameAndMimetype(
public function getMimeType(ExportPlugin $exportPlugin, string $compression): string
{
return match ($compression) {
'gzip' => 'application/x-gzip',
'zip' => 'application/zip',
default => $exportPlugin->getProperties()->getMimeType(),
};
}
public function rememberFilename(
Config $config,
string $exportType,
string $rememberTemplate,
ExportPlugin $exportPlugin,
string $compression,
string $filenameTemplate,
): array {
$config = Config::getInstance();
): void {
if ($exportType === 'server') {
if ($rememberTemplate !== '' && $rememberTemplate !== '0') {
$config->setUserValue('pma_server_filename_template', 'Export/file_template_server', $filenameTemplate);
}
$config->setUserValue('pma_server_filename_template', 'Export/file_template_server', $filenameTemplate);
} elseif ($exportType === 'database') {
if ($rememberTemplate !== '' && $rememberTemplate !== '0') {
$config->setUserValue('pma_db_filename_template', 'Export/file_template_database', $filenameTemplate);
}
$config->setUserValue('pma_db_filename_template', 'Export/file_template_database', $filenameTemplate);
} elseif ($exportType === 'raw') {
if ($rememberTemplate !== '' && $rememberTemplate !== '0') {
$config->setUserValue('pma_raw_filename_template', 'Export/file_template_raw', $filenameTemplate);
}
} elseif ($rememberTemplate !== '' && $rememberTemplate !== '0') {
$config->setUserValue('pma_raw_filename_template', 'Export/file_template_raw', $filenameTemplate);
} else {
$config->setUserValue('pma_table_filename_template', 'Export/file_template_table', $filenameTemplate);
}
$filename = Util::expandUserString($filenameTemplate);
// remove dots in filename (coming from either the template or already
// part of the filename) to avoid a remote code execution vulnerability
$filename = Sanitize::sanitizeFilename($filename, true);
return $this->getFinalFilenameAndMimetypeForFilename($exportPlugin, $compression, $filename);
}
/**

View File

@ -60,7 +60,7 @@ class ExportTest extends AbstractTestCase
self::assertSame($expected, $actual);
}
public function testGetFinalFilenameAndMimetypeForFilename(): void
public function testGetFinalFilename(): void
{
$dbi = $this->createDatabaseInterface();
DatabaseInterface::$instance = $dbi;
@ -70,16 +70,28 @@ class ExportTest extends AbstractTestCase
new Export($dbi),
new Transformations(),
);
$finalFileName = $export->getFinalFilenameAndMimetypeForFilename($exportPlugin, 'zip', 'myfilename');
self::assertSame(['myfilename.php.zip', 'application/zip'], $finalFileName);
$finalFileName = $export->getFinalFilenameAndMimetypeForFilename($exportPlugin, 'gzip', 'myfilename');
self::assertSame(['myfilename.php.gz', 'application/x-gzip'], $finalFileName);
$finalFileName = $export->getFinalFilenameAndMimetypeForFilename(
$exportPlugin,
'gzip',
'export.db1.table1.file',
$finalFileName = $export->getFinalFilename($exportPlugin, 'zip', 'myfilename');
self::assertSame('myfilename.php.zip', $finalFileName);
$finalFileName = $export->getFinalFilename($exportPlugin, 'gzip', 'myfilename');
self::assertSame('myfilename.php.gz', $finalFileName);
$finalFileName = $export->getFinalFilename($exportPlugin, 'gzip', 'export.db1.table1.file');
self::assertSame('export.db1.table1.file.php.gz', $finalFileName);
}
public function testGetMimeType(): void
{
$dbi = $this->createDatabaseInterface();
DatabaseInterface::$instance = $dbi;
$export = new Export($dbi);
$exportPlugin = new ExportPhparray(
new Relation($dbi),
new Export($dbi),
new Transformations(),
);
self::assertSame(['export.db1.table1.file.php.gz', 'application/x-gzip'], $finalFileName);
$mimeType = $export->getMimeType($exportPlugin, 'zip');
self::assertSame('application/zip', $mimeType);
$mimeType = $export->getMimeType($exportPlugin, 'gzip');
self::assertSame('application/x-gzip', $mimeType);
}
public function testExportDatabase(): void