Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hooks in Laravel 5?

I'm creating a package and want hook functionality (the package should inject some extra validation rules when a user updates a field in my app).

I managed to do this using the event system. What I do is pass the $rules variable and $request into the listener, I modify the $rules variable and return it.

Would this be bad practice? What would be the recommended way of doing it?

I mean, it works. I'm just unsure if this is the best way to go about it.

Code below:

SettingsController.php (this is under App/ and where I'm validating on update)

public function update(Setting $setting, Request $request)
{
    $rules = [
        'package' => 'required|in:'.implode(config('app.packages'),','),
        'name' => 'required|max:255|alpha_dash|not_contains:-|unique:auth_setting,name,'.$setting->id.',id,package,'.$setting->package,
        'description' => '',
    ];

    // Is this bad??
    $rules = Event::fire(new SettingsWereSubmitted($request,$rules))[0];

    $v = Validator::make($request->all(),$rules);

Then in my package (packages/exchange/src/Listeners) I got this listener (ValidateSettings.php):

public function handle(SettingsWereSubmitted $event)
{
    if($event->request->package == 'exchange')
    {
        // Add rules

        $rules = [
            'fee' => 'required|decimal|min_amount:0|max_amount:1|max_decimal:8',
             'freeze_trade' => 'required|in:1,0',
        ];

        $event->rules['value'] = $rules[$event->request->name];

        return $event->rules;
    }

}
like image 866
Warz Avatar asked Nov 09 '22 17:11

Warz


1 Answers

I'm looking at this piece of your code

 if($event->request->package == 'exchange')

and think that you can achieve the same behaviour easier by using required_if validation rule.

$rules = [
        'package' => 'required|in:'.implode(config('app.packages'),','),
        'name' => 'required|max:255|alpha_dash|not_contains:-|unique:auth_setting,name,'.$setting->id.',id,package,'.$setting->package,
        'description' => '',
        'fee' => 'required_if:package,exchange|decimal|min_amount:0|max_amount:1|max_decimal:8',
        'freeze_trade' => 'required_if:package,exchange|in:1,0',
    ];

ADDED: By the way, I would suggest using Request classes to validate income requests and remove validation code from controllers because validation of request is responsibility of Request but not Controller. It's pretty easy in Laravel. First, you create your request class in your Http\Requests folder:

class UpdateSomethingRequest extends Requst
{

    public function rules()
    {
      return [
        'package' => 'required|in:'.implode(config('app.packages'),','),
        'name' => 'required|max:255|alpha_dash|not_contains:-|unique:auth_setting,name,'.$setting->id.',id,package,'.$setting->package,
        'description' => '',
        'fee' => 'required_if:package,exchange|decimal|min_amount:0|max_amount:1|max_decimal:8',
        'freeze_trade' => 'required_if:package,exchange|in:1,0',
      ];
    }

}

And then just remove that code from you Controller and type-hint new request class to update method like following:

public function update(Setting $setting, UpdateSomethingRequest $request)
{
// Your request is already validated here so no need to do validation again
}
like image 56
Andrey Degtyaruk Avatar answered Nov 14 '22 21:11

Andrey Degtyaruk