Closed kiankamgar closed 6 months ago
Hi again, do you have any plans to merge these changes in the future?
The Laravel-Validate support Laravel 9 and I don't think we can merge this!
I can make the code support laravel 8 and 9 as well, if you want. We can decide to initialize rule class based on the laravel version
The old rule class is deprecated and soon or later it will be removed
Can you show how to do it?
We can change every rule class to a facade, for example consider ValidPhoneNumber:
<?php
namespace Milwad\LaravelValidate\Rules;
use Illuminate\Support\Facades\Facade;
class ValidPhoneNumber extends Facade
{
protected static function getFacadeAccessor()
{
if (app()->version() < 10) {
return new \Milwad\LaravelValidate\Rules\Legacy\ValidPhoneNumber();
}
return new \Milwad\LaravelValidate\Rules\Modern\ValidPhoneNumber();
}
}
Now we have Modern and Legacy forders in our Rule folder. When a user requests a validation, we check laravel version and return related class based on it: \Milwad\LaravelValidate\Rules\Legacy\ValidPhoneNumber
<?php
namespace Milwad\LaravelValidate\Rules\Legacy;
use Illuminate\Contracts\Validation\Rule;
use Milwad\LaravelValidate\Utils\CountryPhoneCallback;
class ValidPhoneNumber implements Rule
{
public function __construct(protected ?string $code = null)
{
}
/**
* Check phone number is valid.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
if (is_string($this->code)) {
$passes = (new CountryPhoneCallback($value, $this->code))->callPhoneValidator();
return collect($passes)->some(fn ($passe) => $passe);
}
return preg_match('/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/', $value);
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return __('validate.phone-number');
}
}
\Milwad\LaravelValidate\Rules\Modern\ValidPhoneNumber:
<?php
namespace Milwad\LaravelValidate\Rules\Modern;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
use Milwad\LaravelValidate\Utils\CountryPhoneCallback;
use function collect;
class ValidPhoneNumber implements ValidationRule
{
public function __construct(
protected ?string $code = null
){}
/**
* Check phone number is valid.
*
* @param string $attribute
* @param mixed $value
* @param Closure $fail
* @return void
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (! $this->isPhoneNumberValid($value)) {
$fail('validate.phone-number')->translate();
}
}
/**
* Check if phone number is valid
*
* @param mixed $value
* @return bool
*/
private function isPhoneNumberValid(mixed $value): bool
{
if (is_string($this->code)) {
$passes = (new CountryPhoneCallback($value, $this->code))->callPhoneValidator();
return collect($passes)->some(fn ($passe) => $passe);
}
return preg_match('/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/', $value);
}
}
Even we can extract our boolean logic from these two classes and bring it to another class that is responsible for the result and in each class we call the Logic class and return its value
Tell me what do you think about this approach. If you want I can do it and you can see the result and decide
I don't like this way, if Laravel doesn't support these rules in the future, we think about it and you can create a new PR again or create an issue to talk about this.
I just refactored rule classes, If you want I can refactor tests as well