eksa-com/laravel-validation
A Laravel package that extends the framework's built-in validation system with additional rules and reusable helpers, making form and request validation more expressive. Integrates with Laravel's validator and custom rule objects.
Reality check first. This package has zero stars, zero dependents, and a repository link (andersao/laravel-validation) that resolves to a personal account rather than the eksa-com vendor name in the package string. Before writing a single line against it, spend ten minutes confirming it is what you think it is:
composer show eksa-com/laravel-validation # version, requirements, autoload
ls vendor/eksa-com/laravel-validation/src
cat vendor/eksa-com/laravel-validation/composer.json
If composer show reports no laravel/framework constraint, or the constraint tops out below your app's Laravel version, stop — you are looking at an abandoned artifact.
Minimal steps (assuming it holds up):
composer require eksa-com/laravel-validationcomposer.json → extra.laravel.providers. If present and not auto-discovered (Laravel < 5.5), register it in config/app.php.config/validation.php or similar in the package root and publish it:
php artisan vendor:publish --provider="..."src/ top to bottom. At this size the whole package is probably 3–6 classes; you can absorb the entire public surface in one sitting, which is the only real advantage of a micro-package like this.Where to look first: the base validator/abstract class. That is where the package's opinion lives — whether it expects a rules() method per validator, whether it throws or returns a boolean, whether it binds to the container.
First use case: validating input outside a controller. FormRequests only fire on HTTP. The moment you need the same rule set in an artisan command, a queued job, or an importer, you either duplicate rules or extract them. A "validation service" package exists to make that extraction clean:
// console command / job — no FormRequest available
$validator = app(ImportRowValidator::class);
if ($validator->fails($row)) {
$this->warn($validator->errors()->first());
continue;
}
If the package does not make that scenario meaningfully nicer than a plain Validator::make($row, $rules), do not adopt it. Write a 20-line base class in your own app/Validation namespace instead. That is the honest benchmark.
Pattern 1 — Validator-per-payload, shared across entry points. Define one class per meaningful input shape (CreateOrder, ImportRow, WebhookPayload) and call it from controllers, jobs, and commands alike. Rules live in exactly one place; HTTP-specific concerns (authorize, redirect-back) stay in the FormRequest, which delegates:
class StoreOrderRequest extends FormRequest
{
public function rules(): array
{
return app(CreateOrderValidator::class)->rules();
}
}
Pattern 2 — Service-layer validation before persistence. The common workflow this package name implies: controller → service → validator → repository. Validate at the edge of the service so the service is safe to call from anywhere:
class OrderService
{
public function __construct(private CreateOrderValidator $validator) {}
public function create(array $data): Order
{
$this->validator->validate($data); // throws on failure
return Order::create($data);
}
}
The win here is that a job dispatching the same service gets identical guarantees — no silent bad data from a non-HTTP path.
Pattern 3 — Container binding for rule swapping. If the package registers validators in the container, bind interfaces in a service provider so tests can substitute permissive fakes. This is the main reason to prefer a package over inline Validator::make calls: your validators become injectable, mockable collaborators.
Integration tips:
rules(). Do not let the package become a second, parallel rules DSL.RuleServiceProvider rather than sprinkling new SomeRule through validators.validate() → throws ValidationException or fails() → boolean, and never mix. Laravel's exception handler already renders ValidationException as a 422 with the errors bag, so the throwing variant gives you free API-compatible error responses.$this->expectException(ValidationException::class) and assert on ->errors(), so validation contract changes fail CI rather than production.Abandonment is the primary risk, not bugs. Zero dependents means almost nobody has run this against a modern Laravel. Expect stale illuminate/* constraints, no phpunit.xml, and code written for Laravel 5.x ($this->app->make, array syntax). Budget for a fork if you adopt it. Pin the version in composer.json and vendor it mentally as "our code" from day one.
Version constraint mismatch. If composer require resolves against an old Laravel, do not --ignore-platform-reqs your way past it. That usually masks removed helpers or changed Validator contracts and fails at runtime, deep in a request.
Auto-discovery blind spots. Forked packages frequently keep the original extra.laravel.providers pointing at the original vendor namespace. vendor:publish will then silently publish nothing. Check the provider FQCN character by character.
Exception vs. boolean ambiguity. If the package offers both validate() and fails(), confirm which one the README actually documents — the undocumented path is the one with the bug. In particular verify whether errors are attached to a MessageBag you can retrieve afterward, or only thrown.
Double validation. A classic mistake: FormRequest validates, then the service validator runs the same rules again. Harmless but wasteful and confusing in logs. Decide the boundary — HTTP shape in the FormRequest, domain invariants in the validator — and document it in the class docblock.
Translation and message customization. Custom messages() / attributes() support is the first thing small validation packages skip. Verify with a deliberately failing test case; if there is no hook, you will be editing vendor files or dropping the package.
Nested and wildcard rules. Test items.*.sku style rules explicitly. Hand-rolled validation wrappers very often mishandle wildcard expansion or dot-notation error keys, and the failure is silent (returns valid when it should not).
Debugging: when a validator says "passes" and the DB disagrees, dump the resolved rule array (dd($validator->rules())) rather than reading the class — the usual cause is a rule built conditionally and never reached, or a Rule::unique with the wrong table inferred from the class name.
Extension point to prefer: if the package has no messages() hook, subclass its base validator in your own namespace and override there. Never patch vendor/; a fork under your own vendor name with a composer.json repositories VCS entry is far cheaper to maintain than a post-install patch script.
Migration off-ramp. Write validators so their public method signature (rules(), validate(array $data)) matches what a hand-rolled base class would offer. Then removing the package is a find-and-replace on the base class, not a rewrite. Given the dependency profile here, design for that exit from the start.
How can I help you explore Laravel packages today?