Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[6.x] Allow formatting an implicit attribute using a closure #31246

Merged
merged 5 commits into from
Jan 27, 2020

Conversation

themsaid
Copy link
Member

This PR adds a setImplicitAttributesFormatter method to the validator that allows the instance to output a message that says:

age at line 1 must be an integer

instead of

0.age must be an integer
validator(
    [['age' => 'thirty']],
    ['*.age' => 'integer']
)->setImplicitAttributesFormatter(function ($attribute) {
    [$line, $attribute] = explode('.', $attribute);

    return sprintf('%s at line %d', $attribute, $line + 1);
})->validate();

* @return $this
*/
public function setImplicitAttributesFormatter(callable $formatter)
public function setImplicitAttributesFormatter($formatter)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can keep the typehint (callable $formatter = null)

@themsaid themsaid closed this Jan 27, 2020
@themsaid themsaid reopened this Jan 27, 2020
@taylorotwell taylorotwell merged commit 86dc9df into laravel:6.x Jan 27, 2020
@MarceauKa
Copy link

MarceauKa commented Jan 28, 2020

Hi @themsaid , I'm just reading the 6.13 changelog. Can you help me to understand this new behavior with a real case usage? 😇

@PovilasKorop
Copy link
Contributor

Hi @themsaid! Great feature it seems, I want to shoot a video about it, but I don't understand - is it possible to use it with FormRequest classes? Or what would be the syntax with $this->validate() in Controller?

@themsaid
Copy link
Member Author

@PovilasKorop You'll want to use:

function withValidator($validator){
    $validator->setImplicitAttributesFormatter(function ($attribute) {
        [$line, $attribute] = explode('.', $attribute);

        return sprintf('%s at line %d', $attribute, $line + 1);
   });
}

@MarceauKa the example above is a real use case :)

@PovilasKorop
Copy link
Contributor

PovilasKorop commented Jan 29, 2020

@themsaid thanks, it's working, tried it with a bit changed example, will shoot a video tomorrow.
For anyone else, here's the code:

class StoreOrderRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'customer_name' => 'required',
            'products.*.product_id' => 'required',
        ];
    }

    function withValidator($validator){
        $validator->setImplicitAttributesFormatter(function ($attribute) {
            [$field, $line] = explode('.', $attribute);
            if ($field == 'products') {
                return 'product number ' . ($line+1);
            }
        });
    }
}

@ankurk91
Copy link
Contributor

ankurk91 commented Aug 9, 2021

I made it working like in Laravel 8.x

    public function withValidator(Validator $validator)
    {
        $validator->setImplicitAttributesFormatter(function ($attribute) {
            return Str::of($attribute)->afterLast('.');
        });
    }

This is a hidden gem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants