Sirkow
Sirkow

Reputation: 63

Laravel - How to override the request class so that a script is executed whenever an http request is made to the backend?

I have managed this by extending the Form request like this:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use App\Http\Controllers\Root\RootController;
use App\Http\Controllers\Root\ConfigRootController;

class Request extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            //
        ];
    }

    /**
     * Intercept the request and make changes
     * 
     */
    protected function getValidatorInstance()
    {
        
        $data = $this->all();

        RootController::setConn($data['url']);
        $Config = ConfigRootController::get_tl_config($data['url']);

        if(isset($data['cookie'])){
            $User = ConfigRootController::getCurrentUser($data['url'],$data['cookie']);
            $GLOBALS['user']=$User;
        }
        $GLOBALS['CONFIG'] = json_decode($Config->getBody()->getContents());

        return parent::getValidatorInstance();
    }
}

However this solution has a limitation as it does not allow me to use the $request->validate() method in the controller, which is a requirement.

Given that I am using laravel as a stateless API. I need to intercept all requests made and inject the script below right before the controller so that I can access and handle the config data as needed.

$data = $this->all();

RootController::setConn($data['url']);
$Config = ConfigRootController::get_tl_config($data['url']);

if(isset($data['cookie'])){
    $User = ConfigRootController::getCurrentUser($data['url'],$data['cookie']);
    $GLOBALS['user']=$User;
}
$GLOBALS['CONFIG'] = json_decode($Config->getBody()->getContents());

Here is an attempt via extending the Request class and applying the script in a constructor like so :

namespace App\Http\Requests;

// use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http;
use App\Http\Controllers\Root\RootController;
use App\Http\Controllers\Root\ConfigRootController;

class Request extends Http\Request
{
    public function __construct()
    {
        $data = $this->all();

        RootController::setConn($data['url']);
        $Config = ConfigRootController::get_tl_config($data['url']);

        if(isset($data['cookie'])){
            $User = ConfigRootController::getCurrentUser($data['url'],$data['cookie']);
            $GLOBALS['user']= json_decode($User->getBody()->getContents());
        }
        $GLOBALS['TL_CONFIG'] = json_decode($Config->getBody()->getContents());
    }
}

This however results in a 500 internal server error from postman.

Upvotes: -1

Views: 1388

Answers (1)

Sirkow
Sirkow

Reputation: 63

As it has been pointed out, the proper way to do this is via middleware :

First :

php artisan make:middleware BeforeRequest

Then in app\Http\Middleware\BeforeRequest.php :

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use App\Http\Controllers\Root\RootController;
use App\Http\Controllers\Root\ConfigRootController;

class BeforeRequest
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {

        $request->headers->set('Accept', 'application/json'); //force the response to be json format

        $data = $request->all();

        RootController::setConn($data['url']);
        $Config = ConfigRootController::get_tl_config($data['url']);

        if(isset($data['cookie'])){
            $User = ConfigRootController::getCurrentUser($data['url'],$data['cookie']);
            $GLOBALS['user']= json_decode($User->getBody()->getContents());
        }
        $GLOBALS['TL_CONFIG'] = json_decode($Config->getBody()->getContents());

        return $next($request);
    }
}

Then in app\Http\Kernel.php :

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        \App\Http\Middleware\TrustHosts::class,
        \App\Http\Middleware\TrustProxies::class,
        \Fruitcake\Cors\HandleCors::class,
        \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        \App\Http\Middleware\BeforeRequest::class, //! add your middleware
    ];

And that is all.

Upvotes: 0

Related Questions