Skip to content

Commit 849495f

Browse files
Merge pull request #19835 from MauricioFauth/import-status-response-fix
Fix error with import status message
2 parents 487a5fb + ac39c52 commit 849495f

3 files changed

Lines changed: 120 additions & 7 deletions

File tree

psalm-baseline.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,9 +1440,6 @@
14401440
<MixedArrayAssignment>
14411441
<code><![CDATA[$_SESSION['Import_message']['message']]]></code>
14421442
</MixedArrayAssignment>
1443-
<PossiblyUnusedMethod>
1444-
<code><![CDATA[__construct]]></code>
1445-
</PossiblyUnusedMethod>
14461443
</file>
14471444
<file src="src/Controllers/LintController.php">
14481445
<MixedAssignment>

src/Controllers/Import/StatusController.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44

55
namespace PhpMyAdmin\Controllers\Import;
66

7+
use Fig\Http\Message\StatusCodeInterface;
78
use PhpMyAdmin\Controllers\InvocableController;
89
use PhpMyAdmin\Core;
10+
use PhpMyAdmin\Http\Factory\ResponseFactory;
911
use PhpMyAdmin\Http\Response;
1012
use PhpMyAdmin\Http\ServerRequest;
1113
use PhpMyAdmin\Import\Ajax;
1214
use PhpMyAdmin\Message;
13-
use PhpMyAdmin\ResponseRenderer;
1415
use PhpMyAdmin\Routing\Route;
1516
use PhpMyAdmin\Template;
1617

@@ -29,6 +30,12 @@
2930
#[Route('/import-status', ['GET', 'POST'])]
3031
class StatusController implements InvocableController
3132
{
33+
/** Time to wait before checking for the $_SESSION variable. Default is 0.3 seconds. */
34+
private static int $sleepMicroseconds = 300000;
35+
36+
/** Time to wait before rechecking for the $_SESSION variable. Default is 0.25 seconds. */
37+
private static int $sleepMicrosecondsRetry = 250000;
38+
3239
public function __construct(private readonly Template $template)
3340
{
3441
}
@@ -47,7 +54,7 @@ public function __invoke(ServerRequest $request): Response
4754
header('Content-type: text/html');
4855

4956
// wait 0.3 sec before we check for $_SESSION variable
50-
usleep(300000);
57+
usleep(self::$sleepMicroseconds);
5158

5259
$maximumTime = ini_get('max_execution_time');
5360
$timestamp = time();
@@ -56,7 +63,7 @@ public function __invoke(ServerRequest $request): Response
5663
// close session before sleeping
5764
session_write_close();
5865
// sleep
59-
usleep(250000); // 0.25 sec
66+
usleep(self::$sleepMicrosecondsRetry);
6067
// reopen session
6168
session_start();
6269

@@ -79,6 +86,6 @@ public function __invoke(ServerRequest $request): Response
7986
Ajax::status($request->getQueryParam('id'));
8087
}
8188

82-
return ResponseRenderer::getInstance()->response();
89+
return ResponseFactory::create()->createResponse(StatusCodeInterface::STATUS_OK, 'OK');
8390
}
8491
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpMyAdmin\Tests\Controllers\Import;
6+
7+
use Fig\Http\Message\StatusCodeInterface;
8+
use PhpMyAdmin\Config;
9+
use PhpMyAdmin\Controllers\Import\StatusController;
10+
use PhpMyAdmin\Http\Factory\ServerRequestFactory;
11+
use PhpMyAdmin\Import\Ajax;
12+
use PhpMyAdmin\Message;
13+
use PhpMyAdmin\Plugins\Import\Upload\UploadNoplugin;
14+
use PhpMyAdmin\Template;
15+
use PhpMyAdmin\Tests\AbstractTestCase;
16+
use PHPUnit\Framework\Attributes\CoversClass;
17+
use ReflectionProperty;
18+
19+
use function ini_get;
20+
use function ini_set;
21+
22+
#[CoversClass(StatusController::class)]
23+
final class StatusControllerTest extends AbstractTestCase
24+
{
25+
public function testUploadStatus(): void
26+
{
27+
$_SESSION[Ajax::SESSION_KEY] = [
28+
'handler' => UploadNoplugin::class,
29+
'abc1234567890' => [
30+
'id' => 'abc1234567890',
31+
'finished' => false,
32+
'percent' => 0,
33+
'total' => 0,
34+
'complete' => 0,
35+
'plugin' => 'noplugin',
36+
],
37+
];
38+
39+
$request = ServerRequestFactory::create()->createServerRequest('GET', 'https://example.com/')->withQueryParams([
40+
'import_status' => '1',
41+
'id' => 'abc1234567890',
42+
]);
43+
44+
$controller = new StatusController(new Template(new Config()));
45+
$response = $controller($request);
46+
47+
self::assertSame(
48+
'{"id":"abc1234567890","finished":false,"percent":0,"total":0,"complete":0,"plugin":"noplugin"}',
49+
self::getActualOutputForAssertion(),
50+
);
51+
self::assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode());
52+
self::assertSame('', (string) $response->getBody());
53+
}
54+
55+
public function testMessage(): void
56+
{
57+
(new ReflectionProperty(StatusController::class, 'sleepMicroseconds'))->setValue(null, 1);
58+
59+
$message = Message::success('Import has been successfully finished, 2 queries executed. (file.sql)');
60+
$_SESSION['Import_message'] = [];
61+
$_SESSION['Import_message']['message'] = $message->getDisplay();
62+
$_SESSION['Import_message']['go_back_url'] = 'https://example.com/index.php?route=/server/import';
63+
64+
$request = ServerRequestFactory::create()->createServerRequest('GET', 'https://example.com/')->withQueryParams([
65+
'import_status' => '1',
66+
'message' => '1',
67+
]);
68+
69+
$controller = new StatusController(new Template(new Config()));
70+
$response = $controller($request);
71+
72+
$expected = $message->getDisplay();
73+
$expected .= <<<'HTML'
74+
<div class="card"><div class="card-body">
75+
[ <a href="https://example.com/index.php?route=/server/import">Back</a> ]
76+
</div></div>
77+
78+
HTML;
79+
self::assertSame($expected, self::getActualOutputForAssertion());
80+
self::assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode());
81+
self::assertSame('', (string) $response->getBody());
82+
}
83+
84+
public function testMessageProgressTimeout(): void
85+
{
86+
(new ReflectionProperty(StatusController::class, 'sleepMicroseconds'))->setValue(null, 1);
87+
(new ReflectionProperty(StatusController::class, 'sleepMicrosecondsRetry'))->setValue(null, 1);
88+
89+
$maxExecutionTime = ini_get('max_execution_time');
90+
ini_set('max_execution_time', '0');
91+
92+
$message = Message::error('Could not load the progress of the import.');
93+
$_SESSION['Import_message'] = [];
94+
95+
$request = ServerRequestFactory::create()->createServerRequest('GET', 'https://example.com/')->withQueryParams([
96+
'import_status' => '1',
97+
'message' => '1',
98+
]);
99+
100+
$controller = new StatusController(new Template(new Config()));
101+
$response = $controller($request);
102+
103+
self::assertSame($message->getDisplay(), self::getActualOutputForAssertion());
104+
self::assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode());
105+
self::assertSame('', (string) $response->getBody());
106+
107+
ini_set('max_execution_time', $maxExecutionTime);
108+
}
109+
}

0 commit comments

Comments
 (0)