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

[11.x] Define global validation logic for Laravel Prompts #49497

Merged

Conversation

cerbero90
Copy link
Contributor

@cerbero90 cerbero90 commented Dec 27, 2023

This PR is currently a draft because it depends on this PR on Laravel Prompts.

The end goal is to define a global validation logic for Laravel Prompts that leverages the Laravel validation rules, while keeping Laravel Prompts framework-agnostic.

Developers can then reuse the existing validation rules when calling Laravel Prompts:

$name = text('What is your name?', validate: 'required|min:2');

This PR aims to take full advantage of the Laravel validator features by optionally letting developers define custom error messages or attributes, e.g.:

class SampleCommand extends Command
{
    public function handle()
    {
        text('What is your name?', validate: ['name' => 'required']);
    }

    protected function messages()
    {
        return ['name.required' => 'Your :attribute is mandatory.'];
    }

    protected function attributes()
    {
        return ['name' => 'full name'];
    }
}

Update: description updated to reflect this comment.

@cerbero90
Copy link
Contributor Author

Side notes for @jessarcher:

I may have found an alternative solution to aliases for setting the field name and allowing a complete control of developers over the console output.

By default, when we pass the validation rules to the Prompts, the field name answer is used:

text('What is your name', validate: 'required|min:2');
// or
text('What is your name', validate: ['required', 'min:2']);

In the above example, we would get the error The answer field is required.

If we pass an associative array - instead - the key of the array is used as the field name:

text('What is your name', validate: ['name' => 'required|min:2']);
// or
text('What is your name', validate: ['name' => ['required', 'min:2']]);

In the above example, we would get the error The name field is required.

This allows us to have full control over the output by customising the error messages or the attributes, without having to introduce aliases in Prompts.

This PR has been updated with this logic, please let me know your thoughts :)

@driesvints
Copy link
Member

Please note that draft PR's aren't reviewed. Tests seem to fail here as well.

@cerbero90
Copy link
Contributor Author

Thanks @driesvints. As per description, this PR is in draft because it depends on the code of this Laravel Prompts PR.

Once a new version of Laravel Prompts is tagged including this merged PR, I'll make sure to require the new version in this PR. That will fix the tests and I'll then set this PR as ready for review 👍

@driesvints
Copy link
Member

Sorry missed that 👍

@cerbero90
Copy link
Contributor Author

This PR is now ready for review 👍
Here is a breakdown of how this feature works:

// we can pass a callable to `validate` as we were doing before (non-breaking)
$name = text('What is your name?', validate: fn ($value) => $value == '' ? 'Required!' : null);

// we can pass Laravel validation rules to `validate` and get a validation error like `The answer field is required.`
$name = text('What is your name?', validate: 'required');

// we can pass an associative array to `validate` and get a custom validation error like `The name field is required.`
$name = text('What is your name?', validate: ['name' => 'required']);

// we can also define the methods messages() and attributes() in our Command for a total control over the console output
protected function messages()
{
    return ['name.required' => 'Your :attribute is mandatory.'];
}

protected function attributes()
{
    return ['name' => 'full name'];
}

// the above will print `Your full name is mandatory.`

@cerbero90 cerbero90 marked this pull request as ready for review January 10, 2024 01:03
@jessarcher jessarcher self-requested a review January 10, 2024 01:50
Copy link
Member

@jessarcher jessarcher left a comment

Choose a reason for hiding this comment

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

I've tested this locally and it works great!

src/Illuminate/Console/Concerns/ConfiguresPrompts.php Outdated Show resolved Hide resolved
@driesvints driesvints changed the base branch from 10.x to master January 12, 2024 15:13
@driesvints driesvints changed the title [10.x] Define global validation logic for Laravel Prompts [11.x] Define global validation logic for Laravel Prompts Jan 12, 2024
@taylorotwell taylorotwell merged commit 4025748 into laravel:master Jan 12, 2024
27 of 28 checks passed
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.

5 participants