Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Extra Validator Bundle Laravel Package

pixelavengers/extra-validator-bundle

Extra Validator Bundle extends Laravel's validator with additional custom rules for common validation needs. It helps keep form requests and controllers cleaner by replacing repetitive custom checks with reusable, easy-to-apply validation rules.

View on GitHub
Deep Wiki
Context7

Getting Started

First: this is not a Laravel package. pixelavengers/extra-validator-bundle is a Symfony 2-era bundle (ricardclau/PixelavengersExtraValidatorBundle). There is no service provider, no facade, no config file Laravel can publish, and no extra.laravel block for package discovery. You will not be able to composer require it into a modern Laravel app without version gymnastics, because its constraints almost certainly pin Symfony 2.x components and an old PHP range.

So the realistic "getting started" is: evaluate whether to vendor it, fork it, or extract the algorithms.

  1. Inspect before installing. Read the constraint classes first. They live under Validator/Constraints/ and follow the classic Symfony pair pattern: a Constraint subclass plus a ConstraintValidator implementation. The interesting logic (checksum math, regex, normalization) is entirely inside the validator's validate() method.
  2. Attempt the install only to read it.
    composer require pixelavengers/extra-validator-bundle --dry-run
    
    Expect a wall of conflicts. If it resolves, you are probably on an ancient PHP.
  3. First use case — extract a single rule. Pick the validator you actually need (these bundles typically ship Spanish DNI/NIE/CIF, IBAN, or similar format checks). Copy the validate() body into a native Laravel Rule object and drop the Symfony dependency entirely. That is the highest-value first step and takes minutes.
// app/Rules/Nie.php — ported from the bundle's validator
namespace App\Rules;

use Closure;
use Illuminate\Contracts\Validation\ValidationRule;

class Nie implements ValidationRule
{
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        $value = strtoupper(str_replace(['-', ' '], '', (string) $value));

        if (! preg_match('/^[XYZ]\d{7}[A-Z]$/', $value)) {
            $fail("The {$attribute} is not a valid NIE.");
            return;
        }

        $map = ['X' => 0, 'Y' => 1, 'Z' => 2];
        $digits = $map[$value[0]] . substr($value, 1, 7);
        $letter = 'TRWAGMYFPDXBNJZSQVHLCKE'[$digits % 23];

        if ($letter !== $value[8]) {
            $fail("The {$attribute} is not a valid NIE.");
        }
    }
}
$request->validate([
    'nie' => ['required', 'string', new \App\Rules\Nie],
]);

Implementation Patterns

Pattern A — Rule adapter around the Symfony constraint. If you must keep the dependency (e.g. you are porting a Symfony app incrementally), wrap the constraint in a Laravel rule and drive a standalone Symfony validator.

namespace App\Rules;

use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
use Symfony\Component\Validator\Validation;
use Pixelavengers\ExtraValidatorBundle\Validator\Constraints as Extra;

class SymfonyConstraintRule implements ValidationRule
{
    public function __construct(private object $constraint) {}

    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        $violations = Validation::createValidator()
            ->validate($value, $this->constraint);

        foreach ($violations as $violation) {
            $fail($violation->getMessage());
        }
    }
}
'id' => ['required', new SymfonyConstraintRule(new Extra\SomeIdConstraint)],

Pattern B — Bind the Symfony validator in a service provider. If you go the adapter route, register a singleton so you are not rebuilding the validator per field, and register the bundle's validators as tagged services. Symfony's ConstraintValidatorFactory expects services tagged validator.constraint_validator; Laravel has no equivalent, so you wire them manually.

$this->app->singleton(\Symfony\Component\Validator\Validator\ValidatorInterface::class, function () {
    return \Symfony\Component\Validator\Validation::createValidator();
});

Pattern C — Port to a reusable rule set (recommended). Convert each validator into a dedicated Rule class under app/Rules/, add Pest/PHPUnit coverage with the fixture values from the bundle's tests (there usually are a few, and they are gold for parity), and delete the dependency. You keep the intent, lose the abandoned code.

Pattern D — Batch use in Form Requests. Once ported, these are ordinary rules and compose naturally with nullable, bail, and conditional rules. Chain them in a FormRequest::rules() method so controller code stays clean.

Pattern E — Reuse for outbound data hygiene. These format validators are as useful for sanitising data before persisting (normalising an IBAN or tax ID) as they are for rejecting input. Consider a small NormalizesIdentifier concern shared between the rule and your model mutators.

Gotchas and Tips

  • Symfony 2 legacy API. Expect getName(), setDefaultOption(), getDefaultOption(), and validatedBy(). The first two are removed in Symfony 3+/4+. If you install on anything modern these will fatal, which is the practical reason a direct install usually fails.
  • No Laravel auto-discovery. The bundle's composer.json will have type: symfony-bundle and a Symfony\Component\HttpKernel\Bundle\Bundle subclass. Composer will happily download it, but Laravel will never load it. Do not expect a facade or config publish to appear — it will not, and there is nothing to debug.
  • Translation domain mismatch. Symfony constraints carry a message and a translation domain; Laravel's translator is a different API. Messages will come through in whatever the constraint's default string is, not your lang/ files. If you need localised output, translate in the adapter, not by hoping Laravel picks it up.
  • validatedBy() returns Symfony class names. In the adapter pattern, the constraint factory resolves validators by class name from a container that Laravel does not populate. Either instantiate the validator yourself or accept the default no-arg constructor; the latter fails for any validator with dependencies.
  • Abandonment risk is the headline. 14 stars, zero dependents, and a 0.1 score against your evaluation means there is no maintenance path, no security response, and no PHP 8.x compatibility guarantee. Treat any logic you take as a fork with your name on it, pinned by tests.
  • Debugging tip. When a constraint silently passes, check the value type first — Symfony validators frequently return early on null and sometimes on non-strings, whereas Laravel's nullable/string order may hand it something unexpected. Add an explicit is_string($value) guard at the top of any ported validate().
  • Extension point to prefer. If you decide to keep a constraint rather than port it, the clean seam is Validator::extend() in a service provider. It gives you a named rule ('nie') callable everywhere, which is far closer to Laravel ergonomics than the adapter class and hides the Symfony dependency from your controllers.
  • Test with real fixtures. Grab the invalid/valid cases from the bundle's tests (checksum edge cases like lowercase input, spaces, hyphens, and the X/Y/Z prefix mapping) before you delete the dependency. Those cases are the only reliable way to prove your port is equivalent.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource