Boolean_Type
Boolean_Type

Reputation: 1274

Symfony 6: create action route with dynamic parts

I have a controller action in my project based on Symfony 6.3:

#[Route('/test')]
class TestController extends AbstractController
{
    #[Route('/events/page/{page<\d+>?1}/itemsPerPage/{itemsPerPage<\d+>?10}', name: 'get_events')]
    public function getEvents(PaginatorInterface $paginator, int $page = 1, int $itemsPerPage = 10)
    {
    // ...
    }
}

This action uses KnpPaginatorBundle to paginate found events, that's why I need page and itemsPerPage parameters. Everything works fine, when I call my action this way:

http://127.0.0.1:8080/test/events/page/1/itemsPerPage/7

What I want is to make /page/ and /itemsPerPage/ URL parts dynamic too. What I mean:

I realize, that it could be easier to refuse "static" parts usage and do this:

#[Route('/events/{page<\d+>?1}/{itemsPerPage<\d+>?10}', name: 'get_events')]

But I plan to add much more GET parameters in future, so I wouldn't like my URL to finally look like http://127.0.0.1:8080/test/events/1/7/100/8648/78978/... (unless this is the only possible solution).

Also I could try to do something like this to cover all possible cases:

#[Route('/events/page/{page<\d+>?1}/itemsPerPage/{itemsPerPage<\d+>?10}')]
#[Route('/events/itemsPerPage/{itemsPerPage<\d+>?10}/page/{page<\d+>?1}')]
#[Route('/events/itemsPerPage/{itemsPerPage<\d+>?10}')]
#[Route('/events/page/{page<\d+>?1}')]

But as I said above, additional GET parameter will occur later, so such combinations isn't an option because of a huge number of possible cases.

Does Symfony provide a possibility to handle such situation?

Upvotes: 3

Views: 186

Answers (1)

pok_net
pok_net

Reputation: 419

At the Route I would only add variables that the page cannot work without. For example if a page lists user events, then I would add user_id at the Route. Everything else you can get from knp_paginator configuration yaml or get or session and handle them in the controller.

In your current case I would use $_GET to store page and itemsPerPage in session variables and then access them from the session, validate them and then pass them like this:

    $pagination = $paginator->paginate(
        $queryBuilder, /* query NOT result */
        $page,
        $itemsPerPage
    );

This way you can have a clean url and the flexibility to add more parameters in the future.

Upvotes: 0

Related Questions