From 29416f7d32610242900ef44d1e4b84b9c9255255 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Fri, 2 Oct 2026 21:43:15 -0500 Subject: [PATCH 1/4] fix: treat a false row from PDO as no record Signed-off-by: Joey Smith --- src/AbstractDbValidator.php | 6 ++++-- test/unit/NoRecordExistsTest.php | 20 ++++++++++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/AbstractDbValidator.php b/src/AbstractDbValidator.php index b77f8d2..f83a106 100644 --- a/src/AbstractDbValidator.php +++ b/src/AbstractDbValidator.php @@ -165,7 +165,7 @@ public function getTable(): string /** * Run query and returns matches, or null if no matches are found. * - * @return mixed when matches are found. + * @return mixed when matches are found; null when there are none (PDO reports no rows as false). */ protected function query(mixed $value): mixed { @@ -180,6 +180,8 @@ protected function query(mixed $value): mixed $parameters['where1'] = $value; } - return $statement->execute()?->current(); + $row = $statement->execute()?->current(); + + return false === $row ? null : $row; } } diff --git a/test/unit/NoRecordExistsTest.php b/test/unit/NoRecordExistsTest.php index 7656a03..db50b7e 100644 --- a/test/unit/NoRecordExistsTest.php +++ b/test/unit/NoRecordExistsTest.php @@ -39,6 +39,22 @@ public function basicFindsNoRecord() static::assertTrue($validator->isValid('nosuchvalue')); } + /** + * PDO reports "no rows" as false rather than null; that must still count as no record. + * + * @throws Exception + */ + #[Test] + public function noRowsReportedAsFalseFindsNoRecord(): void + { + $validator = new NoRecordExists([ + 'table' => 'users', + 'field' => 'field1', + 'adapter' => $this->getMockNoResult(false), + ]); + static::assertTrue($validator->isValid('nosuchvalue')); + } + /** * Test basic function of RecordExists (no exclusion) * @@ -241,13 +257,13 @@ protected function getMockHasResult(): Adapter * * @throws Exception */ - protected function getMockNoResult(): Adapter + protected function getMockNoResult(mixed $current = null): Adapter { // mock the adapter, driver, and parts $mockConnection = $this->createMock(ConnectionInterface::class); $mockNoResult = $this->createMock(ResultInterface::class); - $mockNoResult->method('current')->willReturn(null); + $mockNoResult->method('current')->willReturn($current); $mockNoResultStatement = $this->createMock(StatementInterface::class); $mockNoResultStatement->method('execute')->willReturn($mockNoResult); From 4b2d5fe7a56fc4d44fcd6174de8c59906532a55a Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Fri, 2 Oct 2026 21:52:55 -0500 Subject: [PATCH 2/4] style: apply mago format to the new test Signed-off-by: Joey Smith --- test/unit/NoRecordExistsTest.php | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/test/unit/NoRecordExistsTest.php b/test/unit/NoRecordExistsTest.php index db50b7e..770106a 100644 --- a/test/unit/NoRecordExistsTest.php +++ b/test/unit/NoRecordExistsTest.php @@ -39,22 +39,6 @@ public function basicFindsNoRecord() static::assertTrue($validator->isValid('nosuchvalue')); } - /** - * PDO reports "no rows" as false rather than null; that must still count as no record. - * - * @throws Exception - */ - #[Test] - public function noRowsReportedAsFalseFindsNoRecord(): void - { - $validator = new NoRecordExists([ - 'table' => 'users', - 'field' => 'field1', - 'adapter' => $this->getMockNoResult(false), - ]); - static::assertTrue($validator->isValid('nosuchvalue')); - } - /** * Test basic function of RecordExists (no exclusion) * @@ -153,6 +137,22 @@ public function excludeWithStringNoRecord() static::assertTrue($validator->isValid('nosuchvalue')); } + /** + * PDO reports "no rows" as false rather than null; that must still count as no record. + * + * @throws Exception + */ + #[Test] + public function noRowsReportedAsFalseFindsNoRecord(): void + { + $validator = new NoRecordExists([ + 'table' => 'users', + 'field' => 'field1', + 'adapter' => $this->getMockNoResult(false), + ]); + static::assertTrue($validator->isValid('nosuchvalue')); + } + /** * @throws Exception */ From 9a268b9662044be387e82d2a50cd7dada41c488c Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Fri, 2 Oct 2026 21:56:20 -0500 Subject: [PATCH 3/4] chore: type the validator error constants Signed-off-by: Joey Smith --- src/AbstractDbValidator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AbstractDbValidator.php b/src/AbstractDbValidator.php index f83a106..2ca99c3 100644 --- a/src/AbstractDbValidator.php +++ b/src/AbstractDbValidator.php @@ -33,8 +33,8 @@ abstract class AbstractDbValidator extends AbstractValidator implements AdapterA /** * Error constants */ - public const ERROR_NO_RECORD_FOUND = 'noRecordFound'; - public const ERROR_RECORD_FOUND = 'recordFound'; + public const string ERROR_NO_RECORD_FOUND = 'noRecordFound'; + public const string ERROR_RECORD_FOUND = 'recordFound'; /** * Message templates. From 2c893d93e24c8dc124a89b61aa14e7682b7f4102 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Fri, 2 Oct 2026 21:58:54 -0500 Subject: [PATCH 4/4] chore: remove an unused mago-ignore pragma Signed-off-by: Joey Smith --- src/AbstractDbValidator.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/AbstractDbValidator.php b/src/AbstractDbValidator.php index 2ca99c3..7cec8f2 100644 --- a/src/AbstractDbValidator.php +++ b/src/AbstractDbValidator.php @@ -41,7 +41,6 @@ abstract class AbstractDbValidator extends AbstractValidator implements AdapterA * * @var array */ - // @mago-ignore analysis:incompatible-property-type public array $messageTemplates = [ self::ERROR_NO_RECORD_FOUND => 'No record matching the input was found', self::ERROR_RECORD_FOUND => 'A record matching the input was found',