acorn icon indicating copy to clipboard operation
acorn copied to clipboard

Help with PR approach for component validation

Open eavonius opened this issue 11 months ago • 7 comments

Summary

Background: I wanted to use laravel validation in blade components within an acorn project (a sage 10 theme to be specific). I read a bunch of the acorn and laravel 9 source and got it working. However, I'm not sure the best way to contribute this back to acorn, since it looks like people were working on validation already and I don't want to disrupt that if my approach conflicts at all. So I'm Looking for some help with how I should approach potentially contributing this, or helping validation move along!

First I found the file src/Illuminate/Foundation/Validation/ValidationRequests.php in the acorn source. This is a PHP trait that can be added to classes in an acorn project that are instantiated with access to the dependency injection container. Composers and Components in a sage 10 theme fit this bill.

Next I added this trait by importing it into a Component class with use Illuminate\Foundation\Validation\ValidatesRequests then adding a call to use ValidatesRequests; before the constructor of the class.

Finally I added some code to the constructor of the component class to test it:

public function __construct(Request $request) {

  if ($request->isMethod('post')) {

    try {
      $this->validate($request, [
        'name' => 'required|min:2'
      ]);
    } catch (\Exception $e) {
      error_log("JSON message dump of validation errors: " . $e->validator->messages());
    }
  }
}

When I submit a form on the component that POSTs an input field named "name", and set that field to 1 character long before posting (so the validation fails), the validation exception is thrown but the JSON representation of the message just had the path within an expected localization file to get the actual message to display. E.g:

{"name":["validation.min.string"]}

After a bunch of digging around, I found this post on StackOverflow that showed in the more recent versions of laravel, the trans() function must be passed to the constructor of the ValidationFactory when it is instantiated. Additionally, the validation.php file from laravel must be present at the default path (relative to your theme/project directory) of ./lang/en/validation.php.

So I first copied the latest commit from laravel's source for version 9.x of validation.php to that path in my project.

Next I found that on line 98 of acorn's ValidationRequest.php trait file is where the ValidationFactory is retrieved from the container. I just added a second parameter to the app function, to pass the result of the trans function as described in the StackOverflow post (since this seemed to take additional parameters to pass to the constructor):

return app(Factory::class, [trans()]);

After submitting the form. The messages come back localized!

{"name":["The category name must be at least 2 characters."]}

So it looks like that class would need to be modified in acorn. But it also seems like we would want to include instructions in acorn (and possibly update the sage 10 new project template files) to include laravel 9's default validation localization files.

Anyway, happy to answer any other questions if I'm headed in the right direction with this. If not, let me know what other approach I should be taking. Thanks!

Additional context

No response

eavonius avatar Aug 02 '23 18:08 eavonius