diff options
8 files changed, 147 insertions, 22 deletions
diff --git a/libraries/classes/Controllers/Normalization/FirstNormalForm/FirstStepController.php b/libraries/classes/Controllers/Normalization/FirstNormalForm/FirstStepController.php new file mode 100644 index 0000000000..025760d602 --- /dev/null +++ b/libraries/classes/Controllers/Normalization/FirstNormalForm/FirstStepController.php @@ -0,0 +1,38 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Controllers\Normalization\FirstNormalForm; + +use PhpMyAdmin\Controllers\AbstractController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Normalization; +use PhpMyAdmin\ResponseRenderer; +use PhpMyAdmin\Template; + +use function in_array; + +final class FirstStepController extends AbstractController +{ + /** @var Normalization */ + private $normalization; + + public function __construct(ResponseRenderer $response, Template $template, Normalization $normalization) + { + parent::__construct($response, $template); + $this->normalization = $normalization; + } + + public function __invoke(ServerRequest $request): void + { + $this->addScriptFiles(['normalization.js', 'vendor/jquery/jquery.uitablefilter.js']); + + $normalForm = '1nf'; + if (isset($_POST['normalizeTo']) && in_array($_POST['normalizeTo'], ['1nf', '2nf', '3nf'])) { + $normalForm = $_POST['normalizeTo']; + } + + $html = $this->normalization->getHtmlFor1NFStep1($GLOBALS['db'], $GLOBALS['table'], $normalForm); + $this->response->addHTML($html); + } +} diff --git a/libraries/classes/Controllers/NormalizationController.php b/libraries/classes/Controllers/NormalizationController.php index 4f318806b4..859ff1610f 100644 --- a/libraries/classes/Controllers/NormalizationController.php +++ b/libraries/classes/Controllers/NormalizationController.php @@ -13,7 +13,6 @@ use PhpMyAdmin\Url; use function __; use function _pgettext; -use function in_array; use function intval; use function json_decode; use function json_encode; @@ -104,11 +103,6 @@ class NormalizationController extends AbstractController $this->addScriptFiles(['normalization.js', 'vendor/jquery/jquery.uitablefilter.js']); - $normalForm = '1nf'; - if (isset($_POST['normalizeTo']) && in_array($_POST['normalizeTo'], ['1nf', '2nf', '3nf'])) { - $normalForm = $_POST['normalizeTo']; - } - if (isset($_POST['createNewTables2NF'])) { $partialDependencies = json_decode($_POST['pd'], true); $tablesName = json_decode($_POST['newTablesName']); @@ -149,13 +143,6 @@ class NormalizationController extends AbstractController return; } - if (isset($_POST['step1'])) { - $html = $this->normalization->getHtmlFor1NFStep1($GLOBALS['db'], $GLOBALS['table'], $normalForm); - $this->response->addHTML($html); - - return; - } - if (isset($_POST['step2'])) { $res = $this->normalization->getHtmlContentsFor1NFStep2($GLOBALS['db'], $GLOBALS['table']); $this->response->addJSON($res); diff --git a/libraries/routes.php b/libraries/routes.php index 508c8deb63..27a509246f 100644 --- a/libraries/routes.php +++ b/libraries/routes.php @@ -21,6 +21,7 @@ use PhpMyAdmin\Controllers\LicenseController; use PhpMyAdmin\Controllers\LintController; use PhpMyAdmin\Controllers\LogoutController; use PhpMyAdmin\Controllers\NavigationController; +use PhpMyAdmin\Controllers\Normalization; use PhpMyAdmin\Controllers\NormalizationController; use PhpMyAdmin\Controllers\PhpInfoController; use PhpMyAdmin\Controllers\Preferences; @@ -129,7 +130,10 @@ return static function (RouteCollector $routes): void { $routes->addRoute(['GET', 'POST'], '/lint', LintController::class); $routes->addRoute(['GET', 'POST'], '/logout', LogoutController::class); $routes->addRoute(['GET', 'POST'], '/navigation', NavigationController::class); - $routes->addRoute(['GET', 'POST'], '/normalization', NormalizationController::class); + $routes->addGroup('/normalization', static function (RouteCollector $routes): void { + $routes->addRoute(['GET', 'POST'], '', NormalizationController::class); + $routes->post('/1nf/step1', Normalization\FirstNormalForm\FirstStepController::class); + }); $routes->get('/phpinfo', PhpInfoController::class); $routes->addGroup('/preferences', static function (RouteCollector $routes): void { $routes->addRoute(['GET', 'POST'], '/export', Preferences\ExportController::class); diff --git a/libraries/services_controllers.php b/libraries/services_controllers.php index d80d979aed..22aa34afb6 100644 --- a/libraries/services_controllers.php +++ b/libraries/services_controllers.php @@ -21,6 +21,7 @@ use PhpMyAdmin\Controllers\LicenseController; use PhpMyAdmin\Controllers\LintController; use PhpMyAdmin\Controllers\LogoutController; use PhpMyAdmin\Controllers\NavigationController; +use PhpMyAdmin\Controllers\Normalization; use PhpMyAdmin\Controllers\NormalizationController; use PhpMyAdmin\Controllers\PhpInfoController; use PhpMyAdmin\Controllers\Preferences; @@ -584,6 +585,14 @@ return [ '$relation' => '@relation', ], ], + Normalization\FirstNormalForm\FirstStepController::class => [ + 'class' => Normalization\FirstNormalForm\FirstStepController::class, + 'arguments' => [ + '$response' => '@response', + '$template' => '@template', + '$normalization' => '@normalization', + ], + ], NormalizationController::class => [ 'class' => NormalizationController::class, 'arguments' => [ diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 3528e6a840..76ea2a44ae 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -2399,8 +2399,16 @@ <code>$_POST['itemType']</code> </MixedArgument> </file> + <file src="libraries/classes/Controllers/Normalization/FirstNormalForm/FirstStepController.php"> + <MixedArgument occurrences="1"> + <code>$normalForm</code> + </MixedArgument> + <MixedAssignment occurrences="1"> + <code>$normalForm</code> + </MixedAssignment> + </file> <file src="libraries/classes/Controllers/NormalizationController.php"> - <MixedArgument occurrences="18"> + <MixedArgument occurrences="17"> <code>$_POST['newTables']</code> <code>$_POST['newTablesName']</code> <code>$_POST['pd']</code> @@ -2411,7 +2419,6 @@ <code>$newColumn</code> <code>$newTable</code> <code>$newtables</code> - <code>$normalForm</code> <code>$partialDependencies</code> <code>$partialDependencies</code> <code>$primary_columns</code> @@ -2420,12 +2427,11 @@ <code>$tables</code> <code>$tablesName</code> </MixedArgument> - <MixedAssignment occurrences="12"> + <MixedAssignment occurrences="11"> <code>$dependencies</code> <code>$newColumn</code> <code>$newTable</code> <code>$newtables</code> - <code>$normalForm</code> <code>$partialDependencies</code> <code>$partialDependencies</code> <code>$primary_columns</code> diff --git a/templates/table/normalization/normalization.twig b/templates/table/normalization/normalization.twig index f6afa0dfa6..381df0ca5f 100644 --- a/templates/table/normalization/normalization.twig +++ b/templates/table/normalization/normalization.twig @@ -1,6 +1,5 @@ -<form method="post" action="{{ url('/normalization') }}" name="normalize" id="normalizeTable"> +<form method="post" action="{{ url('/normalization/1nf/step1') }}" name="normalize" id="normalizeTable"> {{ get_hidden_inputs(db, table) }} - <input type="hidden" name="step1" value="1"> <fieldset class="pma-fieldset"> <legend>{{ 'Improve table structure (Normalization):'|trans }}</legend> diff --git a/test/classes/Controllers/Normalization/FirstNormalForm/FirstStepControllerTest.php b/test/classes/Controllers/Normalization/FirstNormalForm/FirstStepControllerTest.php new file mode 100644 index 0000000000..b8869b3251 --- /dev/null +++ b/test/classes/Controllers/Normalization/FirstNormalForm/FirstStepControllerTest.php @@ -0,0 +1,82 @@ +<?php + +declare(strict_types=1); + +namespace PhpMyAdmin\Tests\Controllers\Normalization\FirstNormalForm; + +use PhpMyAdmin\ConfigStorage\Relation; +use PhpMyAdmin\Controllers\Normalization\FirstNormalForm\FirstStepController; +use PhpMyAdmin\Http\ServerRequest; +use PhpMyAdmin\Normalization; +use PhpMyAdmin\Template; +use PhpMyAdmin\Tests\AbstractTestCase; +use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\Transformations; + +use function in_array; + +/** + * @covers \PhpMyAdmin\Controllers\Normalization\FirstNormalForm\FirstStepController + */ +class FirstStepControllerTest extends AbstractTestCase +{ + /** + * @psalm-param '1nf'|'2nf'|'3nf' $expectedNormalizeTo + * + * @dataProvider providerForTestDefault + */ + public function testDefault(?string $normalizeTo, string $expectedNormalizeTo): void + { + $GLOBALS['db'] = 'test_db'; + $GLOBALS['table'] = 'test_table'; + $_POST['normalizeTo'] = $normalizeTo; + + $dbiDummy = $this->createDbiDummy(); + $dbiDummy->addSelectDb('test_db'); + + $dbi = $this->createDatabaseInterface($dbiDummy); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new FirstStepController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + $files = $response->getHeader()->getScripts()->getFiles(); + $this->assertTrue( + in_array(['name' => 'normalization.js', 'fire' => 1], $files, true), + 'normalization.js script was not included in the response.' + ); + $this->assertTrue( + in_array(['name' => 'vendor/jquery/jquery.uitablefilter.js', 'fire' => 0], $files, true), + 'vendor/jquery/jquery.uitablefilter.js script was not included in the response.' + ); + + $output = $response->getHTMLResult(); + $this->assertStringContainsString('First step of normalization (1NF)', $output); + $this->assertStringContainsString( + '<div id=\'mainContent\' data-normalizeto=\'' . $expectedNormalizeTo . '\'>', + $output + ); + $this->assertStringContainsString('<option value=\'no_such_col\'>No such column</option>', $output); + } + + /** + * @return array<int, array{string|null, '1nf'|'2nf'|'3nf'}> + */ + public function providerForTestDefault(): iterable + { + return [ + [null, '1nf'], + ['', '1nf'], + ['invalid', '1nf'], + ['1nf', '1nf'], + ['2nf', '2nf'], + ['3nf', '3nf'], + ]; + } +} diff --git a/test/classes/Controllers/NormalizationControllerTest.php b/test/classes/Controllers/NormalizationControllerTest.php index 91630a026f..31a87b0676 100644 --- a/test/classes/Controllers/NormalizationControllerTest.php +++ b/test/classes/Controllers/NormalizationControllerTest.php @@ -238,12 +238,12 @@ class NormalizationControllerTest extends AbstractTestCase $output = $response->getHTMLResult(); $this->assertStringContainsString( - '<form method="post" action="index.php?route=/normalization&lang=en" name="normalize" id="normalizeTable"', + '<form method="post" action="index.php?route=/normalization/1nf/step1&lang=en"' + . ' name="normalize" id="normalizeTable"', $output ); $this->assertStringContainsString('<input type="hidden" name="db" value="test_db">', $output); $this->assertStringContainsString('<input type="hidden" name="table" value="test_table">', $output); - $this->assertStringContainsString('<input type="hidden" name="step1" value="1">', $output); $this->assertStringContainsString('type="radio" name="normalizeTo"', $output); $this->assertStringContainsString('id="normalizeToRadio1" value="1nf" checked>', $output); $this->assertStringContainsString('id="normalizeToRadio2" value="2nf">', $output); |