1

I'm using laravel 5.2 and i'm using Form Request that given by laravel vendor to make my code clean, so i don't have many code on my controller :

public function store( CouponRequest $request )
{
    DB::beginTransaction();
    try {
        $coupon = Coupon::create( $request->all() );

        DB::commit();
        return redirect()->route('admin.coupons.index');
    } catch (\Exception $e) {
        DB::rollback();
        return redirect()->back()->withInput();
    }

And this is my sample code about my request form :

public function rules()
{
    switch ( strtolower( $this->method ) ) {
        case 'post':
        {
            return [
                'code' => 'required|unique:coupons,code',
                'name' => 'required',
                'start_year' => 'required',
                'start_month' => 'required',
                'start_day' => 'required',
                'start_time' => 'required',
                'finish_year' => 'required',
                'finish_month' => 'required',
                'finish_day' => 'required',
                'finish_time' => 'required',
                'using_time' => 'required',
                'type' => 'required',
                'free_shipment' => 'required',
                'target' => 'required',
                'target_user' => 'required'
            ];
        }
        case 'put':
        {
            return [
                'code' => 'required',
                'name' => 'required',
                'start_year' => 'required',
                'start_month' => 'required',
                'start_day' => 'required',
                'start_time' => 'required',
                'finish_year' => 'required',
                'finish_month' => 'required',
                'finish_day' => 'required',
                'finish_time' => 'required',
                'using_time' => 'required',
                'type' => 'required',
                'free_shipment' => 'required',
                'target' => 'required',
                'target_user' => 'required'
            ];
        }
        default:
        {
            return [];
        }
    }
}

Where should i place this command? :

$start_date = Carbon::create( $request->start_year, $request->start_month, $request->start_day );
$start_date->setTimeFromTimeString( $request->start_time );
$finish_date = Carbon::create( $request->finish_year, $request->finish_month, $request->finish_day );
$finish_date->setTimeFromTimeString( $request->finish_time );

If i place this code before validation, i could be error when some field not filled well by users.

So what i want is to place this code after validation success, but i don't want to place it at my controller.

Is there FormRequest function that can be called after validation success to modify my request??

I think it's not good when there's much code at controller, so i want to minimalize my controller code.

5
  • you can use a middleware Commented Oct 14, 2016 at 7:47
  • the work flow will like this : middleware -> form request -> controller right? so if i place my code at middleware, it will not validate Commented Oct 14, 2016 at 8:03
  • Don't do that. Middleware provide a mechanism for filtering HTTP requests entering your application. Not transforming http requests. You will end up with a confusing code base. You can write a service instead. That will also make your controller much more cleaner and SOLID. Commented Oct 14, 2016 at 8:05
  • Who is using the $start_date and $finish_date? Are you persisting it or using it? Commented Oct 14, 2016 at 8:08
  • @HilmiErdemKEREN has right, I probably misunderstood your question. You can create a service and inject it to controller. Service container will take care for the wirring Commented Oct 14, 2016 at 8:09

1 Answer 1

1

I am going to attempt this using FormRequest. If the intention here is to both validate and assign start_date and finish_date, this is probably the plausible way of doing so in Laravel:

public function rules()
{
    switch ( strtolower( $this->method ) ) {
        case 'post':
        {
            return [
                'code' => 'required|unique:coupons,code',
                'name' => 'required',
                'start_year' => 'required',
                'start_month' => 'required',
                'start_day' => 'required',
                'start_time' => 'required',
                'finish_year' => 'required',
                'finish_month' => 'required',
                'finish_day' => 'required',
                'finish_time' => 'required',
                'using_time' => 'required',
                'type' => 'required',
                'free_shipment' => 'required',
                'target' => 'required',
                'target_user' => 'required'
            ];
        }
        case 'put':
        {
            return [
                'code' => 'required',
                'name' => 'required',
                'start_year' => 'required',
                'start_month' => 'required',
                'start_day' => 'required',
                'start_time' => 'required',
                'finish_year' => 'required',
                'finish_month' => 'required',
                'finish_day' => 'required',
                'finish_time' => 'required',
                'using_time' => 'required',
                'type' => 'required',
                'free_shipment' => 'required',
                'target' => 'required',
                'target_user' => 'required'
            ];
        }
        default:
        {
            return [];
        }
    }
}

/**
 * @inheritDoc
 *
 * This method overrides Laravel's defeault FormRequest
 * to create validator with `after()` hook
 */
protected function validator($validator)
{
    $validator
        ->make(
            $this->validationData(), $this->rules(), $this->messages(), $this->attributes()
        )
        ->after(function($validator) {

            if ($date = $this->getCarbonInstanceFromPrefix('start')) {
                $request->start_date = $date;
            } else {
                $validator->errors()
                    ->add('start_year', 'Invalid starting date and time');
            }

            if ($date = $this->getCarbonInstanceFromPrefix('finish')) {
                $request->finish_year = $date;
            } else {
                $validator->errors()
                    ->add('finish_year', 'Invalid finish date and time');
            }

        });
}

/**
 * Retrieve carbon instance from current request, using prefix
 *
 * @param  string $prefix
 *
 * @return Carbon|null
 */
protected function getCarbonInstanceFromPrefix($prefix = '')
{
    try {
        $date = Carbon::create( 
            $request->get($prefix . '_year'), 
            $request->get($prefix . '_month'), 
            $request->get($prefix . '_day') 
        );
        $date->setTimeFromTimeString( $request->get($prefix . '_time') );
        return $date;
    } catch (\Exception $e) {
        return null;
    }
}

Quick Explanation

FormRequest essentially extends from Illuminate\Foundation\Http\FormRequest and can override the method where instance of Validator is created. By creating your custom validator, you can attach after() event to both validate each date inputs, and also assign additional parameter to request in one go.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.