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;
}
}
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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With