POST-Params not accessible in Symfony Controller when forward is used? - symfony

I use the forward-method to forward requests to another Controller action:
$response = $this->forward($menuItemConfig['controller'] . ':' . $actionParams['action'], [
'request' => $request,
]);
This is the action of the Controller - post params are empty.
public function delete(Request $request): Response
{
if ($request->isMethod('POST') == false) {
throw new AccessDeniedException('Only POST allowed for this action.');
}
$postParams = $request->request->all();
dump($postParams);
die;
}
Passing parameters to the action does not work. All not-DI-params of the action are generally empty.
Symfony version 5.2.3

I have noticed that you are missing :, try this:
$response = $this->forward($menuItemConfig['controller'] . '::' . $actionParams['action'], [
'request' => $request,]);

Related

In Symfony how do I redirect to route with datas from search form ? Error : Variable does not exist

I made a search form in order to get events list. This form is displayed in front/search.html.twig. When I submit the search form, I'd like it leads me to front/events.html.twig.
When I submitted it, it says "category" doesn't exist. I don't have this problem when I replaced
return $this->redirectToRoute('events', $data);
with
return $this->render('front/events.html.twig', $data);
but I wish to use to route "events"...
This is my EventsController.php file :
<?php
namespace App\Controller\Front;
use App\Form\SearchType;
use App\Repository\EventsRepository;
use App\Repository\CategoriesRepository;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class EventsController extends AbstractController
{
#[Route('/search', name: 'search')]
public function search(Request $request, SessionInterface $sessionInterface)
{
$data = $request->request->all();
$sessionSearchFormData = $sessionInterface->get('searchFormData');
$form = $this->createForm(SearchType::class, ['data' => $sessionSearchFormData]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$sessionInterface->set('searchFormData', $data);
return $this->redirectToRoute('events', $data);
}
return $this->renderForm('front/search.html.twig', [
'form' => $form
]);
}
#[Route('/events', name: 'events')]
public function events(
EventsRepository $eventsRepository,
CategoriesRepository $categoriesRepository
){
$events = $eventsRepository->findAll();
$categories = $categoriesRepository->findAll();
return $this->render("front/events.html.twig", ['events' => $events, 'categories' => $categories]);
}
}
Bonjour Emilie,
Your route events does not have parameters. So you can't redirect it using parameters.
you can try something like this :
public function index($name)
{
return $this->redirectToRoute('events', ['max' => 10]);
}
You can forward to another Controller :
public function index($name)
{
$response = $this->forward('App\Controller\OtherController::fancy', [
'name' => $name,
'color' => 'green',
]);
// ... further modify the response or return it directly
return $response;
}
Regards,
hous has found the solution :
The second parameter must be an array :
return $this->redirectToRoute('events', [$data]);

Test roles access to controllers in symfony

I'm asking myself how to tests with phpunit in symfony roles access.
For example, if i have an indexAction and 5 different roles in my security config, i want to be sure that user A will have a 401, user B a 403, user C a 500...
But it cause an issue: tests are really long to execute, because we have 5 functional tests by action.
Now, i'm doing that kind of thing:
/**
* #covers \App\Bundle\FrontBundle\Controller\DefaultController::indexAction()
*
* #dataProvider rolesAllAccess
*
* #param string $user
* #param integer $expectedCode
*
* #return void
*/
public function testRolesIndexAction($user, $expectedCode)
{
$client = $this->createClientWith($user);
$client->request('GET', '/');
$this->assertEquals($expectedCode, $client->getResponse()->getStatusCode());
}
The function createClientWith authenticate a client that i have defined in my dataProvider before. It makes exactly what i described before.
Do you have any idea on how doing that better or - at least - with better performances ?
Thanks!
Depends on your authentication method. I use JWT. Also, all my web tests extends ApiTestCase that extends WebTestCase. And In all WebTestCases I use a logged user. Logged use log in inside the setup method.
abstract class ApiTestCase extends WebTestCase
{
protected function setUp()
{
$client = static::makeClient();
$client->request(
'POST',
'/tokens', [
'username' => 'username',
'password' => 'password'
], [
// no files here
],
$headers = [
'HTTP_CONTENT_TYPE' => 'application/x-www-form-urlencoded',
'HTTP_ACCEPT' => 'application/json',
]
);
$response = $client->getResponse();
$data = json_decode($response->getContent(), true);
$this->client = static::createClient(
array(),
array(
'HTTP_Authorization' => sprintf('%s %s', 'Bearer', $data['token']),
'HTTP_CONTENT_TYPE' => 'application/json',
'HTTP_ACCEPT' => 'application/json',
)
);
}
}
And here an example of test:
class DivisionControllerTest extends ApiTestCase
{
public function testList()
{
$this->client->request('GET', '/resource');
$response = $this->client->getResponse();
$expectedContent = ' !!! put expected content here !!! ';
$this->assertEquals(
$expectedContent,
$response->getContent()
);
}
}
Your test could be
public function testRolesIndexAction($expectedCode)
{
$this->client->request('GET', '/');
$this->assertEquals($expectedCode, $this->client->getResponse()->getStatusCode());
}
Try to use this to call one time $this->createClientWith. I suggest to look here for more recommandation.

Why won't my kernel.response event listener modify my response?

I don't find the reason why my subsequent kernel.response event listener won't modify my response here. Do you encountered this problem too before, or is there a misprint into the lines ?
Context: users will have a 10-items visit history attached to them, under Symfony3.
public function onResponse(FilterResponseEvent $event)
{
$request = $event->getRequest();
if(!$event->isMasterRequest() || !preg_match('#^dm_.*#', $request->get('_route'))){
return;
}
$history = $request->cookies->get('history');
if(!$history)$history = "[]";
$history = json_decode($history, true);
$addon = [
'route' => $request->get('_route'),
'route_params' => $request->attributes->get('_route_params'),
'url' => $request->getRequestUri(),
'date' => new \Datetime
];
$history[] = $addon;
$history = array_slice(
$history,
-10
);
$cookie = new Cookie('history', json_encode($history), time() + 3600);
$response = $event->getResponse();
$response->headers->setCookie($cookie);
}
I added some var_dump()s, to check that event was caught (and it was). I also tested to modify headers elsewhere, and it works fine. So, just here, I don't see why it doesn't.

Silex - get right condionals in finish middleware

I want to create a pdf file out of some route-dependant data
{http://example.com/products/123/?action=update}
$app->finish(function (Request $request, Response $response) {
// Make a pdf file, only if:
// - the route is under /products/
// - the action is update
// - the subsequent ProductType form isSubmitted() and isValid()
// - the 'submit' button on the ProductType form isClicked()
});
As a normal form submission process I have:
public function update(Application $app, Request $request)
{
$form = $app['form.factory']->create(ProductType::class, $product);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if (!$form->get('submit')->isClicked()) {
return $app->redirect('somewhere');
}
$product = $form->getData();
$app['em']->persist($product);
$app['em']->flush();
return $app->redirect('product_page');
}
return $app['twig']->render('products/update.html.twig', array(
'form' => $form->createView(),
));
}
Questions:
Should I duplicate all of the conditionals in finish middleware?
How to access the Product entity in finish middleware?
Consider having multiple resource types like Products, Services, Users, ...

Symfony redirect with request

I want to redirect and send my request to another route but this method is not working.
return $this->redirect($this->generateUrl(
'admin_platform_create',
array('request' => $request)
));
When I arrive into admin_platform_create it doesn't pass that if
public function createAction(Request $request)
{
if ($request->getMethod() == 'POST')
{
Though this is working,
return $this->forward('AdminPlatformBundle:Manage:edit',
array('request' => $request));
It is not what I need as it is not writing the new URL.
Thanks for your help!
If you are using Symfony 2.6 or later, you can do it:
return $this->redirectToRoute('route', [
'request' => $request
], 307);

Resources