Skip to content

Commit 234809d

Browse files
Merge pull request #18599 from MauricioFauth/export-show-page-redirect
Change export to server file to use redirection after save
2 parents eff6872 + f3b57f6 commit 234809d

6 files changed

Lines changed: 131 additions & 43 deletions

File tree

libraries/classes/Controllers/Export/ExportController.php

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -275,15 +275,16 @@ public function __invoke(ServerRequest $request): void
275275

276276
// Open file on server if needed
277277
if ($GLOBALS['save_on_server']) {
278-
[
279-
$GLOBALS['save_filename'],
280-
$GLOBALS['message'],
281-
$GLOBALS['file_handle'],
282-
] = $this->export->openFile($filename, $isQuickExport);
278+
[$GLOBALS['save_filename'], $message, $GLOBALS['file_handle']] = $this->export->openFile(
279+
$filename,
280+
$isQuickExport,
281+
);
283282

284283
// problem opening export file on server?
285-
if (! empty($GLOBALS['message'])) {
286-
$this->export->showPage($GLOBALS['export_type']);
284+
if ($message !== null) {
285+
$location = $this->export->getPageLocationAndSaveMessage($GLOBALS['export_type'], $message);
286+
$this->response->header('Location: ' . $location);
287+
$this->response->setHttpResponseCode(302);
287288

288289
return;
289290
}
@@ -487,8 +488,10 @@ public function __invoke(ServerRequest $request): void
487488
// Ignore
488489
}
489490

490-
if ($GLOBALS['save_on_server'] && ! empty($GLOBALS['message'])) {
491-
$this->export->showPage($GLOBALS['export_type']);
491+
if ($GLOBALS['save_on_server'] && $GLOBALS['message'] instanceof Message) {
492+
$location = $this->export->getPageLocationAndSaveMessage($GLOBALS['export_type'], $GLOBALS['message']);
493+
$this->response->header('Location: ' . $location);
494+
$this->response->setHttpResponseCode(302);
492495

493496
return;
494497
}
@@ -534,12 +537,14 @@ public function __invoke(ServerRequest $request): void
534537

535538
/* If we saved on server, we have to close file now */
536539
if ($GLOBALS['save_on_server']) {
537-
$GLOBALS['message'] = $this->export->closeFile(
540+
$message = $this->export->closeFile(
538541
$GLOBALS['file_handle'],
539542
$this->export->dumpBuffer,
540543
$GLOBALS['save_filename'],
541544
);
542-
$this->export->showPage($GLOBALS['export_type']);
545+
$location = $this->export->getPageLocationAndSaveMessage($GLOBALS['export_type'], $message);
546+
$this->response->header('Location: ' . $location);
547+
$this->response->setHttpResponseCode(302);
543548

544549
return;
545550
}

libraries/classes/Export/Export.php

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,10 @@
77

88
namespace PhpMyAdmin\Export;
99

10-
use PhpMyAdmin\Application;
11-
use PhpMyAdmin\Controllers\Database\ExportController as DatabaseExportController;
12-
use PhpMyAdmin\Controllers\Server\ExportController as ServerExportController;
13-
use PhpMyAdmin\Controllers\Table\ExportController as TableExportController;
14-
use PhpMyAdmin\Core;
1510
use PhpMyAdmin\DatabaseInterface;
1611
use PhpMyAdmin\Encoding;
1712
use PhpMyAdmin\Exceptions\ExportException;
13+
use PhpMyAdmin\FlashMessages;
1814
use PhpMyAdmin\Identifiers\DatabaseName;
1915
use PhpMyAdmin\Message;
2016
use PhpMyAdmin\Plugins;
@@ -396,12 +392,12 @@ public function getFilenameAndMimetype(
396392
* @param string $filename the export filename
397393
* @param bool $quickExport whether it's a quick export or not
398394
*
399-
* @return mixed[] the full save filename, possible message and the file handle
395+
* @psalm-return array{string, Message|null, resource|null}
400396
*/
401397
public function openFile(string $filename, bool $quickExport): array
402398
{
403399
$fileHandle = null;
404-
$message = '';
400+
$message = null;
405401
$doNotSaveItOver = true;
406402

407403
if (isset($_POST['quick_export_onserver_overwrite'])) {
@@ -432,8 +428,8 @@ public function openFile(string $filename, bool $quickExport): array
432428
$message->addParam($saveFilename);
433429
} else {
434430
$fileHandle = @fopen($saveFilename, 'w');
435-
436431
if ($fileHandle === false) {
432+
$fileHandle = null;
437433
$message = Message::error(
438434
__(
439435
'The web server does not have permission to save the file %s.',
@@ -1075,33 +1071,23 @@ public function exportTable(
10751071
/**
10761072
* Loads correct page after doing export
10771073
*/
1078-
public function showPage(string $exportType): void
1074+
public function getPageLocationAndSaveMessage(string $exportType, Message $message): string
10791075
{
1080-
$GLOBALS['active_page'] ??= null;
1081-
$request = Application::getRequest();
1082-
$container = Core::getContainerBuilder();
1083-
if ($exportType === 'server') {
1084-
$GLOBALS['active_page'] = Url::getFromRoute('/server/export');
1085-
/** @var ServerExportController $controller */
1086-
$controller = $container->get(ServerExportController::class);
1087-
$controller($request);
1076+
(new FlashMessages())->addMessage($message->isError() ? 'danger' : 'success', $message->getMessage());
10881077

1089-
return;
1078+
if ($exportType === 'server') {
1079+
return 'index.php?route=/server/export' . Url::getCommonRaw([], '&');
10901080
}
10911081

10921082
if ($exportType === 'database') {
1093-
$GLOBALS['active_page'] = Url::getFromRoute('/database/export');
1094-
/** @var DatabaseExportController $controller */
1095-
$controller = $container->get(DatabaseExportController::class);
1096-
$controller($request);
1083+
$params = ['db' => $GLOBALS['db']];
10971084

1098-
return;
1085+
return 'index.php?route=/database/export' . Url::getCommonRaw($params, '&');
10991086
}
11001087

1101-
$GLOBALS['active_page'] = Url::getFromRoute('/table/export');
1102-
/** @var TableExportController $controller */
1103-
$controller = $container->get(TableExportController::class);
1104-
$controller($request);
1088+
$params = ['db' => $GLOBALS['db'], 'table' => $GLOBALS['table'], 'single_table' => 'true'];
1089+
1090+
return 'index.php?route=/table/export' . Url::getCommonRaw($params, '&');
11051091
}
11061092

11071093
/**

phpstan-baseline.neon

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4122,7 +4122,7 @@ parameters:
41224122

41234123
-
41244124
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
4125-
count: 7
4125+
count: 5
41264126
path: libraries/classes/Controllers/Export/ExportController.php
41274127

41284128
-
@@ -4181,7 +4181,7 @@ parameters:
41814181
path: libraries/classes/Controllers/Export/ExportController.php
41824182

41834183
-
4184-
message: "#^Parameter \\#1 \\$exportType of method PhpMyAdmin\\\\Export\\\\Export\\:\\:showPage\\(\\) expects string, mixed given\\.$#"
4184+
message: "#^Parameter \\#1 \\$exportType of method PhpMyAdmin\\\\Export\\\\Export\\:\\:getPageLocationAndSaveMessage\\(\\) expects string, mixed given\\.$#"
41854185
count: 3
41864186
path: libraries/classes/Controllers/Export/ExportController.php
41874187

@@ -13310,6 +13310,11 @@ parameters:
1331013310
count: 2
1331113311
path: libraries/classes/Export/Export.php
1331213312

13313+
-
13314+
message: "#^Parameter \\#1 \\$params of static method PhpMyAdmin\\\\Url\\:\\:getCommonRaw\\(\\) expects array\\<int\\|string, bool\\|int\\|string\\>, array\\<string, mixed\\> given\\.$#"
13315+
count: 2
13316+
path: libraries/classes/Export/Export.php
13317+
1331313318
-
1331413319
message: "#^Parameter \\#1 \\$str of method PhpMyAdmin\\\\DatabaseInterface\\:\\:quoteString\\(\\) expects string, mixed given\\.$#"
1331513320
count: 1

psalm-baseline.xml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,7 +1766,6 @@
17661766
</ArgumentTypeCoercion>
17671767
<InvalidArgument>
17681768
<code><![CDATA[$GLOBALS['asfile']]]></code>
1769-
<code><![CDATA[$GLOBALS['file_handle']]]></code>
17701769
</InvalidArgument>
17711770
<InvalidArrayOffset>
17721771
<code><![CDATA[$GLOBALS['active_page']]]></code>
@@ -1946,6 +1945,7 @@
19461945
<code>exportHeader</code>
19471946
</MixedMethodCall>
19481947
<PossiblyInvalidArgument>
1948+
<code><![CDATA[$GLOBALS['file_handle']]]></code>
19491949
<code><![CDATA[$this->export->dumpBuffer]]></code>
19501950
<code><![CDATA[$this->export->dumpBuffer]]></code>
19511951
<code>$whatStrucOrData</code>
@@ -6063,7 +6063,6 @@
60636063
</file>
60646064
<file src="libraries/classes/Export/Export.php">
60656065
<InvalidArrayOffset>
6066-
<code><![CDATA[$GLOBALS['active_page']]]></code>
60676066
<code><![CDATA[$GLOBALS['cfg']['SaveDir']]]></code>
60686067
<code><![CDATA[$GLOBALS['save_filename']]]></code>
60696068
<code><![CDATA[$GLOBALS['sql_create_table']]]></code>
@@ -6112,7 +6111,6 @@
61126111
<code><![CDATA[$aliases[$dbName]['tables'][$tableName]['columns'][$col]]]></code>
61136112
</MixedArrayOffset>
61146113
<MixedAssignment>
6115-
<code><![CDATA[$GLOBALS['active_page']]]></code>
61166114
<code><![CDATA[$GLOBALS['save_filename']]]></code>
61176115
<code><![CDATA[$GLOBALS['time_start']]]></code>
61186116
<code><![CDATA[$aliases[$dbName]['alias']]]></code>

templates/export.twig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@
77
{{ page_settings_error_html|raw }}
88
{{ page_settings_html|raw }}
99

10+
{% for flash_key, flash_messages in flash() %}
11+
{% for flash_message in flash_messages %}
12+
<div class="alert alert-{{ flash_key }}" role="alert">
13+
{{ flash_message }}
14+
</div>
15+
{% endfor %}
16+
{% endfor %}
17+
1018
{% block message %}{% endblock %}
1119

1220
{% if templates.is_enabled %}

test/classes/Export/ExportTest.php

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66

77
use PhpMyAdmin\ConfigStorage\Relation;
88
use PhpMyAdmin\Export\Export;
9+
use PhpMyAdmin\FlashMessages;
910
use PhpMyAdmin\Identifiers\DatabaseName;
11+
use PhpMyAdmin\Message;
1012
use PhpMyAdmin\Plugins\Export\ExportPhparray;
1113
use PhpMyAdmin\Plugins\Export\ExportSql;
1214
use PhpMyAdmin\Tests\AbstractTestCase;
@@ -225,4 +227,88 @@ public function testExportServer(): void
225227

226228
$this->assertSame(htmlspecialchars($expected, ENT_COMPAT), $this->getActualOutputForAssertion());
227229
}
230+
231+
public function testGetPageLocationAndSaveMessageForServerExportWithError(): void
232+
{
233+
$GLOBALS['lang'] = 'en';
234+
$GLOBALS['server'] = 2;
235+
$_SESSION = [];
236+
$dbi = $this->createDatabaseInterface();
237+
$export = new Export($dbi);
238+
$location = $export->getPageLocationAndSaveMessage('server', Message::error('Error message!'));
239+
$this->assertSame('index.php?route=/server/export&server=2&lang=en', $location);
240+
$this->assertSame(['danger' => ['Error message!']], (new FlashMessages())->getMessages());
241+
}
242+
243+
public function testGetPageLocationAndSaveMessageForServerExportWithSuccess(): void
244+
{
245+
$GLOBALS['lang'] = 'en';
246+
$GLOBALS['server'] = 2;
247+
$_SESSION = [];
248+
$dbi = $this->createDatabaseInterface();
249+
$export = new Export($dbi);
250+
$location = $export->getPageLocationAndSaveMessage('server', Message::success('Success message!'));
251+
$this->assertSame('index.php?route=/server/export&server=2&lang=en', $location);
252+
$this->assertSame(['success' => ['Success message!']], (new FlashMessages())->getMessages());
253+
}
254+
255+
public function testGetPageLocationAndSaveMessageForDatabaseExportWithError(): void
256+
{
257+
$GLOBALS['lang'] = 'en';
258+
$GLOBALS['server'] = 2;
259+
$GLOBALS['db'] = 'test_db';
260+
$_SESSION = [];
261+
$dbi = $this->createDatabaseInterface();
262+
$export = new Export($dbi);
263+
$location = $export->getPageLocationAndSaveMessage('database', Message::error('Error message!'));
264+
$this->assertSame('index.php?route=/database/export&db=test_db&server=2&lang=en', $location);
265+
$this->assertSame(['danger' => ['Error message!']], (new FlashMessages())->getMessages());
266+
}
267+
268+
public function testGetPageLocationAndSaveMessageForDatabaseExportWithSuccess(): void
269+
{
270+
$GLOBALS['lang'] = 'en';
271+
$GLOBALS['server'] = 2;
272+
$GLOBALS['db'] = 'test_db';
273+
$_SESSION = [];
274+
$dbi = $this->createDatabaseInterface();
275+
$export = new Export($dbi);
276+
$location = $export->getPageLocationAndSaveMessage('database', Message::success('Success message!'));
277+
$this->assertSame('index.php?route=/database/export&db=test_db&server=2&lang=en', $location);
278+
$this->assertSame(['success' => ['Success message!']], (new FlashMessages())->getMessages());
279+
}
280+
281+
public function testGetPageLocationAndSaveMessageForTableExportWithError(): void
282+
{
283+
$GLOBALS['lang'] = 'en';
284+
$GLOBALS['server'] = 2;
285+
$GLOBALS['db'] = 'test_db';
286+
$GLOBALS['table'] = 'test_table';
287+
$_SESSION = [];
288+
$dbi = $this->createDatabaseInterface();
289+
$export = new Export($dbi);
290+
$location = $export->getPageLocationAndSaveMessage('table', Message::error('Error message!'));
291+
$this->assertSame(
292+
'index.php?route=/table/export&db=test_db&table=test_table&single_table=true&server=2&lang=en',
293+
$location,
294+
);
295+
$this->assertSame(['danger' => ['Error message!']], (new FlashMessages())->getMessages());
296+
}
297+
298+
public function testGetPageLocationAndSaveMessageForTableExportWithSuccess(): void
299+
{
300+
$GLOBALS['lang'] = 'en';
301+
$GLOBALS['server'] = 2;
302+
$GLOBALS['db'] = 'test_db';
303+
$GLOBALS['table'] = 'test_table';
304+
$_SESSION = [];
305+
$dbi = $this->createDatabaseInterface();
306+
$export = new Export($dbi);
307+
$location = $export->getPageLocationAndSaveMessage('table', Message::success('Success message!'));
308+
$this->assertSame(
309+
'index.php?route=/table/export&db=test_db&table=test_table&single_table=true&server=2&lang=en',
310+
$location,
311+
);
312+
$this->assertSame(['success' => ['Success message!']], (new FlashMessages())->getMessages());
313+
}
228314
}

0 commit comments

Comments
 (0)