Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
tests:
name: PHP ${{ matrix.php }} — Tests
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4']

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: intl, json, mbstring
coverage: none

- name: Cache Composer dependencies
uses: actions/cache@v4
with:
path: vendor
key: composer-${{ matrix.php }}-${{ hashFiles('composer.json') }}
restore-keys: composer-${{ matrix.php }}-

- name: Install dependencies
run: composer install --no-interaction --prefer-dist

- name: Run PHPUnit
run: vendor/bin/phpunit --colors

static-analysis:
name: PHPStan
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
extensions: intl, json, mbstring
coverage: none

- name: Cache Composer dependencies
uses: actions/cache@v4
with:
path: vendor
key: composer-8.3-${{ hashFiles('composer.json') }}
restore-keys: composer-8.3-

- name: Install dependencies
run: composer install --no-interaction --prefer-dist

- name: Run PHPStan
run: vendor/bin/phpstan analyse src tests --no-progress
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ Use `ValidatorFactory` to retrieve any validator by its type key:
```php
use QDenka\EasyValidation\Application\Validators\ValidatorFactory;

\$types = ['email','google_email','disposable_email','url','number','date','ip','uuid','json','base64','phone'];
foreach (\$types as \$type) {
\$validator = ValidatorFactory::create(\$type);
\$value = 'test_value_for_' . \$type;
if (\$validator && \$validator->validate(\$value)) {
echo "[\$type] valid\n";
$types = ['email','google_email','disposable_email','url','number','date','ip','uuid','json','base64','phone'];
foreach ($types as $type) {
$validator = ValidatorFactory::create($type);
$value = 'test_value_for_' . $type;
if ($validator && $validator->validate($value)) {
echo "[$type] valid\n";
} else {
echo "[\$type] invalid\n";
echo "[$type] invalid\n";
}
}
```
Expand All @@ -92,7 +92,7 @@ if (Validator::isGoogleMail('user@gmail.com')) {
echo "It's a Gmail address";
}

if (!Validator::isDisposableEmail('temp@mailinator.com')) {
if (Validator::isDisposableEmail('temp@mailinator.com')) {
echo "Disposable email detected";
}

Expand All @@ -115,7 +115,7 @@ Validator::isValidPhone('+1234567890');
| ------------------ | ---------------------- | ------------------------------------- |
| `email` | `isValidEmail()` | RFC-compliant email |
| `google_email` | `isGoogleMail()` | Gmail & Googlemail domains |
| `disposable_email` | `!isDisposableEmail()` | Blacklisted disposable domains |
| `disposable_email` | `isDisposableEmail()` | Blacklisted disposable domains |
| `url` | `isValidUrl()` | HTTP/HTTPS URLs |
| `number` | `isValidNumber()` | Numeric values |
| `date` | `isValidDate()` | Date in `Y-m-d` (configurable format) |
Expand Down Expand Up @@ -150,8 +150,8 @@ Ensure all domains are lowercase.
To add a new validator:

1. Implement `ValidatorInterface` in `src/Domain/YourType/YourValidator.php`.
2. Add your class to `VALIDATOR_MAP` in `src/Infrastructure/Factories/Validator.php`.
3. (Optional) Add a static helper in the same class.
2. Register your class in `ValidatorFactory` (`src/Application/Validators/ValidatorFactory.php`).
3. (Optional) Add a static helper in `Validator` facade (`src/Infrastructure/Factories/Validator.php`).
4. Write tests under `tests/` following existing patterns.

---
Expand Down
27 changes: 15 additions & 12 deletions src/Application/Validators/ValidatorFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,25 @@

namespace QDenka\EasyValidation\Application\Validators;

use QDenka\EasyValidation\Domain\Ip\IpValidator;
use QDenka\EasyValidation\Domain\Uuid\UuidValidator;
use QDenka\EasyValidation\Domain\Json\JsonValidator;
use QDenka\EasyValidation\Domain\Contracts\ValidatorFactoryInterface;
use QDenka\EasyValidation\Domain\Contracts\ValidatorInterface;
use QDenka\EasyValidation\Domain\Base64\Base64Validator;
use QDenka\EasyValidation\Domain\Phone\PhoneNumberValidator;
use QDenka\EasyValidation\Domain\Date\DateValidator;
use QDenka\EasyValidation\Domain\Email\DisposableEmailValidator;
use QDenka\EasyValidation\Domain\Email\EmailValidator;
use QDenka\EasyValidation\Domain\Email\GoogleMailValidator;
use QDenka\EasyValidation\Domain\Email\DisposableEmailValidator;
use QDenka\EasyValidation\Domain\Date\DateValidator;
use QDenka\EasyValidation\Domain\Ip\IpValidator;
use QDenka\EasyValidation\Domain\Json\JsonValidator;
use QDenka\EasyValidation\Domain\Number\NumberValidator;
use QDenka\EasyValidation\Domain\Phone\PhoneNumberValidator;
use QDenka\EasyValidation\Domain\Url\UrlValidator;
use QDenka\EasyValidation\Domain\Uuid\UuidValidator;
use QDenka\EasyValidation\Infrastructure\Email\FileDisposableEmailDomainProvider;


class ValidatorFactory implements ValidatorFactoryInterface
{
private const CONFIG_PATH = __DIR__ . '/../../../config/disposable_domains.php';

public static function create(string $type): ?ValidatorInterface
{
switch (strtolower($type)) {
Expand All @@ -26,14 +29,14 @@ public static function create(string $type): ?ValidatorInterface
case 'google_email':
return new GoogleMailValidator();
case 'disposable_email':
$provider = new FileDisposableEmailDomainProvider(__DIR__ . '/../../config/disposable_domains.php');
$provider = new FileDisposableEmailDomainProvider(self::CONFIG_PATH);
return new DisposableEmailValidator($provider);
case 'date':
return new DateValidator();
case 'number':
return new NumberValidator();
case 'url':
return new UrlValidator();
case 'number':
return new NumberValidator();
case 'date':
return new DateValidator();
case 'ip':
return new IpValidator();
case 'uuid':
Expand Down
17 changes: 0 additions & 17 deletions src/Application/Validators/ValidatorFactoryInterface.php

This file was deleted.

2 changes: 1 addition & 1 deletion src/Domain/Base64/Base64Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace QDenka\EasyValidation\Domain\Base64;

use QDenka\EasyValidation\Application\Validators\ValidatorInterface;
use QDenka\EasyValidation\Domain\Contracts\ValidatorInterface;

/**
* Validates Base64-encoded strings.
Expand Down
21 changes: 21 additions & 0 deletions src/Domain/Contracts/ValidatorFactoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace QDenka\EasyValidation\Domain\Contracts;

/**
* Interface ValidatorFactoryInterface
*
* Contract for creating validator instances by type key.
*
* @package QDenka\EasyValidation\Domain\Contracts
*/
interface ValidatorFactoryInterface
{
/**
* Create a validator by type key.
*
* @param string $type
* @return ValidatorInterface|null
*/
public static function create(string $type): ?ValidatorInterface;
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<?php

namespace QDenka\EasyValidation\Application\Validators;
namespace QDenka\EasyValidation\Domain\Contracts;

/**
* Interface ValidatorInterface
*
* @package QDenka\EasyValidation\Application\Validators
* Core domain contract that all validators must implement.
*
* @package QDenka\EasyValidation\Domain\Contracts
*/
interface ValidatorInterface
{
Expand Down
2 changes: 1 addition & 1 deletion src/Domain/Date/DateValidator.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
namespace QDenka\EasyValidation\Domain\Date;

use QDenka\EasyValidation\Application\Validators\ValidatorInterface;
use QDenka\EasyValidation\Domain\Contracts\ValidatorInterface;

/**
* Validates dates in a given format (default YYYY-MM-DD).
Expand Down
2 changes: 1 addition & 1 deletion src/Domain/Email/DisposableEmailValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace QDenka\EasyValidation\Domain\Email;

use QDenka\EasyValidation\Application\Validators\ValidatorInterface;
use QDenka\EasyValidation\Domain\Contracts\ValidatorInterface;
use QDenka\EasyValidation\Domain\Email\Provider\DisposableEmailDomainProviderInterface;

/**
Expand Down
4 changes: 2 additions & 2 deletions src/Domain/Email/EmailValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace QDenka\EasyValidation\Domain\Email;

use QDenka\EasyValidation\Application\Validators\ValidatorInterface;
use QDenka\EasyValidation\Domain\Contracts\ValidatorInterface;

/**
* Class EmailValidator
Expand All @@ -14,7 +14,7 @@ class EmailValidator implements ValidatorInterface
/**
* Validate the given email value
*
* @param mixed $value
* @param string $value
* @return bool
*/
public function validate(string $value): bool
Expand Down
2 changes: 1 addition & 1 deletion src/Domain/Email/GoogleMailValidator.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
namespace QDenka\EasyValidation\Domain\Email;

use QDenka\EasyValidation\Application\Validators\ValidatorInterface;
use QDenka\EasyValidation\Domain\Contracts\ValidatorInterface;

/**
* Checks that email is valid *and* uses Gmail or Googlemail domain.
Expand Down
2 changes: 1 addition & 1 deletion src/Domain/Ip/IpValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace QDenka\EasyValidation\Domain\Ip;

use QDenka\EasyValidation\Application\Validators\ValidatorInterface;
use QDenka\EasyValidation\Domain\Contracts\ValidatorInterface;

/**
* Validates IPv4 and IPv6 addresses.
Expand Down
6 changes: 1 addition & 5 deletions src/Domain/Json/JsonValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace QDenka\EasyValidation\Domain\Json;

use QDenka\EasyValidation\Application\Validators\ValidatorInterface;
use QDenka\EasyValidation\Domain\Contracts\ValidatorInterface;

/**
* Checks if a string is valid JSON.
Expand All @@ -17,10 +17,6 @@ class JsonValidator implements ValidatorInterface
*/
public function validate(string $value): bool
{
if (! is_string($value)) {
return false;

}
json_decode($value);
return json_last_error() === JSON_ERROR_NONE;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Domain/Number/NumberValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace QDenka\EasyValidation\Domain\Number;

use QDenka\EasyValidation\Application\Validators\ValidatorInterface;
use QDenka\EasyValidation\Domain\Contracts\ValidatorInterface;

/**
* Class NumberValidator
Expand All @@ -14,7 +14,7 @@ class NumberValidator implements ValidatorInterface
/**
* Validate the given number value
*
* @param mixed $value
* @param string $value
* @return bool
*/
public function validate(string $value): bool
Expand Down
2 changes: 1 addition & 1 deletion src/Domain/Phone/PhoneNumberValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace QDenka\EasyValidation\Domain\Phone;

use QDenka\EasyValidation\Application\Validators\ValidatorInterface;
use QDenka\EasyValidation\Domain\Contracts\ValidatorInterface;

/**
* Basic international phone number check (E.164).
Expand Down
12 changes: 10 additions & 2 deletions src/Domain/Url/UrlValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

namespace QDenka\EasyValidation\Domain\Url;

use QDenka\EasyValidation\Application\Validators\ValidatorInterface;
use QDenka\EasyValidation\Domain\Contracts\ValidatorInterface;

/**
* Class UrlValidator
*
* Validates HTTP and HTTPS URLs only.
*
* @package QDenka\EasyValidation\Domain\Url
*/
class UrlValidator implements ValidatorInterface
Expand All @@ -19,6 +21,12 @@ class UrlValidator implements ValidatorInterface
*/
public function validate(string $value): bool
{
return filter_var($value, FILTER_VALIDATE_URL) !== false;
if (filter_var($value, FILTER_VALIDATE_URL) === false) {
return false;
}

$scheme = parse_url($value, PHP_URL_SCHEME);

return in_array(strtolower($scheme ?? ''), ['http', 'https'], true);
}
}
2 changes: 1 addition & 1 deletion src/Domain/Uuid/UuidValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace QDenka\EasyValidation\Domain\Uuid;

use QDenka\EasyValidation\Application\Validators\ValidatorInterface;
use QDenka\EasyValidation\Domain\Contracts\ValidatorInterface;

/**
* Validates UUID v1–v5.
Expand Down
Loading