Merge pull request #17666 from MauricioFauth/normalization
Extract some actions from NormalizationController class
This commit is contained in:
commit
160d6efbe8
@ -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);
|
||||
@ -80,13 +79,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);
|
||||
@ -133,13 +131,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);
|
||||
@ -157,13 +154,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);
|
||||
@ -181,13 +177,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);
|
||||
@ -322,10 +317,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) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
<?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;
|
||||
|
||||
final class FourthStepController 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
|
||||
{
|
||||
$res = $this->normalization->getHtmlContentsFor1NFStep4($GLOBALS['db'], $GLOBALS['table']);
|
||||
$this->response->addJSON($res);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
<?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;
|
||||
|
||||
final class SecondStepController 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
|
||||
{
|
||||
$res = $this->normalization->getHtmlContentsFor1NFStep2($GLOBALS['db'], $GLOBALS['table']);
|
||||
$this->response->addJSON($res);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
<?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;
|
||||
|
||||
final class ThirdStepController 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
|
||||
{
|
||||
$res = $this->normalization->getHtmlContentsFor1NFStep3($GLOBALS['db'], $GLOBALS['table']);
|
||||
$this->response->addJSON($res);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Controllers\Normalization\SecondNormalForm;
|
||||
|
||||
use PhpMyAdmin\Controllers\AbstractController;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\Normalization;
|
||||
use PhpMyAdmin\ResponseRenderer;
|
||||
use PhpMyAdmin\Template;
|
||||
|
||||
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
|
||||
{
|
||||
$res = $this->normalization->getHtmlFor2NFstep1($GLOBALS['db'], $GLOBALS['table']);
|
||||
$this->response->addJSON($res);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Controllers\Normalization\SecondNormalForm;
|
||||
|
||||
use PhpMyAdmin\Controllers\AbstractController;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\Normalization;
|
||||
use PhpMyAdmin\ResponseRenderer;
|
||||
use PhpMyAdmin\Template;
|
||||
|
||||
use function json_decode;
|
||||
|
||||
final class NewTablesController 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
|
||||
{
|
||||
$partialDependencies = json_decode($_POST['pd'], true);
|
||||
$html = $this->normalization->getHtmlForNewTables2NF($partialDependencies, $GLOBALS['table']);
|
||||
$this->response->addHTML($html);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Controllers\Normalization\ThirdNormalForm;
|
||||
|
||||
use PhpMyAdmin\Controllers\AbstractController;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\Normalization;
|
||||
use PhpMyAdmin\ResponseRenderer;
|
||||
use PhpMyAdmin\Template;
|
||||
|
||||
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
|
||||
{
|
||||
$tables = $_POST['tables'];
|
||||
$res = $this->normalization->getHtmlFor3NFstep1($GLOBALS['db'], $tables);
|
||||
$this->response->addJSON($res);
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
@ -83,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);
|
||||
@ -104,11 +95,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,49 +135,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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
$this->response->addJSON($res);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->render('table/normalization/normalization', [
|
||||
'db' => $GLOBALS['db'],
|
||||
'table' => $GLOBALS['table'],
|
||||
|
||||
@ -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,16 @@ 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->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->post('/3nf/step1', Normalization\ThirdNormalForm\FirstStepController::class);
|
||||
});
|
||||
$routes->get('/phpinfo', PhpInfoController::class);
|
||||
$routes->addGroup('/preferences', static function (RouteCollector $routes): void {
|
||||
$routes->addRoute(['GET', 'POST'], '/export', Preferences\ExportController::class);
|
||||
|
||||
@ -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,62 @@ return [
|
||||
'$relation' => '@relation',
|
||||
],
|
||||
],
|
||||
Normalization\FirstNormalForm\FirstStepController::class => [
|
||||
'class' => Normalization\FirstNormalForm\FirstStepController::class,
|
||||
'arguments' => [
|
||||
'$response' => '@response',
|
||||
'$template' => '@template',
|
||||
'$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' => [
|
||||
'$response' => '@response',
|
||||
'$template' => '@template',
|
||||
'$normalization' => '@normalization',
|
||||
],
|
||||
],
|
||||
Normalization\FirstNormalForm\ThirdStepController::class => [
|
||||
'class' => Normalization\FirstNormalForm\ThirdStepController::class,
|
||||
'arguments' => [
|
||||
'$response' => '@response',
|
||||
'$template' => '@template',
|
||||
'$normalization' => '@normalization',
|
||||
],
|
||||
],
|
||||
Normalization\SecondNormalForm\FirstStepController::class => [
|
||||
'class' => Normalization\SecondNormalForm\FirstStepController::class,
|
||||
'arguments' => [
|
||||
'$response' => '@response',
|
||||
'$template' => '@template',
|
||||
'$normalization' => '@normalization',
|
||||
],
|
||||
],
|
||||
Normalization\SecondNormalForm\NewTablesController::class => [
|
||||
'class' => Normalization\SecondNormalForm\NewTablesController::class,
|
||||
'arguments' => [
|
||||
'$response' => '@response',
|
||||
'$template' => '@template',
|
||||
'$normalization' => '@normalization',
|
||||
],
|
||||
],
|
||||
Normalization\ThirdNormalForm\FirstStepController::class => [
|
||||
'class' => Normalization\ThirdNormalForm\FirstStepController::class,
|
||||
'arguments' => [
|
||||
'$response' => '@response',
|
||||
'$template' => '@template',
|
||||
'$normalization' => '@normalization',
|
||||
],
|
||||
],
|
||||
NormalizationController::class => [
|
||||
'class' => NormalizationController::class,
|
||||
'arguments' => [
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<files psalm-version="4.24.0@06dd975cb55d36af80f242561738f16c5f58264f">
|
||||
<files psalm-version="v4.25.0@d7cd84c4ebca74ba3419b9601f81d177bcbe2aac">
|
||||
<file src="libraries/classes/Advisory/Advisor.php">
|
||||
<MixedArgument occurrences="8">
|
||||
<code>$matches[1]</code>
|
||||
@ -2399,39 +2399,57 @@
|
||||
<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/Normalization/SecondNormalForm/NewTablesController.php">
|
||||
<MixedArgument occurrences="2">
|
||||
<code>$_POST['pd']</code>
|
||||
<code>$partialDependencies</code>
|
||||
</MixedArgument>
|
||||
<MixedAssignment occurrences="1">
|
||||
<code>$partialDependencies</code>
|
||||
</MixedAssignment>
|
||||
</file>
|
||||
<file src="libraries/classes/Controllers/Normalization/ThirdNormalForm/FirstStepController.php">
|
||||
<MixedArgument occurrences="1">
|
||||
<code>$tables</code>
|
||||
</MixedArgument>
|
||||
<MixedAssignment occurrences="1">
|
||||
<code>$tables</code>
|
||||
</MixedAssignment>
|
||||
</file>
|
||||
<file src="libraries/classes/Controllers/NormalizationController.php">
|
||||
<MixedArgument occurrences="18">
|
||||
<MixedArgument occurrences="14">
|
||||
<code>$_POST['newTables']</code>
|
||||
<code>$_POST['newTablesName']</code>
|
||||
<code>$_POST['pd']</code>
|
||||
<code>$_POST['pd']</code>
|
||||
<code>$_POST['pd']</code>
|
||||
<code>$_POST['tables']</code>
|
||||
<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>
|
||||
<code>$repeatingColumns</code>
|
||||
<code>$tables</code>
|
||||
<code>$tables</code>
|
||||
<code>$tablesName</code>
|
||||
</MixedArgument>
|
||||
<MixedAssignment occurrences="12">
|
||||
<MixedAssignment occurrences="9">
|
||||
<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>
|
||||
<code>$repeatingColumns</code>
|
||||
<code>$tables</code>
|
||||
<code>$tables</code>
|
||||
<code>$tablesName</code>
|
||||
</MixedAssignment>
|
||||
</file>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Tests\Controllers\Normalization\FirstNormalForm;
|
||||
|
||||
use PhpMyAdmin\ConfigStorage\Relation;
|
||||
use PhpMyAdmin\Controllers\Normalization\FirstNormalForm\FourthStepController;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\Normalization;
|
||||
use PhpMyAdmin\Template;
|
||||
use PhpMyAdmin\Tests\AbstractTestCase;
|
||||
use PhpMyAdmin\Tests\Stubs\ResponseRenderer;
|
||||
use PhpMyAdmin\Transformations;
|
||||
|
||||
/**
|
||||
* @covers \PhpMyAdmin\Controllers\Normalization\FirstNormalForm\FourthStepController
|
||||
*/
|
||||
class FourthStepControllerTest extends AbstractTestCase
|
||||
{
|
||||
public function testDefault(): void
|
||||
{
|
||||
$GLOBALS['db'] = 'test_db';
|
||||
$GLOBALS['table'] = 'test_table';
|
||||
|
||||
$dbiDummy = $this->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' => '<input type="checkbox" value="id">id [ int(11) ]<br><input type="checkbox" value="name">name [ varchar(20) ]<br><input type="checkbox" value="datetimefield">datetimefield [ datetime ]<br><br><input class="btn btn-secondary" type="submit" id="removeRedundant" value="Remove selected"><input class="btn btn-secondary" type="submit" value="No redundant column" onclick="goToFinish1NF();">',
|
||||
], $response->getJSONResult());
|
||||
// phpcs:enable
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Tests\Controllers\Normalization\FirstNormalForm;
|
||||
|
||||
use PhpMyAdmin\ConfigStorage\Relation;
|
||||
use PhpMyAdmin\Controllers\Normalization\FirstNormalForm\SecondStepController;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\Normalization;
|
||||
use PhpMyAdmin\Template;
|
||||
use PhpMyAdmin\Tests\AbstractTestCase;
|
||||
use PhpMyAdmin\Tests\Stubs\ResponseRenderer;
|
||||
use PhpMyAdmin\Transformations;
|
||||
|
||||
/**
|
||||
* @covers \PhpMyAdmin\Controllers\Normalization\FirstNormalForm\SecondStepController
|
||||
*/
|
||||
class SecondStepControllerTest extends AbstractTestCase
|
||||
{
|
||||
public function testDefault(): void
|
||||
{
|
||||
$GLOBALS['db'] = 'test_db';
|
||||
$GLOBALS['table'] = 'test_table';
|
||||
|
||||
$dbi = $this->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());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Tests\Controllers\Normalization\FirstNormalForm;
|
||||
|
||||
use PhpMyAdmin\ConfigStorage\Relation;
|
||||
use PhpMyAdmin\Controllers\Normalization\FirstNormalForm\ThirdStepController;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\Normalization;
|
||||
use PhpMyAdmin\Template;
|
||||
use PhpMyAdmin\Tests\AbstractTestCase;
|
||||
use PhpMyAdmin\Tests\Stubs\ResponseRenderer;
|
||||
use PhpMyAdmin\Transformations;
|
||||
|
||||
/**
|
||||
* @covers \PhpMyAdmin\Controllers\Normalization\FirstNormalForm\ThirdStepController
|
||||
*/
|
||||
class ThirdStepControllerTest extends AbstractTestCase
|
||||
{
|
||||
public function testDefault(): void
|
||||
{
|
||||
$GLOBALS['db'] = 'test_db';
|
||||
$GLOBALS['table'] = 'test_table';
|
||||
|
||||
$dbiDummy = $this->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' => '<input type="checkbox" value="id">id [ int(11) ]<br><input type="checkbox" value="name">name [ varchar(20) ]<br><input type="checkbox" value="datetimefield">datetimefield [ datetime ]<br><br><input class="btn btn-secondary" type="submit" id="moveRepeatingGroup" value="Done"><input class="btn btn-secondary" type="submit" value="No repeating group" onclick="goToStep4();">',
|
||||
'primary_key' => '["id"]',
|
||||
], $response->getJSONResult());
|
||||
// phpcs:enable
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Tests\Controllers\Normalization\SecondNormalForm;
|
||||
|
||||
use PhpMyAdmin\ConfigStorage\Relation;
|
||||
use PhpMyAdmin\Controllers\Normalization\SecondNormalForm\FirstStepController;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\Normalization;
|
||||
use PhpMyAdmin\Template;
|
||||
use PhpMyAdmin\Tests\AbstractTestCase;
|
||||
use PhpMyAdmin\Tests\Stubs\ResponseRenderer;
|
||||
use PhpMyAdmin\Transformations;
|
||||
|
||||
/**
|
||||
* @covers \PhpMyAdmin\Controllers\Normalization\SecondNormalForm\FirstStepController
|
||||
*/
|
||||
class FirstStepControllerTest extends AbstractTestCase
|
||||
{
|
||||
public function testDefault(): void
|
||||
{
|
||||
$GLOBALS['db'] = 'test_db';
|
||||
$GLOBALS['table'] = 'test_table';
|
||||
|
||||
$dbi = $this->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));
|
||||
|
||||
$this->assertSame([
|
||||
'legendText' => 'Step 2.1 Find partial dependencies',
|
||||
'headText' => 'No partial dependencies possible as the primary key ( id ) has just one column.<br>',
|
||||
'subText' => '',
|
||||
'extra' => '<h3>Table is already in second normal form.</h3>',
|
||||
'primary_key' => 'id',
|
||||
], $response->getJSONResult());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Tests\Controllers\Normalization\SecondNormalForm;
|
||||
|
||||
use PhpMyAdmin\ConfigStorage\Relation;
|
||||
use PhpMyAdmin\Controllers\Normalization\SecondNormalForm\NewTablesController;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\Normalization;
|
||||
use PhpMyAdmin\Template;
|
||||
use PhpMyAdmin\Tests\AbstractTestCase;
|
||||
use PhpMyAdmin\Tests\Stubs\ResponseRenderer;
|
||||
use PhpMyAdmin\Transformations;
|
||||
|
||||
use function json_encode;
|
||||
|
||||
/**
|
||||
* @covers \PhpMyAdmin\Controllers\Normalization\SecondNormalForm\NewTablesController
|
||||
*/
|
||||
class NewTablesControllerTest extends AbstractTestCase
|
||||
{
|
||||
public function testDefault(): void
|
||||
{
|
||||
$GLOBALS['db'] = 'test_db';
|
||||
$GLOBALS['table'] = 'test_table';
|
||||
$_POST['pd'] = json_encode(['ID, task' => [], '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(
|
||||
'<p><b>In order to put the original table \'test_table\' into Second normal form we need to create the following tables:</b></p><p><input type="text" name="ID, task" value="test_table">( <u>ID, task</u> )<p><input type="text" name="task" value="table2">( <u>task</u>, timestamp )',
|
||||
$response->getHTMLResult()
|
||||
);
|
||||
// phpcs:enable
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Tests\Controllers\Normalization\ThirdNormalForm;
|
||||
|
||||
use PhpMyAdmin\ConfigStorage\Relation;
|
||||
use PhpMyAdmin\Controllers\Normalization\ThirdNormalForm\FirstStepController;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\Normalization;
|
||||
use PhpMyAdmin\Template;
|
||||
use PhpMyAdmin\Tests\AbstractTestCase;
|
||||
use PhpMyAdmin\Tests\Stubs\ResponseRenderer;
|
||||
use PhpMyAdmin\Transformations;
|
||||
|
||||
/**
|
||||
* @covers \PhpMyAdmin\Controllers\Normalization\ThirdNormalForm\FirstStepController
|
||||
*/
|
||||
class FirstStepControllerTest extends AbstractTestCase
|
||||
{
|
||||
public function testDefault(): void
|
||||
{
|
||||
$GLOBALS['db'] = 'test_db';
|
||||
$GLOBALS['table'] = 'test_table';
|
||||
$_POST['tables'] = ['test_table'];
|
||||
|
||||
$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));
|
||||
|
||||
// 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 <b>minimal set</b> of columns among given set whose values combined together are sufficient to determine the value of the column.<br>Note: A column may have no transitive dependency, in that case you don\'t have to select any.',
|
||||
'extra' => '<b>\'name\' depends on:</b><br><form id="td_1" data-colname="name" data-tablename="test_table" class="smallIndent"><input type="checkbox" name="pd" value="name"><span>name</span><input type="checkbox" name="pd" value="datetimefield"><span>datetimefield</span></form><br><br><b>\'datetimefield\' depends on:</b><br><form id="td_2" data-colname="datetimefield" data-tablename="test_table" class="smallIndent"><input type="checkbox" name="pd" value="name"><span>name</span><input type="checkbox" name="pd" value="datetimefield"><span>datetimefield</span></form><br><br>',
|
||||
], $response->getJSONResult());
|
||||
// phpcs:enable
|
||||
}
|
||||
}
|
||||
@ -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(
|
||||
'<p><b>In order to put the original table \'test_tbl\' into Second normal'
|
||||
. ' form we need to create the following tables:</b></p><p><input type="text" '
|
||||
. 'name="ID, task" value="test_tbl">( <u>ID, task</u> )<p><input type="text" name="task"'
|
||||
. ' value="table2">( <u>task</u>, timestamp )'
|
||||
);
|
||||
}
|
||||
|
||||
public function testCreateNewTables2NF(): void
|
||||
{
|
||||
$_POST['createNewTables2NF'] = 1;
|
||||
@ -238,12 +216,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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user