From ea4d8e403451422741c267bca4ea0b9f2c98ee45 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Mon, 16 Dec 2024 00:14:47 +0000 Subject: [PATCH] Implement getErrorCount() in Triggers Signed-off-by: Kamil Tekiela --- phpstan-baseline.neon | 30 --------------- psalm-baseline.xml | 39 -------------------- src/Controllers/Triggers/IndexController.php | 10 +---- src/Triggers/Triggers.php | 37 +++++++++++-------- tests/unit/Triggers/TriggersTest.php | 4 +- 5 files changed, 24 insertions(+), 96 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index a61167488b..f9ab60d660 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -5769,12 +5769,6 @@ parameters: count: 11 path: src/Controllers/Triggers/IndexController.php - - - message: '#^Only booleans are allowed in \|\|, int\<0, max\> given on the left side\.$#' - identifier: booleanOr.leftNotBoolean - count: 1 - path: src/Controllers/Triggers/IndexController.php - - message: '#^Parameter \#1 \$identifier of static method PhpMyAdmin\\Util\:\:backquote\(\) expects string\|Stringable\|null, mixed given\.$#' identifier: argument.type @@ -5793,12 +5787,6 @@ parameters: count: 1 path: src/Controllers/Triggers/IndexController.php - - - message: '#^Parameter \#1 \$value of function count expects array\|Countable, mixed given\.$#' - identifier: argument.type - count: 1 - path: src/Controllers/Triggers/IndexController.php - - message: '#^Parameter \#3 \$name of method PhpMyAdmin\\Triggers\\Triggers\:\:getTriggerByName\(\) expects string, mixed given\.$#' identifier: argument.type @@ -18099,18 +18087,6 @@ parameters: count: 1 path: src/Transformations.php - - - message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' - identifier: foreach.nonIterable - count: 1 - path: src/Triggers/Triggers.php - - - - message: '#^Binary operation "\." between ''\'' and mixed results in an error\.$#' - identifier: binaryOp.invalid - count: 1 - path: src/Triggers/Triggers.php - - message: '#^Binary operation "\.\=" between non\-falsy\-string and mixed results in an error\.$#' identifier: assignOp.invalid @@ -18126,12 +18102,6 @@ parameters: count: 1 path: src/Triggers/Triggers.php - - - message: '#^Cannot access an offset on mixed\.$#' - identifier: offsetAccess.nonOffsetAccessible - count: 7 - path: src/Triggers/Triggers.php - - message: '#^Cannot call method getCreateSql\(\) on PhpMyAdmin\\Triggers\\Trigger\|null\.$#' identifier: method.nonObject diff --git a/psalm-baseline.xml b/psalm-baseline.xml index b7ba8af142..1739190e1e 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -3647,9 +3647,6 @@ - - - @@ -3659,9 +3656,6 @@ - - - @@ -3698,10 +3692,6 @@ - - - - @@ -10565,29 +10555,6 @@ - - - - - - - - - - - - - - - - - - - - - - - @@ -10601,15 +10568,9 @@ - - - - - - diff --git a/src/Controllers/Triggers/IndexController.php b/src/Controllers/Triggers/IndexController.php index bb84196bb8..3ef30a18ba 100644 --- a/src/Controllers/Triggers/IndexController.php +++ b/src/Controllers/Triggers/IndexController.php @@ -22,7 +22,6 @@ use PhpMyAdmin\UrlParams; use PhpMyAdmin\Util; use function __; -use function count; use function htmlspecialchars; use function in_array; use function mb_strtoupper; @@ -45,8 +44,6 @@ final class IndexController implements InvocableController public function __invoke(ServerRequest $request): Response { - $GLOBALS['errors'] ??= null; - $this->response->addScriptFiles(['triggers.js', 'sql.js']); if (! $request->isAjax()) { @@ -93,11 +90,6 @@ final class IndexController implements InvocableController $this->dbi->selectDb(Current::$database); } - /** - * Keep a list of errors that occurred while - * processing an 'Add' or 'Edit' operation. - */ - $GLOBALS['errors'] = []; $GLOBALS['message'] ??= null; if (! empty($_POST['editor_process_add']) || ! empty($_POST['editor_process_edit'])) { @@ -160,7 +152,7 @@ final class IndexController implements InvocableController * Display a form used to add/edit a trigger, if necessary */ if ( - count($GLOBALS['errors']) + $this->triggers->getErrorCount() > 0 || empty($_POST['editor_process_add']) && empty($_POST['editor_process_edit']) && (! empty($_REQUEST['add_item']) || ! empty($_REQUEST['edit_item'])) // FIXME: must be simpler than that diff --git a/src/Triggers/Triggers.php b/src/Triggers/Triggers.php index f98a721293..1756d8868d 100644 --- a/src/Triggers/Triggers.php +++ b/src/Triggers/Triggers.php @@ -16,6 +16,7 @@ use Webmozart\Assert\Assert; use function __; use function array_column; use function array_multisort; +use function count; use function explode; use function htmlspecialchars; use function in_array; @@ -34,6 +35,9 @@ class Triggers private const EVENTS = ['INSERT', 'UPDATE', 'DELETE']; + /** @var list */ + private array $errors = []; + public function __construct(private DatabaseInterface $dbi) { } @@ -69,7 +73,7 @@ class Triggers $itemQuery = $this->getQueryFromRequest(); // set by getQueryFromRequest() - if ($GLOBALS['errors'] === []) { + if ($this->errors === []) { // Execute the created query if (! empty($_POST['editor_process_edit'])) { // Backup the old trigger, in case something goes wrong @@ -78,7 +82,7 @@ class Triggers $dropItem = $trigger->getDropSql(); $result = $this->dbi->tryQuery($dropItem); if (! $result) { - $GLOBALS['errors'][] = sprintf( + $this->errors[] = sprintf( __('The following query has failed: "%s"'), htmlspecialchars($dropItem), ) @@ -87,7 +91,7 @@ class Triggers } else { $result = $this->dbi->tryQuery($itemQuery); if (! $result) { - $GLOBALS['errors'][] = sprintf( + $this->errors[] = sprintf( __('The following query has failed: "%s"'), htmlspecialchars($itemQuery), ) @@ -103,7 +107,7 @@ class Triggers // and now even the backup query does not execute! // This should not happen, but we better handle // this just in case. - $GLOBALS['errors'][] = __('Sorry, we failed to restore the dropped trigger.') . '
' + $this->errors[] = __('Sorry, we failed to restore the dropped trigger.') . '
' . __('The backed up query was:') . '"' . htmlspecialchars($createItem) . '"
' . __('MySQL said: ') . $this->dbi->getError(); @@ -122,7 +126,7 @@ class Triggers // 'Add a new item' mode $result = $this->dbi->tryQuery($itemQuery); if (! $result) { - $GLOBALS['errors'][] = sprintf( + $this->errors[] = sprintf( __('The following query has failed: "%s"'), htmlspecialchars($itemQuery), ) @@ -140,7 +144,7 @@ class Triggers } } - if ($GLOBALS['errors'] !== []) { + if ($this->errors !== []) { $GLOBALS['message'] = Message::error( '' . __( @@ -149,7 +153,7 @@ class Triggers . '', ); $GLOBALS['message']->addHtml('
    '); - foreach ($GLOBALS['errors'] as $string) { + foreach ($this->errors as $string) { $GLOBALS['message']->addHtml('
  • ' . $string . '
  • '); } @@ -179,8 +183,6 @@ class Triggers */ public function getQueryFromRequest(): string { - $GLOBALS['errors'] ??= null; - $query = 'CREATE '; if (! empty($_POST['item_definer'])) { if (str_contains($_POST['item_definer'], '@')) { @@ -188,7 +190,7 @@ class Triggers $query .= 'DEFINER=' . Util::backquote($arr[0]); $query .= '@' . Util::backquote($arr[1]) . ' '; } else { - $GLOBALS['errors'][] = __('The definer must be in the "username@hostname" format!'); + $this->errors[] = __('The definer must be in the "username@hostname" format!'); } } @@ -196,19 +198,19 @@ class Triggers if (! empty($_POST['item_name'])) { $query .= Util::backquote($_POST['item_name']) . ' '; } else { - $GLOBALS['errors'][] = __('You must provide a trigger name!'); + $this->errors[] = __('You must provide a trigger name!'); } if (! empty($_POST['item_timing']) && in_array($_POST['item_timing'], $this->time, true)) { $query .= $_POST['item_timing'] . ' '; } else { - $GLOBALS['errors'][] = __('You must provide a valid timing for the trigger!'); + $this->errors[] = __('You must provide a valid timing for the trigger!'); } if (! empty($_POST['item_event']) && in_array($_POST['item_event'], self::EVENTS, true)) { $query .= $_POST['item_event'] . ' '; } else { - $GLOBALS['errors'][] = __('You must provide a valid event for the trigger!'); + $this->errors[] = __('You must provide a valid event for the trigger!'); } $query .= 'ON '; @@ -218,14 +220,14 @@ class Triggers ) { $query .= Util::backquote($_POST['item_table']); } else { - $GLOBALS['errors'][] = __('You must provide a valid table name!'); + $this->errors[] = __('You must provide a valid table name!'); } $query .= ' FOR EACH ROW '; if (! empty($_POST['item_definition'])) { $query .= $_POST['item_definition']; } else { - $GLOBALS['errors'][] = __('You must provide a trigger definition.'); + $this->errors[] = __('You must provide a trigger definition.'); } return $query; @@ -274,4 +276,9 @@ class Triggers return $tables; } + + public function getErrorCount(): int + { + return count($this->errors); + } } diff --git a/tests/unit/Triggers/TriggersTest.php b/tests/unit/Triggers/TriggersTest.php index 01ab240a3c..2c3ac4bd75 100644 --- a/tests/unit/Triggers/TriggersTest.php +++ b/tests/unit/Triggers/TriggersTest.php @@ -61,8 +61,6 @@ class TriggersTest extends AbstractTestCase string $query, int $numErr, ): void { - $GLOBALS['errors'] = []; - $_POST['item_definer'] = $definer; $_POST['item_name'] = $name; $_POST['item_timing'] = $timing; @@ -71,7 +69,7 @@ class TriggersTest extends AbstractTestCase $_POST['item_definition'] = $definition; self::assertSame($query, $this->triggers->getQueryFromRequest()); - self::assertCount($numErr, $GLOBALS['errors']); + self::assertSame($numErr, $this->triggers->getErrorCount()); } /**