Skip to content

Conversation

@QDenka
Copy link
Owner

@QDenka QDenka commented Feb 8, 2026

Summary

This PR addresses critical bugs, DRY violations, DDD layer misplacements, and low test coverage.

Changes

Bug Fixes

  • Fix disposable domains config path in ValidatorFactory — path resolved to src/config/ instead of project root config/. Changed from ../../config to ../../../config.
  • Fix misleading ! in READMEisDisposableEmail() already negates internally, so the ! prefix in the example inverted the intended logic.

Refactoring

  • Move ValidatorInterface and ValidatorFactoryInterface to Domain\Contracts — Domain layer should not depend on Application layer (proper DDD dependency direction).
  • Remove duplicate factory logic from Validator facade — facade now delegates to ValidatorFactory instead of maintaining its own VALIDATOR_MAP copy. One source of truth when adding new validators.
  • Convert ValidatorFactory from switch/case to VALIDATOR_MAP constant — consistent with the map-based approach, easier to extend.
  • Delete deprecated interface files from Application\Validators\.

Validator Improvements

  • UrlValidator — now only accepts http:// and https:// schemes (matching documented behavior), rejects ftp://, file://, etc.
  • JsonValidator — removed redundant is_string() check (parameter is already type-hinted as string).

Tests

  • Expanded test coverage from 4/11 to 11/11 validators — added tests for GoogleMail, DisposableEmail, IP, UUID, JSON, Base64, and Phone.
  • Added edge-case tests: impossible date 2023-02-30, ftp:// rejection, invalid UUID version byte, phone without + prefix, too-short phone numbers, factory create() returning working instance.

Commits

All changes are atomic — each commit addresses a single concern.

The path was resolving to src/config/ instead of the project root
config/ directory. Changed from '../../config' to '../../../config'
to correctly traverse three levels up from src/Application/Validators/.
Removed the erroneous `!` negation before `Validator::isDisposableEmail()`.
The method already returns true when the email IS disposable (it internally
negates the validator result), so the extra `!` inverted the intended logic.
Also updated the validators table to remove the `!` prefix from the helper
column, and clarified the Extending section instructions.
…main layer

Moved both interfaces from src/Application/Validators/ to
src/Domain/Contracts/ so that the Domain layer does not depend
on the Application layer (proper DDD dependency direction).

Updated all validator imports across Domain layer to reference
the new namespace QDenka\EasyValidation\Domain\Contracts\.

Also fixed UrlValidator to only accept http/https schemes
(matching the documented behavior) and removed redundant
is_string() check from JsonValidator (parameter is already
type-hinted as string).
Validator facade now delegates all creation to ValidatorFactory
instead of maintaining its own VALIDATOR_MAP copy. This eliminates
the DRY violation — only one place to update when adding validators.

Also updated both files to use Domain\Contracts namespace for
ValidatorInterface and ValidatorFactoryInterface.

Converted ValidatorFactory from switch/case to VALIDATOR_MAP
constant for consistency and maintainability.
This interface has been moved to Domain\Contracts\ValidatorInterface.
The old file is no longer referenced by any class.
…n layer

This interface has been moved to Domain\Contracts\ValidatorFactoryInterface.
The old file is no longer referenced by any class.
Previously only Email, URL, Number and Date had tests (4 of 11).
Added tests for GoogleMail, DisposableEmail, IP, UUID, JSON,
Base64 and Phone validators. Also added edge-case tests:
- impossible date (2023-02-30)
- ftp:// rejection in URL validator
- UUID with invalid version byte
- phone without + prefix and too-short numbers
- factory create() returns working validator instance
Runs PHPUnit across PHP 7.4, 8.0, 8.1, 8.2, 8.3, 8.4 matrix.
Runs PHPStan static analysis on PHP 8.3.
Triggered on push to main and on pull requests targeting main.
Includes Composer dependency caching for faster builds.
…tibility

PHPStan cannot resolve constructor signatures through dynamic
`new $class()` calls. Replaced VALIDATOR_MAP + dynamic instantiation
with explicit switch/case so PHPStan can statically verify each
constructor call. Extracted config path to a class constant.
@QDenka QDenka merged commit 0eb7e9b into main Feb 8, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant