Symfony2 routing from POST - symfony

I'm issuing a POST body of: controller=user&action=add
To the URL: my_site.com/
I want acoording to post run addAction from UserController
class UserController extends Controller
{
public function addAction()
{
//return $this->redirectToRoute('test');
return $this->render('BeerwerdClaberonBundle:Default:index.html.twig');
}
}
How can I do this?

You can specify a route and with that route you can specify a request method.
For example:
/**
* #Route("/contact")
* #Method("GET")
*/
For more info see the documentation on routing:
http://symfony.com/doc/current/book/routing.html#adding-http-method-requirements

Related

Symfony, how to define homepage route

I created a HomeController to show my homepage
class HomeController extends AbstractController
{
#[Route('/{page?}', name: 'home')]
public function index(PostRepository $pr, EntityManagerInterface $em, $page, ): Response
{
…
}
}
So far so good. But this stops working when I create a second page because it will always be catched by the home route.
For example my security controller always get's redirected to home when called with path('app_login')
class SecurityController extends AbstractController
{
/**
* #Route("/login", name="app_login")
*/
public function login(AuthenticationUtils $authenticationUtils): Response
{
It seems like the home route is too greedy and catches almost everything.
I suggest you to create requirements for your route param. Without it your home route will match any request that start with / followed by a string.
#[Route('/{page?}', name: 'home', requirements={"page"="\d+"})]
public function index(PostRepository $pr, EntityManagerInterface $em, $page = 1): Response {
//…
}
I'm not very sure how to handle that ?, with a default value I think you don't need it anymore.
https://symfony.com/doc/current/routing.html#parameters-validation

Define global defaults for all route methods with Symfony

Is there any solution to define global defaults for all routes in a Symfony project? For example, I would like to use the GET method by default for all routes, to avoid routes matching ANY method if I forgot to use methods={…} in one of them.
A less expensive alternative to define all routes with the GET method is to add it to the controller. Now all routes within this controller only allow GET calls unless another one is specified:
/**
* #Method({"GET"})
*/
class MyController extends Controller
{
public function indexAction(Request $request)
{
// only allows GET
}
/**
* #Method({"GET", "POST"})
*/
public function editAction(Request $request)
{
// allows GET and POST
}
}

Symfony 3 - replace string after render view (annotation)

I need replace string in view after rendered.
My all controllere use annotaion #Template("path").
My controller:
...
class AboutController extends Controller
{
/**
* #Route("/about-us", name="about")
* #Method("GET")
* #Template("#AppBundle/Resources/views/About/index.html.twig")
*/
public function indexAction()
{
}
}
...
I know to do it without annotaion:
...
class AboutController extends Controller
{
/**
* #Route("/about-us", name="about")
* #Method("GET")
*/
public function indexAction()
{
$content = $this->renderView('AppBundle/Resources/views/About/index.html.twig', []);
$content = str_replace('my text', 'my new text', $content);
return new Response($content);
}
}
...
How I can do it with annotaion (#template)?
I think you should use Symfony's Event system onKernelResponse
This will allow you to grab the response after controller action return it and modify the response before sending it.
To subscribe an event follow Syfmony's doc example.
You did not tell us which version of Symfony you are using, those links are 3.4.
Hope this helps.

Set requirements for get request parameters in symfony's controller

I have a controller which handles a GET request. I need to set requirement parameters for GET request, e.g.: 'http://localhost/site/main?id=10&sort=asc
My controller class
class IndexController extends Controller {
` /**
* #Route
* (
* "/site/main",
* name="main"
* )
*
* #Method("GET")
*/
public function mainAction(Request $request)
{
return new Response('', 200);
}
}
How could I do that?
UPD: I need to set requirement for URL parameters like
id: "\d+",
sort: "\w+"
Etc.
The same as symfony allows to do with POST request.
You can specify the requirements in the "#Route" annotation like this:
class IndexController extends Controller {
` /**
* #Route
* (
* "/site/main",
* name="main",
* requirements={
* "id": "\d+",
* "sort": "\w+"
* })
* )
*
* #Method("GET")
*/
public function mainAction(Request $request)
{
return new Response('', 200);
}
}
#Method is what you need http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/routing.html#route-method
If you try to use this route with POST, you will have 404
I couldn't understand your question well.
However, if what you need is to set up a filter mechanism for the GET method parameters as it is already available for the URL using route requirements, I think there is no ready to use tools for this in the Route component, as commented #Yoshi.
I had to do this kind of work myself and used this. I hope it helps you too
public function indexAction(Request $request)
{
// Parameter names used in the current request
$current_request_params=array_keys($request->query->all());
// $ALLOWED_INDEX_PARAMS should be declared as Class static property array and hold names of the query parameters you want to allow for this method/action
$unallowed_request_params=array_diff($current_request_params,PersonController::$ALLOWED_INDEX_PARAMS);
if (!empty($unallowed_request_params))
{
$result=array("error"=>sprintf("Unknown parameters: %s. PLease check the API documentation for more details.",implode($unallowed_request_params,", ")));
$jsonRsp=$this->get("serializer")->serialize($result,"json");
return new Response($jsonRsp,Response::HTTP_BAD_REQUEST,array("Content-Type"=>"application/json"));
}
// We are sure all parameters are correct, process the query job ..
}

Lookup route in symfony 2

I've defined a route in my app routing file:
RouteName:
pattern: /some/route
defaults: { _controller: MyAppBundle:Controller:action }
In a controller I can use:
$this->get('router')->generate('RouteName');
How would I simply access that from a fresh class I create, for example a view class that doesn't extend anything:
namespace My\AppBundle\View;
class ViewClass {
public function uri()
{
return getTheRoute('RouteName');
}
}
You need to inject "router" service into your ViewClass. Eg. in place where your define your ViewClass service:
viewclass.service:
class: Namespace\For\ViewClass
arguments:
router: "#router"
and then in your constructor:
public function __construct(\Symfony\Bundle\FrameworkBundle\Routing\Router $router)
{
$this->router = $router;
}
The clue is in how the $this->generateUrl() method works in Controllers. See:
/**
* Generates a URL from the given parameters.
*
* #param string $route The name of the route
* #param mixed $parameters An array of parameters
* #param Boolean $absolute Whether to generate an absolute URL
*
* #return string The generated URL
*/
public function generateUrl($route, $parameters = array(), $absolute = false)
{
return $this->container->get('router')->generate($route, $parameters, $absolute);
}
So you'll need to define your class as a service and inject the #router service. Either that or have your class implement ContainerAwareInterface, but the first method would definitely be better.
You should register your class as a service and insert the router as a dependency.
See the chapter on the service container in the excellent symfony2 docs.
If you're not familiar with the concepts of the service container and dependency injection, you might feel a bit overwhelmed. However, try your best to understand it because it is a essential part of the symfony2 architecture.
You could pass the entire container from your controller to your view class on instantiation. This is NOT BEST PRACTICE and not recommended.
class View
{
protected $container;
public function __construct(\Symfony\Component\DependencyInjection\Container $container)
{
$this->container = $container;
}
}
Then in your code you could use
$this->container->get('router')->generate($route, $parameters, $absolute);

Resources