find out information about called controller from app.php in Symfony2 - symfony

I am looking through properties of $kernel, $loader, $request and $response but cannot find anything related to controller and action that were actually called as a result of accessing specific URL. Is there a way to find out this info inside app.php, without manual analysis of route configuration files?

Related

Symfony 2.8 how to get Route option

With EventListener I use my lass TransactionListener. This class check permission for current url. Some URL are open. I check it by attribut "option" in routing.yml
For getting option on current route I use very slow method
$route = $this->router->getRouteCollection()->get($e->getRequest()->attributes->get('_route'));
Do I have other opportunity to get option-datafrom current route? How to get fully route-object from current route name or request?

Symfony redirect to dynamic route name

I'm using the Symfony CMF Routing Bundle to create dynamic routes (I'm using one example here):
$route = new Route('/dynamic-url');
$route->setMethods("GET");
$route->setDefault('_controller', 'AppBundle:MyRoute:getResponse');
$routeCollection->add('my-dynamic-route', $route);
The response is loaded from the getResponseAction() function inside the MyRouteController:
/**
* No annotations here, because I want the url to be dynamic from the database
*/
public function getResponseAction(Request $request) {
return $this->render('dynamic-page-template.html.twig');
}
When I go to '/dynamic-url', it works.
When in another controller, I want to redirect to this dynamic route, like this:
return $this->redirectToRoute('my-dynamic-route');
But I get this error: "None of the chained routers were able to generate route: Route 'my-dynamic-route' not found"
Also interesting: when I go to '/dynamic-url', the dev bar actually says that the Route name is 'my-dynamic-route'.
Edit
When I load all the routes, I don't see my dynamic route names:
$this->get('router')->getRouteCollection();
I think they should be in this list.
Since it's a dynamic route, which wasn't saved anywhere (like routing.yml ) it will be only availabe for Request where it has been defined. So at the end of Request your app will immediately "forget" about new Route generated at runtime.
When I load all the routes, I don't see my dynamic route names:
$this->get('router')->getRouteCollection();
I think they should be in this list.
Actualy No. It depends on where you call $this->get('router')->getRouteCollection();
Just try to call
dump($this->get('router')->getRouteCollection();)
right before the return statement in your Action where you're adding the my-dynamic-route route. I'm sure you'll see your my-dynamic-route in the list of routes, but if you call it anywhere else - you won't see it.
It's less about symfony rather about stateless nature of web (see Why say that HTTP is a stateless protocol?)
I started to think about this and pointed your question to an routing issue on symfony-cmf. You tagged with #symfony-cmf and i think this would be important feature for us.
I also think, when you persist your route with /my-route you should also ask the router for that name (or in case of the CMF with an content object with that a route.)
If you use the CmfRoutingBundle dynamic router, you should persist your routes to doctrine. The idea of dynamic here is that they can be created at runtime, e.g. in an admin interface or elsewhere by code. The DynamicRouter loads routes from the database.
If you use PHPCR-ODM, the route name is the repository id, typically something like /cms/routes/my-route and you can generate it with that name. If you have access to the route object loaded from the database, you can also generate from that, rather than the path. If you have to hardcode a path in your application, its an indication that probably a normally configured route would be better.
If you just add a route to the route collection on the fly, you would have to make sure that happens in each request, its only available when you add it. With the CMF ChainRouter you could register your own router that does that, but i would not know of a good use case for that. Either you know the route, then you can configure it in the routing.xml|yml|php config file. Or routes are loaded dynamically, in which point you should use DynamicRouter, potentially with a custom route loader.

Symfony2: How to get Authentication Listener config values into another service?

I'm working on creating an authentication provider for Symfony 2 that allows users to authenticate with the single sign on protocol called CAS.
My Authentication Listener extends from AbstractAuthenticationListener. One of the config params is check_path, which is the path/route that triggers the authentication listener to authenticate the request.
I need check_path when I construct the URL to the CAS server (so CAS server knows where to return the user to), which is easy, since my custom Entry Point class is passed the configuration array when it's constructed in my security Factory.
The hard part is that I also need check_path outside of the listener, like during authentication inside my Authentication Provider class. I need it because when CAS server sends the user back to the app, it passes a "ticket" parameter that must be validated. To validate it, I send a curl request to CAS server that must contain the ticket as well as the original check_path that was used.
As a wrote this, I realized that I could get the current URL of the page request when I'm inside the Authentication Provider (since it's check_path that triggers it anyway), but that seems off, and I'd rather get the config value directly to re-construct the service URL. It also doesn't help me when I want to use check_path elsewhere, like when constructing a logout URL to the CAS server which also required the check_path.
EDIT: The createAuthProvider method of AbstractFactory is passed both the config and the container, but I cannot modify any of my services in here because they are not yet part of the container. Perhaps if I had a way to add a compiler pass after my services are loaded and somehow having access to the listener config?
Can you pass check_path as parameter to your listener?
If it defined in your config or parameters file you can pass it to your listener like this:
your_authentication_listener:
class: YourBundle\Listener\AuthenticationListener
arguments: ['%check_path%']
tags:
...
(If I understood you correct.)
You can make %check_path%(or a namespaced version of it) a 'normal' parameter:
Inside of DependencyInjection, there are (by default) two classes responsible for defining and loading your bundle's configuration. In there you can also inject your configuration into your service container.
DependencyInjection\Configuration is where you define which configurations are available in your bundle, what type they should be etc.
DependencyInjection\YourBundleNameExtension is where you can load your configuration and also add them to the service container.
If you have not done anything in there yet, your Extension's load()-method should look something like this:
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader(
$container,
new FileLocator(__DIR__.'/../Resources/config')
);
$loader->load('services.yml');
}
$config holds your bundle's configuration in the form of an array, so if we imagine your YAML config file looks like this:
your_bundle_name:
check_path: foo
Your $config will look like that:
array( 'check_path' => 'foo' )
So now, all you have to do is add this configuration to the container. Inside your load()-method simply add something like:
$container->setParameter(
'my_bundle_name.check_path',
$config['check_path']
);
Inside your services.yml you can now use %my_bundle_name.check_path% like every other parameter:
my_bundle_name.security.authentication.provider:
class: MyBundleName\Security\Core\Authentication\Provider\MyAuthenticationProvider
arguments: ['%my_bundle_name.check_path%']
For more details, have a look at Symfony's documentation [1,
2]

Convention-based routing in Symfony2

I'm trying to learn learn how routing works in Symfony2, and so far everything I've read has examples like this:
blog:
path: /blog/{page}
defaults: { _controller: AcmeBlogBundle:Blog:index, page: 1 }
This routes requests to /blog/123 to the AcmeBlogBundle Blog controller's "index" action, and passes the 123 parameter as the "page" parameter to that controller action. If no page parameter is passed, then the page defaults to 1.
That's all well and good, but what if you want to simply have a convention based routing system that passes things through like this:
/{bundle}/{controller}/{action}
So, for a URL like this:
/acme/blog/index
It would then call AcmeBlogBundle Blog controller's "index" action.
No specific routing configuration is necessary, it simply infers the bundle, controller, and action from the URL. So you can continue adding bundles, controllers, and actions, and you don't need to modify the routing configuration. It just works.
If this isn't possible, can you at least infer the controller and action from the URL? E.g., perhaps you need a route that specifically identifies the bundle, but can we get the controller and action from the URL?
I read through the Symfony "The Book" page about routing, and I couldn't figure out a way to do this.
No way. This was considered as bad practice and so it was removed from symfony.
But you should take a look at the #Route annotation, as it simplifies configuring routes in such a nice way. Directly attached to the action, there is no lack between config and code.

Access to Doctrine during Bundle Initialization

I have a Symfony2 bundle which I want to use database table which stores key value configuration parameters. I want to be able to load a query and cache it for a long time and be able to inject the configuration parameters into symfony2 service container.
Right now I am injecting a service which loads the configuration from doctrine, and calling a get($key) method to retrieve the value for the key I want.
I basically want these configuration options to be available from the symfony2 service container parameter bag.
Is there maybe an event I could tie into or some sort of compiler pass I can use with my bundle to achieve this?
I'll do something like that in your service listener
public function onLateKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
$mydata= $this->manager->getRepository('YourBundle:YourTable')->getAll();
$parameters['mydata'] = $mydata;
$request->attributes->add($parameters);
}
In your Controller, you can get your parameters :
$this->container->get('request')->attributes->get('mydata');

Resources