Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Silex passing app and request to controller classes

Tags:

silex

I want a simple way to access $app and $request in my controller classes. The document says to do this,

public function action(Application $app, Request $request) {
 // Do something.
}

but it doesn't look right to have to inject $app and $request to every method. Is there a way to include $app and $request to every controller by default, maybe using the constructor? I'd like to be able to use it as $this->app.

Thanks.

like image 723
tdbui22 Avatar asked Jul 10 '13 04:07

tdbui22


2 Answers

In the Controllers as Services part of the documentation you can see how to inject dependencies to controller classes via the constructor - in that case a repository.

like image 152
Maerlyn Avatar answered Nov 30 '22 14:11

Maerlyn


It's possible :

Create a ControllerResolver.php somewhere in your project and put this inside :

namespace MyProject;

use Silex\ControllerResolver as BaseControllerResolver;

class ControllerResolver extends BaseControllerResolver
{
    protected function instantiateController($class)
    {
        return new $class($this->app);
    }
}

Then register it in your app (before $app->run();):

$app['resolver'] = function ($app) {
    return new \MyProject\ControllerResolver($app, $app['logger']);
};

Now you can create a base controller for your app, for example :

namespace MyProject;

use Silex\Application;
use Symfony\Component\HttpFoundation\Response;

abstract class BaseController
{
    public $app;

    public function __construct(Application $app)
    {
        $this->app = $app;
    }

    public function getParam($key)
    {
        $postParams = $this->app['request_stack']->getCurrentRequest()->request->all();
        $getParams = $this->app['request_stack']->getCurrentRequest()->query->all();

        if (isset($postParams[$key])) {
            return $postParams[$key];
        } elseif (isset($getParams[$key])) {
            return $getParams[$key];
        } else {
            return null;
        }
    }

    public function render($view, array $parameters = array())
    {
        $response = new Response();
        return $response->setContent($this->app['twig']->render($view, $parameters));
    }

}

And extend it :

class HomeController extends BaseController
{
    public function indexAction()
    {
        // now you can use $this->app

        return $this->render('home.html.twig');
    }
}
like image 28
Yoann Kergall Avatar answered Nov 30 '22 16:11

Yoann Kergall