From 398bdae484ae6fdb63b7ee04db788d31c358ff40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Meneghini=20Fauth?= Date: Thu, 28 Jul 2022 18:33:34 -0300 Subject: [PATCH 1/7] Extract normalization 1NF step 1 action MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maurício Meneghini Fauth --- .../FirstNormalForm/FirstStepController.php | 38 +++++++++ .../Controllers/NormalizationController.php | 13 --- libraries/routes.php | 6 +- libraries/services_controllers.php | 9 ++ psalm-baseline.xml | 14 +++- .../table/normalization/normalization.twig | 3 +- .../FirstStepControllerTest.php | 82 +++++++++++++++++++ .../NormalizationControllerTest.php | 4 +- 8 files changed, 147 insertions(+), 22 deletions(-) create mode 100644 libraries/classes/Controllers/Normalization/FirstNormalForm/FirstStepController.php create mode 100644 test/classes/Controllers/Normalization/FirstNormalForm/FirstStepControllerTest.php 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 @@ +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 @@ $_POST['itemType'] + + + $normalForm + + + $normalForm + + - + $_POST['newTables'] $_POST['newTablesName'] $_POST['pd'] @@ -2411,7 +2419,6 @@ $newColumn $newTable $newtables - $normalForm $partialDependencies $partialDependencies $primary_columns @@ -2420,12 +2427,11 @@ $tables $tablesName - + $dependencies $newColumn $newTable $newtables - $normalForm $partialDependencies $partialDependencies $primary_columns 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 @@ -
+ {{ get_hidden_inputs(db, table) }} -
{{ 'Improve table structure (Normalization):'|trans }} 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 @@ +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( + '
', + $output + ); + $this->assertStringContainsString('', $output); + } + + /** + * @return array + */ + 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( - 'assertStringContainsString('', $output); $this->assertStringContainsString('', $output); - $this->assertStringContainsString('', $output); $this->assertStringContainsString('type="radio" name="normalizeTo"', $output); $this->assertStringContainsString('id="normalizeToRadio1" value="1nf" checked>', $output); $this->assertStringContainsString('id="normalizeToRadio2" value="2nf">', $output); From 6e8600f321804d23999af7f06f945ac121b56139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Meneghini=20Fauth?= Date: Thu, 28 Jul 2022 22:52:28 -0300 Subject: [PATCH 2/7] Extract normalization 1NF step 2 action MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maurício Meneghini Fauth --- js/src/normalization.js | 5 +- .../FirstNormalForm/SecondStepController.php | 29 ++++++++++++ .../Controllers/NormalizationController.php | 7 --- libraries/routes.php | 1 + libraries/services_controllers.php | 8 ++++ .../SecondStepControllerTest.php | 46 +++++++++++++++++++ 6 files changed, 86 insertions(+), 10 deletions(-) create mode 100644 libraries/classes/Controllers/Normalization/FirstNormalForm/SecondStepController.php create mode 100644 test/classes/Controllers/Normalization/FirstNormalForm/SecondStepControllerTest.php diff --git a/js/src/normalization.js b/js/src/normalization.js index b3ba87a48a..86b83d9efe 100644 --- a/js/src/normalization.js +++ b/js/src/normalization.js @@ -181,13 +181,12 @@ function goToStep3 () { function goToStep2 (extra) { $.post( - 'index.php?route=/normalization', + 'index.php?route=/normalization/1nf/step2', { 'ajax_request': true, 'db': window.CommonParams.get('db'), 'table': window.CommonParams.get('table'), - 'server': window.CommonParams.get('server'), - 'step2': true + 'server': window.CommonParams.get('server') }, function (data) { $('#mainContent legend').html(data.legendText); $('#mainContent h4').html(data.headText); diff --git a/libraries/classes/Controllers/Normalization/FirstNormalForm/SecondStepController.php b/libraries/classes/Controllers/Normalization/FirstNormalForm/SecondStepController.php new file mode 100644 index 0000000000..630f117182 --- /dev/null +++ b/libraries/classes/Controllers/Normalization/FirstNormalForm/SecondStepController.php @@ -0,0 +1,29 @@ +normalization = $normalization; + } + + public function __invoke(ServerRequest $request): void + { + $res = $this->normalization->getHtmlContentsFor1NFStep2($GLOBALS['db'], $GLOBALS['table']); + $this->response->addJSON($res); + } +} diff --git a/libraries/classes/Controllers/NormalizationController.php b/libraries/classes/Controllers/NormalizationController.php index 859ff1610f..97e7f74433 100644 --- a/libraries/classes/Controllers/NormalizationController.php +++ b/libraries/classes/Controllers/NormalizationController.php @@ -143,13 +143,6 @@ class NormalizationController extends AbstractController return; } - if (isset($_POST['step2'])) { - $res = $this->normalization->getHtmlContentsFor1NFStep2($GLOBALS['db'], $GLOBALS['table']); - $this->response->addJSON($res); - - return; - } - if (isset($_POST['step3'])) { $res = $this->normalization->getHtmlContentsFor1NFStep3($GLOBALS['db'], $GLOBALS['table']); $this->response->addJSON($res); diff --git a/libraries/routes.php b/libraries/routes.php index 27a509246f..3b397d0a3b 100644 --- a/libraries/routes.php +++ b/libraries/routes.php @@ -133,6 +133,7 @@ return static function (RouteCollector $routes): void { $routes->addGroup('/normalization', static function (RouteCollector $routes): void { $routes->addRoute(['GET', 'POST'], '', NormalizationController::class); $routes->post('/1nf/step1', Normalization\FirstNormalForm\FirstStepController::class); + $routes->post('/1nf/step2', Normalization\FirstNormalForm\SecondStepController::class); }); $routes->get('/phpinfo', PhpInfoController::class); $routes->addGroup('/preferences', static function (RouteCollector $routes): void { diff --git a/libraries/services_controllers.php b/libraries/services_controllers.php index 22aa34afb6..1c56d43e66 100644 --- a/libraries/services_controllers.php +++ b/libraries/services_controllers.php @@ -593,6 +593,14 @@ return [ '$normalization' => '@normalization', ], ], + Normalization\FirstNormalForm\SecondStepController::class => [ + 'class' => Normalization\FirstNormalForm\SecondStepController::class, + 'arguments' => [ + '$response' => '@response', + '$template' => '@template', + '$normalization' => '@normalization', + ], + ], NormalizationController::class => [ 'class' => NormalizationController::class, 'arguments' => [ diff --git a/test/classes/Controllers/Normalization/FirstNormalForm/SecondStepControllerTest.php b/test/classes/Controllers/Normalization/FirstNormalForm/SecondStepControllerTest.php new file mode 100644 index 0000000000..edce909046 --- /dev/null +++ b/test/classes/Controllers/Normalization/FirstNormalForm/SecondStepControllerTest.php @@ -0,0 +1,46 @@ +createDatabaseInterface(); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new SecondStepController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + $this->assertSame([ + 'legendText' => 'Step 1.2 Have a primary key', + 'headText' => 'Primary key already exists.', + 'subText' => 'Taking you to next step…', + 'hasPrimaryKey' => '1', + 'extra' => '', + ], $response->getJSONResult()); + } +} From 08297d96b8c1dae5b9ee82c96b73f68ac3523136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Meneghini=20Fauth?= Date: Fri, 29 Jul 2022 19:03:35 -0300 Subject: [PATCH 3/7] Extract normalization 1NF step 3 action MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maurício Meneghini Fauth --- js/src/normalization.js | 3 +- .../FirstNormalForm/ThirdStepController.php | 29 +++++++++++ .../Controllers/NormalizationController.php | 7 --- libraries/routes.php | 1 + libraries/services_controllers.php | 8 +++ .../ThirdStepControllerTest.php | 51 +++++++++++++++++++ 6 files changed, 90 insertions(+), 9 deletions(-) create mode 100644 libraries/classes/Controllers/Normalization/FirstNormalForm/ThirdStepController.php create mode 100644 test/classes/Controllers/Normalization/FirstNormalForm/ThirdStepControllerTest.php diff --git a/js/src/normalization.js b/js/src/normalization.js index 86b83d9efe..d704912efc 100644 --- a/js/src/normalization.js +++ b/js/src/normalization.js @@ -157,13 +157,12 @@ window.goToStep4 = goToStep4; function goToStep3 () { $.post( - 'index.php?route=/normalization', + 'index.php?route=/normalization/1nf/step3', { 'ajax_request': true, 'db': window.CommonParams.get('db'), 'table': window.CommonParams.get('table'), 'server': window.CommonParams.get('server'), - 'step3': true }, function (data) { $('#mainContent legend').html(data.legendText); $('#mainContent h4').html(data.headText); diff --git a/libraries/classes/Controllers/Normalization/FirstNormalForm/ThirdStepController.php b/libraries/classes/Controllers/Normalization/FirstNormalForm/ThirdStepController.php new file mode 100644 index 0000000000..068a154d93 --- /dev/null +++ b/libraries/classes/Controllers/Normalization/FirstNormalForm/ThirdStepController.php @@ -0,0 +1,29 @@ +normalization = $normalization; + } + + public function __invoke(ServerRequest $request): void + { + $res = $this->normalization->getHtmlContentsFor1NFStep3($GLOBALS['db'], $GLOBALS['table']); + $this->response->addJSON($res); + } +} diff --git a/libraries/classes/Controllers/NormalizationController.php b/libraries/classes/Controllers/NormalizationController.php index 97e7f74433..13398e77ab 100644 --- a/libraries/classes/Controllers/NormalizationController.php +++ b/libraries/classes/Controllers/NormalizationController.php @@ -143,13 +143,6 @@ class NormalizationController extends AbstractController return; } - if (isset($_POST['step3'])) { - $res = $this->normalization->getHtmlContentsFor1NFStep3($GLOBALS['db'], $GLOBALS['table']); - $this->response->addJSON($res); - - return; - } - if (isset($_POST['step4'])) { $res = $this->normalization->getHtmlContentsFor1NFStep4($GLOBALS['db'], $GLOBALS['table']); $this->response->addJSON($res); diff --git a/libraries/routes.php b/libraries/routes.php index 3b397d0a3b..b1da0f3dc5 100644 --- a/libraries/routes.php +++ b/libraries/routes.php @@ -134,6 +134,7 @@ return static function (RouteCollector $routes): void { $routes->addRoute(['GET', 'POST'], '', NormalizationController::class); $routes->post('/1nf/step1', Normalization\FirstNormalForm\FirstStepController::class); $routes->post('/1nf/step2', Normalization\FirstNormalForm\SecondStepController::class); + $routes->post('/1nf/step3', Normalization\FirstNormalForm\ThirdStepController::class); }); $routes->get('/phpinfo', PhpInfoController::class); $routes->addGroup('/preferences', static function (RouteCollector $routes): void { diff --git a/libraries/services_controllers.php b/libraries/services_controllers.php index 1c56d43e66..9ee26c2692 100644 --- a/libraries/services_controllers.php +++ b/libraries/services_controllers.php @@ -601,6 +601,14 @@ return [ '$normalization' => '@normalization', ], ], + Normalization\FirstNormalForm\ThirdStepController::class => [ + 'class' => Normalization\FirstNormalForm\ThirdStepController::class, + 'arguments' => [ + '$response' => '@response', + '$template' => '@template', + '$normalization' => '@normalization', + ], + ], NormalizationController::class => [ 'class' => NormalizationController::class, 'arguments' => [ diff --git a/test/classes/Controllers/Normalization/FirstNormalForm/ThirdStepControllerTest.php b/test/classes/Controllers/Normalization/FirstNormalForm/ThirdStepControllerTest.php new file mode 100644 index 0000000000..0b06272051 --- /dev/null +++ b/test/classes/Controllers/Normalization/FirstNormalForm/ThirdStepControllerTest.php @@ -0,0 +1,51 @@ +createDbiDummy(); + $dbiDummy->addSelectDb('test_db'); + + $dbi = $this->createDatabaseInterface($dbiDummy); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new ThirdStepController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + // phpcs:disable Generic.Files.LineLength.TooLong + $this->assertSame([ + 'legendText' => 'Step 1.3 Move repeating groups', + 'headText' => 'Do you have a group of two or more columns that are closely related and are all repeating the same attribute? For example, a table that holds data on books might have columns such as book_id, author1, author2, author3 and so on which form a repeating group. In this case a new table (book_id, author) should be created.', + 'subText' => 'Check the columns which form a repeating group. If no such group, click on \'No repeating group\'', + 'extra' => 'id [ int(11) ]
name [ varchar(20) ]
datetimefield [ datetime ]

', + 'primary_key' => '["id"]', + ], $response->getJSONResult()); + // phpcs:enable + } +} From bcb02c2e0149f95e88b207b7206a6da35362a04a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Meneghini=20Fauth?= Date: Fri, 29 Jul 2022 20:11:56 -0300 Subject: [PATCH 4/7] Extract normalization 1NF step 4 action MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maurício Meneghini Fauth --- js/src/normalization.js | 3 +- .../FirstNormalForm/FourthStepController.php | 29 +++++++++++ .../Controllers/NormalizationController.php | 7 --- libraries/routes.php | 1 + libraries/services_controllers.php | 8 +++ .../FourthStepControllerTest.php | 50 +++++++++++++++++++ 6 files changed, 89 insertions(+), 9 deletions(-) create mode 100644 libraries/classes/Controllers/Normalization/FirstNormalForm/FourthStepController.php create mode 100644 test/classes/Controllers/Normalization/FirstNormalForm/FourthStepControllerTest.php diff --git a/js/src/normalization.js b/js/src/normalization.js index d704912efc..93a4627324 100644 --- a/js/src/normalization.js +++ b/js/src/normalization.js @@ -133,13 +133,12 @@ function goToFinish1NF () { function goToStep4 () { $.post( - 'index.php?route=/normalization', + 'index.php?route=/normalization/1nf/step4', { 'ajax_request': true, 'db': window.CommonParams.get('db'), 'table': window.CommonParams.get('table'), 'server': window.CommonParams.get('server'), - 'step4': true }, function (data) { $('#mainContent legend').html(data.legendText); $('#mainContent h4').html(data.headText); diff --git a/libraries/classes/Controllers/Normalization/FirstNormalForm/FourthStepController.php b/libraries/classes/Controllers/Normalization/FirstNormalForm/FourthStepController.php new file mode 100644 index 0000000000..b7e18b9eee --- /dev/null +++ b/libraries/classes/Controllers/Normalization/FirstNormalForm/FourthStepController.php @@ -0,0 +1,29 @@ +normalization = $normalization; + } + + public function __invoke(ServerRequest $request): void + { + $res = $this->normalization->getHtmlContentsFor1NFStep4($GLOBALS['db'], $GLOBALS['table']); + $this->response->addJSON($res); + } +} diff --git a/libraries/classes/Controllers/NormalizationController.php b/libraries/classes/Controllers/NormalizationController.php index 13398e77ab..5d48db966d 100644 --- a/libraries/classes/Controllers/NormalizationController.php +++ b/libraries/classes/Controllers/NormalizationController.php @@ -143,13 +143,6 @@ class NormalizationController extends AbstractController return; } - if (isset($_POST['step4'])) { - $res = $this->normalization->getHtmlContentsFor1NFStep4($GLOBALS['db'], $GLOBALS['table']); - $this->response->addJSON($res); - - return; - } - if (isset($_POST['step']) && $_POST['step'] == '2.1') { $res = $this->normalization->getHtmlFor2NFstep1($GLOBALS['db'], $GLOBALS['table']); $this->response->addJSON($res); diff --git a/libraries/routes.php b/libraries/routes.php index b1da0f3dc5..5da6ea4b34 100644 --- a/libraries/routes.php +++ b/libraries/routes.php @@ -135,6 +135,7 @@ return static function (RouteCollector $routes): void { $routes->post('/1nf/step1', Normalization\FirstNormalForm\FirstStepController::class); $routes->post('/1nf/step2', Normalization\FirstNormalForm\SecondStepController::class); $routes->post('/1nf/step3', Normalization\FirstNormalForm\ThirdStepController::class); + $routes->post('/1nf/step4', Normalization\FirstNormalForm\FourthStepController::class); }); $routes->get('/phpinfo', PhpInfoController::class); $routes->addGroup('/preferences', static function (RouteCollector $routes): void { diff --git a/libraries/services_controllers.php b/libraries/services_controllers.php index 9ee26c2692..944fa534f3 100644 --- a/libraries/services_controllers.php +++ b/libraries/services_controllers.php @@ -593,6 +593,14 @@ return [ '$normalization' => '@normalization', ], ], + Normalization\FirstNormalForm\FourthStepController::class => [ + 'class' => Normalization\FirstNormalForm\FourthStepController::class, + 'arguments' => [ + '$response' => '@response', + '$template' => '@template', + '$normalization' => '@normalization', + ], + ], Normalization\FirstNormalForm\SecondStepController::class => [ 'class' => Normalization\FirstNormalForm\SecondStepController::class, 'arguments' => [ diff --git a/test/classes/Controllers/Normalization/FirstNormalForm/FourthStepControllerTest.php b/test/classes/Controllers/Normalization/FirstNormalForm/FourthStepControllerTest.php new file mode 100644 index 0000000000..a77cd1cb60 --- /dev/null +++ b/test/classes/Controllers/Normalization/FirstNormalForm/FourthStepControllerTest.php @@ -0,0 +1,50 @@ +createDbiDummy(); + $dbiDummy->addSelectDb('test_db'); + + $dbi = $this->createDatabaseInterface($dbiDummy); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new FourthStepController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + // phpcs:disable Generic.Files.LineLength.TooLong + $this->assertSame([ + 'legendText' => 'Step 1.4 Remove redundant columns', + 'headText' => 'Do you have a group of columns which on combining gives an existing column? For example, if you have first_name, last_name and full_name then combining first_name and last_name gives full_name which is redundant.', + 'subText' => 'Check the columns which are redundant and click on remove. If no redundant column, click on \'No redundant column\'', + 'extra' => 'id [ int(11) ]
name [ varchar(20) ]
datetimefield [ datetime ]

', + ], $response->getJSONResult()); + // phpcs:enable + } +} From 51db9db3ddc06e0bfc2909abb7585325885d2e7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Meneghini=20Fauth?= Date: Fri, 29 Jul 2022 21:10:52 -0300 Subject: [PATCH 5/7] Extract normalization 2NF step 1 action MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maurício Meneghini Fauth --- js/src/normalization.js | 3 +- .../SecondNormalForm/FirstStepController.php | 29 +++++++++++ .../Controllers/NormalizationController.php | 7 --- libraries/routes.php | 1 + libraries/services_controllers.php | 8 ++++ .../FirstStepControllerTest.php | 48 +++++++++++++++++++ 6 files changed, 87 insertions(+), 9 deletions(-) create mode 100644 libraries/classes/Controllers/Normalization/SecondNormalForm/FirstStepController.php create mode 100644 test/classes/Controllers/Normalization/SecondNormalForm/FirstStepControllerTest.php diff --git a/js/src/normalization.js b/js/src/normalization.js index 93a4627324..005fcd33c5 100644 --- a/js/src/normalization.js +++ b/js/src/normalization.js @@ -80,13 +80,12 @@ function goTo3NFStep1 (newTables) { function goTo2NFStep1 () { $.post( - 'index.php?route=/normalization', + 'index.php?route=/normalization/2nf/step1', { 'ajax_request': true, 'db': window.CommonParams.get('db'), 'table': window.CommonParams.get('table'), 'server': window.CommonParams.get('server'), - 'step': '2.1' }, function (data) { $('#page_content h3').html(window.Messages.str2NFNormalization); $('#mainContent legend').html(data.legendText); diff --git a/libraries/classes/Controllers/Normalization/SecondNormalForm/FirstStepController.php b/libraries/classes/Controllers/Normalization/SecondNormalForm/FirstStepController.php new file mode 100644 index 0000000000..e0f59b6c90 --- /dev/null +++ b/libraries/classes/Controllers/Normalization/SecondNormalForm/FirstStepController.php @@ -0,0 +1,29 @@ +normalization = $normalization; + } + + public function __invoke(ServerRequest $request): void + { + $res = $this->normalization->getHtmlFor2NFstep1($GLOBALS['db'], $GLOBALS['table']); + $this->response->addJSON($res); + } +} diff --git a/libraries/classes/Controllers/NormalizationController.php b/libraries/classes/Controllers/NormalizationController.php index 5d48db966d..7886423ce7 100644 --- a/libraries/classes/Controllers/NormalizationController.php +++ b/libraries/classes/Controllers/NormalizationController.php @@ -143,13 +143,6 @@ class NormalizationController extends AbstractController return; } - if (isset($_POST['step']) && $_POST['step'] == '2.1') { - $res = $this->normalization->getHtmlFor2NFstep1($GLOBALS['db'], $GLOBALS['table']); - $this->response->addJSON($res); - - return; - } - if (isset($_POST['step']) && $_POST['step'] == '3.1') { $tables = $_POST['tables']; $res = $this->normalization->getHtmlFor3NFstep1($GLOBALS['db'], $tables); diff --git a/libraries/routes.php b/libraries/routes.php index 5da6ea4b34..dad41d8b24 100644 --- a/libraries/routes.php +++ b/libraries/routes.php @@ -136,6 +136,7 @@ return static function (RouteCollector $routes): void { $routes->post('/1nf/step2', Normalization\FirstNormalForm\SecondStepController::class); $routes->post('/1nf/step3', Normalization\FirstNormalForm\ThirdStepController::class); $routes->post('/1nf/step4', Normalization\FirstNormalForm\FourthStepController::class); + $routes->post('/2nf/step1', Normalization\SecondNormalForm\FirstStepController::class); }); $routes->get('/phpinfo', PhpInfoController::class); $routes->addGroup('/preferences', static function (RouteCollector $routes): void { diff --git a/libraries/services_controllers.php b/libraries/services_controllers.php index 944fa534f3..9009548946 100644 --- a/libraries/services_controllers.php +++ b/libraries/services_controllers.php @@ -617,6 +617,14 @@ return [ '$normalization' => '@normalization', ], ], + Normalization\SecondNormalForm\FirstStepController::class => [ + 'class' => Normalization\SecondNormalForm\FirstStepController::class, + 'arguments' => [ + '$response' => '@response', + '$template' => '@template', + '$normalization' => '@normalization', + ], + ], NormalizationController::class => [ 'class' => NormalizationController::class, 'arguments' => [ diff --git a/test/classes/Controllers/Normalization/SecondNormalForm/FirstStepControllerTest.php b/test/classes/Controllers/Normalization/SecondNormalForm/FirstStepControllerTest.php new file mode 100644 index 0000000000..52cb33daaa --- /dev/null +++ b/test/classes/Controllers/Normalization/SecondNormalForm/FirstStepControllerTest.php @@ -0,0 +1,48 @@ +createDatabaseInterface(); + $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)); + + // phpcs:disable Generic.Files.LineLength.TooLong + $this->assertSame([ + 'legendText' => 'Step 2.1 Find partial dependencies', + 'headText' => 'No partial dependencies possible as the primary key ( id ) has just one column.
', + 'subText' => '', + 'extra' => '

Table is already in second normal form.

', + 'primary_key' => 'id', + ], $response->getJSONResult()); + // phpcs:enable + } +} From dd25695569bc86f66e6be393bf92394229639549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Meneghini=20Fauth?= Date: Sat, 30 Jul 2022 00:36:58 -0300 Subject: [PATCH 6/7] Extract normalization 2NF new tables action MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maurício Meneghini Fauth --- js/src/normalization.js | 4 +- .../SecondNormalForm/NewTablesController.php | 32 +++++++++++++ .../Controllers/NormalizationController.php | 8 ---- libraries/routes.php | 1 + libraries/services_controllers.php | 8 ++++ phpstan-baseline.neon | 10 ++-- psalm-baseline.xml | 18 ++++--- .../NewTablesControllerTest.php | 48 +++++++++++++++++++ .../NormalizationControllerTest.php | 22 --------- 9 files changed, 108 insertions(+), 43 deletions(-) create mode 100644 libraries/classes/Controllers/Normalization/SecondNormalForm/NewTablesController.php create mode 100644 test/classes/Controllers/Normalization/SecondNormalForm/NewTablesControllerTest.php diff --git a/js/src/normalization.js b/js/src/normalization.js index 005fcd33c5..4e734e240e 100644 --- a/js/src/normalization.js +++ b/js/src/normalization.js @@ -318,10 +318,10 @@ function goTo2NFStep2 (pd, primaryKey) { 'table': window.CommonParams.get('table'), 'server': window.CommonParams.get('server'), 'pd': JSON.stringify(pd), - 'getNewTables2NF':1 }; + }; $.ajax({ type: 'POST', - url: 'index.php?route=/normalization', + url: 'index.php?route=/normalization/2nf/new-tables', data: datastring, async:false, success: function (data) { diff --git a/libraries/classes/Controllers/Normalization/SecondNormalForm/NewTablesController.php b/libraries/classes/Controllers/Normalization/SecondNormalForm/NewTablesController.php new file mode 100644 index 0000000000..07232fa380 --- /dev/null +++ b/libraries/classes/Controllers/Normalization/SecondNormalForm/NewTablesController.php @@ -0,0 +1,32 @@ +normalization = $normalization; + } + + public function __invoke(ServerRequest $request): void + { + $partialDependencies = json_decode($_POST['pd'], true); + $html = $this->normalization->getHtmlForNewTables2NF($partialDependencies, $GLOBALS['table']); + $this->response->addHTML($html); + } +} diff --git a/libraries/classes/Controllers/NormalizationController.php b/libraries/classes/Controllers/NormalizationController.php index 7886423ce7..02451e26fa 100644 --- a/libraries/classes/Controllers/NormalizationController.php +++ b/libraries/classes/Controllers/NormalizationController.php @@ -82,14 +82,6 @@ class NormalizationController extends AbstractController return; } - if (isset($_POST['getNewTables2NF'])) { - $partialDependencies = json_decode($_POST['pd'], true); - $html = $this->normalization->getHtmlForNewTables2NF($partialDependencies, $GLOBALS['table']); - echo $html; - - return; - } - if (isset($_POST['getNewTables3NF'])) { $dependencies = json_decode($_POST['pd']); $tables = json_decode($_POST['tables'], true); diff --git a/libraries/routes.php b/libraries/routes.php index dad41d8b24..d150421a99 100644 --- a/libraries/routes.php +++ b/libraries/routes.php @@ -136,6 +136,7 @@ return static function (RouteCollector $routes): void { $routes->post('/1nf/step2', Normalization\FirstNormalForm\SecondStepController::class); $routes->post('/1nf/step3', Normalization\FirstNormalForm\ThirdStepController::class); $routes->post('/1nf/step4', Normalization\FirstNormalForm\FourthStepController::class); + $routes->post('/2nf/new-tables', Normalization\SecondNormalForm\NewTablesController::class); $routes->post('/2nf/step1', Normalization\SecondNormalForm\FirstStepController::class); }); $routes->get('/phpinfo', PhpInfoController::class); diff --git a/libraries/services_controllers.php b/libraries/services_controllers.php index 9009548946..dc7fa99985 100644 --- a/libraries/services_controllers.php +++ b/libraries/services_controllers.php @@ -625,6 +625,14 @@ return [ '$normalization' => '@normalization', ], ], + Normalization\SecondNormalForm\NewTablesController::class => [ + 'class' => Normalization\SecondNormalForm\NewTablesController::class, + 'arguments' => [ + '$response' => '@response', + '$template' => '@template', + '$normalization' => '@normalization', + ], + ], NormalizationController::class => [ 'class' => NormalizationController::class, 'arguments' => [ diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index aa0ed2f75c..b223fbc395 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1220,6 +1220,11 @@ parameters: count: 1 path: libraries/classes/Controllers/HomeController.php + - + message: "#^Parameter \\#1 \\$partialDependencies of method PhpMyAdmin\\\\Normalization\\:\\:getHtmlForNewTables2NF\\(\\) expects array, mixed given\\.$#" + count: 1 + path: libraries/classes/Controllers/Normalization/SecondNormalForm/NewTablesController.php + - message: "#^Parameter \\#1 \\$dependencies of method PhpMyAdmin\\\\Normalization\\:\\:getHtmlForNewTables3NF\\(\\) expects object, mixed given\\.$#" count: 1 @@ -1235,11 +1240,6 @@ parameters: count: 1 path: libraries/classes/Controllers/NormalizationController.php - - - message: "#^Parameter \\#1 \\$partialDependencies of method PhpMyAdmin\\\\Normalization\\:\\:getHtmlForNewTables2NF\\(\\) expects array, mixed given\\.$#" - count: 1 - path: libraries/classes/Controllers/NormalizationController.php - - message: "#^Parameter \\#2 \\$tables of method PhpMyAdmin\\\\Normalization\\:\\:getHtmlForNewTables3NF\\(\\) expects array, mixed given\\.$#" count: 1 diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 76ea2a44ae..91aa5a2050 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,5 +1,5 @@ - + $matches[1] @@ -2407,33 +2407,39 @@ $normalForm + + + $_POST['pd'] + $partialDependencies + + + $partialDependencies + + - + $_POST['newTables'] $_POST['newTablesName'] $_POST['pd'] $_POST['pd'] - $_POST['pd'] $_POST['tables'] $dependencies $newColumn $newTable $newtables $partialDependencies - $partialDependencies $primary_columns $repeatingColumns $tables $tables $tablesName - + $dependencies $newColumn $newTable $newtables $partialDependencies - $partialDependencies $primary_columns $repeatingColumns $tables diff --git a/test/classes/Controllers/Normalization/SecondNormalForm/NewTablesControllerTest.php b/test/classes/Controllers/Normalization/SecondNormalForm/NewTablesControllerTest.php new file mode 100644 index 0000000000..e019257735 --- /dev/null +++ b/test/classes/Controllers/Normalization/SecondNormalForm/NewTablesControllerTest.php @@ -0,0 +1,48 @@ + [], 'task' => ['timestamp']]); + + $dbi = $this->createDatabaseInterface(); + $GLOBALS['dbi'] = $dbi; + $response = new ResponseRenderer(); + $template = new Template(); + + $controller = new NewTablesController( + $response, + $template, + new Normalization($dbi, new Relation($dbi), new Transformations(), $template) + ); + $controller($this->createStub(ServerRequest::class)); + + // phpcs:disable Generic.Files.LineLength.TooLong + $this->assertSame( + '

In order to put the original table \'test_table\' into Second normal form we need to create the following tables:

( ID, task )

( task, timestamp )', + $response->getHTMLResult() + ); + // phpcs:enable + } +} diff --git a/test/classes/Controllers/NormalizationControllerTest.php b/test/classes/Controllers/NormalizationControllerTest.php index 31a87b0676..6e8ca6e76d 100644 --- a/test/classes/Controllers/NormalizationControllerTest.php +++ b/test/classes/Controllers/NormalizationControllerTest.php @@ -117,28 +117,6 @@ class NormalizationControllerTest extends AbstractTestCase $this->expectOutputString($data); } - public function testGetNewTables2NF(): void - { - $_POST['getNewTables2NF'] = 1; - $_POST['pd'] = json_encode([ - 'ID, task' => [], - 'task' => ['timestamp'], - ]); - - $GLOBALS['goto'] = 'index.php?route=/sql'; - $GLOBALS['containerBuilder']->setParameter('db', $GLOBALS['db']); - $GLOBALS['containerBuilder']->setParameter('table', $GLOBALS['table']); - /** @var NormalizationController $normalizationController */ - $normalizationController = $GLOBALS['containerBuilder']->get(NormalizationController::class); - $normalizationController($this->createStub(ServerRequest::class)); - $this->expectOutputString( - '

In order to put the original table \'test_tbl\' into Second normal' - . ' form we need to create the following tables:

( ID, task )

( task, timestamp )' - ); - } - public function testCreateNewTables2NF(): void { $_POST['createNewTables2NF'] = 1; From efc04db52b7e77b6ec067fad427fa3a3a2c88689 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Meneghini=20Fauth?= Date: Sat, 30 Jul 2022 17:49:12 -0300 Subject: [PATCH 7/7] Extract normalization 3NF step 1 action MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maurício Meneghini Fauth --- js/src/normalization.js | 3 +- .../ThirdNormalForm/FirstStepController.php | 30 +++++++++++ .../Controllers/NormalizationController.php | 8 --- libraries/routes.php | 1 + libraries/services_controllers.php | 8 +++ psalm-baseline.xml | 14 +++-- .../FirstStepControllerTest.php | 2 - .../FirstStepControllerTest.php | 51 +++++++++++++++++++ 8 files changed, 101 insertions(+), 16 deletions(-) create mode 100644 libraries/classes/Controllers/Normalization/ThirdNormalForm/FirstStepController.php create mode 100644 test/classes/Controllers/Normalization/ThirdNormalForm/FirstStepControllerTest.php diff --git a/js/src/normalization.js b/js/src/normalization.js index 4e734e240e..c800ff634d 100644 --- a/js/src/normalization.js +++ b/js/src/normalization.js @@ -40,13 +40,12 @@ function goTo3NFStep1 (newTables) { tables = [window.CommonParams.get('table')]; } $.post( - 'index.php?route=/normalization', + 'index.php?route=/normalization/3nf/step1', { 'ajax_request': true, 'db': window.CommonParams.get('db'), 'server': window.CommonParams.get('server'), 'tables': tables, - 'step': '3.1' }, function (data) { $('#page_content').find('h3').html(window.Messages.str3NFNormalization); $('#mainContent').find('legend').html(data.legendText); diff --git a/libraries/classes/Controllers/Normalization/ThirdNormalForm/FirstStepController.php b/libraries/classes/Controllers/Normalization/ThirdNormalForm/FirstStepController.php new file mode 100644 index 0000000000..5b50da6a87 --- /dev/null +++ b/libraries/classes/Controllers/Normalization/ThirdNormalForm/FirstStepController.php @@ -0,0 +1,30 @@ +normalization = $normalization; + } + + public function __invoke(ServerRequest $request): void + { + $tables = $_POST['tables']; + $res = $this->normalization->getHtmlFor3NFstep1($GLOBALS['db'], $tables); + $this->response->addJSON($res); + } +} diff --git a/libraries/classes/Controllers/NormalizationController.php b/libraries/classes/Controllers/NormalizationController.php index 02451e26fa..1dbf6586bd 100644 --- a/libraries/classes/Controllers/NormalizationController.php +++ b/libraries/classes/Controllers/NormalizationController.php @@ -135,14 +135,6 @@ class NormalizationController extends AbstractController return; } - if (isset($_POST['step']) && $_POST['step'] == '3.1') { - $tables = $_POST['tables']; - $res = $this->normalization->getHtmlFor3NFstep1($GLOBALS['db'], $tables); - $this->response->addJSON($res); - - return; - } - $this->render('table/normalization/normalization', [ 'db' => $GLOBALS['db'], 'table' => $GLOBALS['table'], diff --git a/libraries/routes.php b/libraries/routes.php index d150421a99..7f17bbf603 100644 --- a/libraries/routes.php +++ b/libraries/routes.php @@ -138,6 +138,7 @@ return static function (RouteCollector $routes): void { $routes->post('/1nf/step4', Normalization\FirstNormalForm\FourthStepController::class); $routes->post('/2nf/new-tables', Normalization\SecondNormalForm\NewTablesController::class); $routes->post('/2nf/step1', Normalization\SecondNormalForm\FirstStepController::class); + $routes->post('/3nf/step1', Normalization\ThirdNormalForm\FirstStepController::class); }); $routes->get('/phpinfo', PhpInfoController::class); $routes->addGroup('/preferences', static function (RouteCollector $routes): void { diff --git a/libraries/services_controllers.php b/libraries/services_controllers.php index dc7fa99985..3d9eb312ea 100644 --- a/libraries/services_controllers.php +++ b/libraries/services_controllers.php @@ -633,6 +633,14 @@ return [ '$normalization' => '@normalization', ], ], + Normalization\ThirdNormalForm\FirstStepController::class => [ + 'class' => Normalization\ThirdNormalForm\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 91aa5a2050..98672f2a3c 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -2416,8 +2416,16 @@ $partialDependencies + + + $tables + + + $tables + + - + $_POST['newTables'] $_POST['newTablesName'] $_POST['pd'] @@ -2431,10 +2439,9 @@ $primary_columns $repeatingColumns $tables - $tables $tablesName - + $dependencies $newColumn $newTable @@ -2443,7 +2450,6 @@ $primary_columns $repeatingColumns $tables - $tables $tablesName diff --git a/test/classes/Controllers/Normalization/SecondNormalForm/FirstStepControllerTest.php b/test/classes/Controllers/Normalization/SecondNormalForm/FirstStepControllerTest.php index 52cb33daaa..c5ec7dda6f 100644 --- a/test/classes/Controllers/Normalization/SecondNormalForm/FirstStepControllerTest.php +++ b/test/classes/Controllers/Normalization/SecondNormalForm/FirstStepControllerTest.php @@ -35,7 +35,6 @@ class FirstStepControllerTest extends AbstractTestCase ); $controller($this->createStub(ServerRequest::class)); - // phpcs:disable Generic.Files.LineLength.TooLong $this->assertSame([ 'legendText' => 'Step 2.1 Find partial dependencies', 'headText' => 'No partial dependencies possible as the primary key ( id ) has just one column.
', @@ -43,6 +42,5 @@ class FirstStepControllerTest extends AbstractTestCase 'extra' => '

Table is already in second normal form.

', 'primary_key' => 'id', ], $response->getJSONResult()); - // phpcs:enable } } diff --git a/test/classes/Controllers/Normalization/ThirdNormalForm/FirstStepControllerTest.php b/test/classes/Controllers/Normalization/ThirdNormalForm/FirstStepControllerTest.php new file mode 100644 index 0000000000..dd55cef91e --- /dev/null +++ b/test/classes/Controllers/Normalization/ThirdNormalForm/FirstStepControllerTest.php @@ -0,0 +1,51 @@ +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)); + + // phpcs:disable Generic.Files.LineLength.TooLong + $this->assertSame([ + 'legendText' => 'Step 3.1 Find transitive dependencies', + 'headText' => 'Please answer the following question(s) carefully to obtain a correct normalization.', + 'subText' => 'For each column below, please select the minimal set of columns among given set whose values combined together are sufficient to determine the value of the column.
Note: A column may have no transitive dependency, in that case you don\'t have to select any.', + 'extra' => '\'name\' depends on:
namedatetimefield

\'datetimefield\' depends on:
namedatetimefield


', + ], $response->getJSONResult()); + // phpcs:enable + } +}