sourcetoad/rule-helper-for-laravel
Fluent helpers for building Laravel validation rules. Use RuleSet to chain required/unique/max and add custom rules, or Rule for static rule builders. Supports reusable defined rule sets and extras like requiredIfAll/requiredIfAny for complex conditions.
Installation
composer require sourcetoad/rule-helper-for-laravel
Publish the config (if needed):
php artisan vendor:publish --provider="SourceToad\RuleHelper\RuleHelperServiceProvider"
First Use Case
Define a custom rule in app/Rules/CustomRule.php:
use SourceToad\RuleHelper\Rules\BaseRule;
class CustomRule extends BaseRule
{
public function passes($attribute, $value)
{
return $value === 'expected';
}
}
Use it in a Form Request:
use App\Rules\CustomRule;
public function rules()
{
return [
'field_name' => ['required', new CustomRule],
];
}
Key Files to Review
config/rule-helper.php (for global settings)app/Rules/ (custom rule storage)vendor/sourcetoad/rule-helper-for-laravel/src/ (core logic)Reusable Rule Creation
Extend BaseRule for shared validation logic:
class EmailDomainRule extends BaseRule
{
protected $domain;
public function __construct($domain)
{
$this->domain = $domain;
}
public function passes($attribute, $value)
{
return str_ends_with($value, "@{$this->domain}");
}
}
Usage:
'email' => [new EmailDomainRule('example.com')]
Rule Chaining
Combine rules with RuleHelper::combine():
use SourceToad\RuleHelper\Facades\RuleHelper;
$rule = RuleHelper::combine([
'min:5',
'max:20',
new CustomRule,
]);
Dynamic Rule Generation
Use RuleHelper::make() for runtime rules:
$rule = RuleHelper::make(function ($value, $attribute) {
return $value === request('confirm_' . $attribute);
});
Integration with Laravel Pipelines Pass rules through pipelines for pre/post-processing:
$value = $request->input('field')
->through(fn ($value) => strtolower($value))
->then(new CustomRule)
->passes();
API Resource Validation Attach rules to API resources:
use SourceToad\RuleHelper\Traits\ValidatesRules;
class UserResource extends JsonResource
{
use ValidatesRules;
public function toArray($request)
{
$this->validateRules($request, [
'name' => [new CustomRule],
]);
return parent::toArray($request);
}
}
Caching Rules
$rule = Cache::remember("rule_{$key}", now()->addHours(1), fn() => new CustomRule);
Attribute Name Confusion
$attribute parameter in passes() may not match the input key if using sometimes or nested arrays. Debug with:
dd($attribute, $value, $this->getAttributeName());
Locale-Specific Rules
date_format rely on PHP’s locale settings. Set explicitly:
setlocale(LC_TIME, 'en_US.UTF-8');
Dependency Injection
public function passes($attribute, $value)
{
return app(MyService::class)->check($value);
}
Testing Quirks
BaseRule and overriding methods:
$mockRule = Mockery::mock(CustomRule::class)->makePartial();
$mockRule->shouldReceive('passes')->andReturn(true);
Rule Organization
Group related rules in namespaces (e.g., App\Rules\Auth, App\Rules\Payment).
Error Message Customization
Override message() in BaseRule:
public function message()
{
return 'The :attribute must be a valid :rule.';
}
Conditional Rules
Use RuleHelper::when() for context-aware rules:
$rule = RuleHelper::when(
fn() => auth()->check(),
fn() => new AdminOnlyRule
);
Performance
For heavy rules, implement shouldSkipValidation() to bypass checks when possible:
public function shouldSkipValidation()
{
return $this->attribute === 'cached_field';
}
Debugging
Enable verbose rule logging in config/rule-helper.php:
'debug' => env('APP_DEBUG', false),
Logs will appear in storage/logs/rule-helper.log.
Extending Core Rules Override Laravel’s built-in rules by publishing the package’s config and modifying:
'extensions' => [
'custom' => \App\Rules\CustomRule::class,
],
How can I help you explore Laravel packages today?