Symfony2 / routing / use parameters as Controller or Action name - symfony

Is it possible to route to a controller/action using given parameters ?
For example :
my_custom_route:
pattern: /{controller}/{action}
defaults: { _controller: AcmeDemoBundle:[controller]:[action] }
I would like [controller] and [action] to be replaced by given route's parameters values.
I.E : http://www.somedomain.com/Content/add should call action "addAction" of controller "ContentController" in bundle "AcmeDemoBundle"

Yes you can do so however it is not recommended. What would you do in future of you had to refactor your code and your controller / action had to change? You may break links and functionality along with possibly losing search engine optimization that may have been done for that particular route.

Related

Is there a way to check controller parameters before the controller method?

My controller code has more lines to validate the received parameters than the real function code and I was wondering if there is a way to do this validations outside the controller method.
I have checked the Symfony docs but I could not found anything. I was thinking in something like a listener but just for that method.
Thank you guys.
EDIT: I'm aware about route requirements. I'm looking for a place to inject my own code.
EDIT: Added a little snippet.
public function searchAddressAction($radius, $page){
if ($radius < 5 || $radius > 50) {
throw $this->createNotFoundException('Radius not valid');
}
if ($page <= 0) {
throw $this->createNotFoundException('Page not found');
}
EDIT 3: This seems to be the way but I can't make it work (thanks to #dlondero):
search_address:
path: /{address}/{radius}/{page}
defaults:
_controller: AppBundle:Default:searchAddress
radius: 20
page: 1
options:
expose: true
requirements:
radius: \d+
page: \d+
condition: 'request.get("radius") == 50 '
Besides the default route requirements, there are 2 options to do some extra checks if a request should be passed through to a Controller.
Create a custom route loader.
http://symfony.com/doc/current/routing/custom_route_loader.html
This can be very useful if you want to get route requirements from the database for example.
Conditions (Might be what you're looking for)
https://symfony.com/doc/current/routing/conditions.html
This is using the expression language https://symfony.com/doc/current/components/expression_language/syntax.html
I don't think you can use the parameters name in here, but you can access the query in the request, which would for sure meet the requirements of the path.
If both of these are not working, than the validation has to be done in the Controller.
You can of course create a class to do the validation, and in your controller you use that class so you only have to call 1 method to do the validation.
I don't recommend a listener for this, as it would be called for all requests, and then has to do a check if it should do the validation.
Besides that it's performance wise not preferable, it doesn't make sense to do this kind of validation in a listener, so if someone else would work on your code, he has to dig in weird places to find out why a controller returns a 404, but still matches the route.
You probably are looking for kernel.request event. Then you could have your listener/subscriber and check what you need to check.

Redirecting in symfony

I'm trying to understand if there is any difference between these two ways to do a redirection in symfony.
1 Via config without custom controller
As explained here.
# app/config/routing.yml
# ...
codes:
path: /codes # redirect /codes to /code
defaults:
_controller: FrameworkBundle:Redirect:urlRedirect
path: /code
permanent: true
2 Via redirect() method in a custom controller
As explained here.
class RedirectsController extends Controller {
/**
* #Route("/codes")
*/
public function codesAction() {
return $this->redirect('/code', 301); // redirect /codes to /code
}
}
When I talk about differences I mean things like performance, ease of use and maintainability.
Thanks.
In the first case you don't need to create a controller. You can manage everything from the configuration, and this is a convenience.
The redirect will be made by RedirectController. In terms of performance there is no difference between the two methods.
If what you have to do is redirect then go with the first method.
The thing is your first solution will redirect without using a specific controller, using only configuration, whereas your second solution will do your action and then redirect. These are two different use cases and they are not the same.

Dynamic action for route in Symfony 2.x (part of the url)

Is it possible to define a route in Symfony 2.x that dynamically resolves the action based on part of the route ?
Example :
rest_localite:
path: /rest/localite/{_action}
defaults: { _controller: ApplicationLocaliteBundle:Rest:{_action}, _format: json }
Thank you very much
This was considered bad practice as it exposes internal parts of the application and last I heard they removed it.
If you are doing this to save time you might want to look at the #Route annotations for actions, it is less of a pain.
But if you really cannot do without dynamic actions calls and do not mind the risk you could try passing the action's name as a parameter to a single controller method that then calls the appropriate method.

Symfony2 impersonation route parameters missing

I receive an error when I change pages if I am impersonated as another user in Symfony2. It only happens when the route has additional parameters. There is no sign of route generation at the pointed line number.
Controller action
/**
* #Route("/member/{id}", name="member_page")
* #Template()
*/
public function memberAction($id)
Error
An exception has been thrown during the rendering of a template ("Some mandatory parameters are missing ("slug") to generate a URL for route "member_page".") in members.html.twig at line 2.
Do you have two routes with the same name?
Watch your routing.yml file or the class annotation, maybe you have defined a prefix with slug parameter.
If the "slug" parameters is not necessary, provide a default for that as NULL. Here is an example
message_edit:
pattern: /edit/{slug}
defaults: { _controller: CommunicationBundle:Default:edit, slug: null }
Thanks for the answers, but there was something else going on:
The template was extending another template in which the bug could be found. Therefor an incorrect linenumber was displayed in the eror message. After setting up a smaller test environment I could replicate the problem. It was an anchor to exit impersonation which I wanted to redirect to the current page, but was obviously missing the parameters of the current page:
Stop impersonation
I fixed it for now by just using the named 'home' route.

How to pass arguments to controller from route in Symfony2

I'm working on a Symfony2 project and am trying to figure out how to pass parameters from the route configuration to the controller. I know I can configure default values in the route configuration, and retrieve the values in the controller using the appropriate var name in the function declaration, but that isn't exactly what I want.
My use case is the following. I have a standard method in my controller that I want to access from 2 or 3 different routes. Depending on which route is being called, I want to "configure" the method differently. I can accomplish this in a few ways:
In my controller, check the route name using `$this->container->get("request")->get("_route"), but that is ugly, and then I am hardcoded to the route name. Moves configuration to the controller, which should just be logic - not configuration.
Create a base controller class, and subclass each method for my different routes. Each subclassed method would then have the necessary configuration within the method. Cleaner soln than #1, but still "heavy" in the sense of having multiple classes for a simple need and still pushes configuration data into the business logic.
Put configuration data into the route configuration. In the controller, access the configuration data as required. Ideal solution, but don't know how.
I can use the route default array to specify my arguments, but then must make sure to use a regex to ensure that the params are not overridden at the URL level (security risk). This is functional, but still kinda cludgy and not a pretty hack.
I presume that there must a better way to do this, but I can't seem to figure it out. Is there a way to access the routing object from the controller, and access the different configuration parameters?
You can pull the actual route from the router service. Something like:
$routeName = $this->container->get("request")->get("_route");
$router = $this->container->get("router");
$route = $router->getRouteCollection()->get($routeName);
Not sure if this would be such a great design though. Consider passing a $configName to your controller method, adding a parameter with the same name in a config file then using getParameter to access it. That would eliminate the route stuff from the equation.
Something like:
zayso_arbiter_import:
pattern: /import
defaults: { _controller: ZaysoArbiterBundle:Import:index, configName: 'someConfigName' }
public function importAction(Request $request, $configName)

Resources