In my app I've got a group of routes which need some bootstraping before dispatching.
To illustrate the situation:
There is a special routes group with prefix 'app'. All of this routes have also some params:
site.dev/app/index?age=11&else=af3fs4ta21
Without these params user shouldn't be allowed to access route. I've got it done by creating a simple route middleware.
if (!$request->exists('age') || !$request->exists('else')) {
return redirect('/');
}
Next step is to initialize a class which takes route parameters as a construct arguments. Then param "else" is being used as a argument to db calls. I need to access this class in every route from /app route group.
In order to achive that I tried setting up a serviceprovider:
public function register()
{
$this->app->singleton(Dual::class, function ($app) {
return new Dual($this->app->request->all());
});
}
Then I created a special controller extending BaseController and passing Dual class to its constructor.
class DualController extends Controller
{
public function __construct(Request $request, Dual $dual)
{
$this->middleware(\App\Http\Middleware\DualMiddleware::class);
$this->dual = $dual;
}
}
And then every single controller is extending DualController and accessing Dual class by $this->dual->method().
It is working if route params are in their place and there is already a row in a database.
The problem
This middleware is executed AFTER ServiceProvider & DualController are initializing class Dual. So, middleware is not really working. If route params are not present it is going to fail.
Moreover, in case that there is no required row in database for some reason, Dual class will not be initialized (as it depends on calls to db) and whole app will crash saying that I am trying to perform operations on null.
Desired behaviour
First check route for params presence.
Second, check if there is row in db with key from route.
Third - try to initialize Dual class and pass it to all controllers used by route group /app.
If any of the steps fail -> display proper message.
Part of dual class:
class Dual
{
protected $client = null;
public $config = [];
public function __construct($config)
{
$this->config = $config;
$this->bootstrap();
}
public function getEli()
{
$eli = Eli::where(['else' => $this->config['else']])->first();
return $eli;
}
public function instantiateClient()
{
$client = Client::factory(Client::ADAPTER_OAUTH, [
'entrypoint' => $this->getEli()->eli_url,
'client_id' => '111',
'client_secret' => '111',
]);
$client->setAccessToken($this->getEli()->accessToken()->first()->access_token);
return $client;
}
public function getClient()
{
if ($this->client === null)
{
throw new \Exception('Client is NOT instantiated');
}
return $this->client;
}
public function bootstrap()
{
$this->client = $this->instantiateClient();
}