Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 routing to controllers using querystring parameters

I am currently living in Bizzaro World with one client.

Because the symfony application we are writing has the response injected into a page in another applciation we are forced to only have a single URL for the application, but luckily we do get the querystring passed to us intact.

As such, I need to do the exact opposite of how symfony does things, a kind of old school MVC approach. I need the routing to work via querystring parameters, routing to the correct controller and rendering the correct response, and not use the standard, and sane, path approach.

So the urls would be http://www.bizzaro.com/appname?route=%2fblog and not http://www.bizzaro.com/appname/blog, and so forth.

There are good examples in the routing section on how to ensure querystrings are passed as parameters to controller actions, but not for this rather regressive approach.

Where do I even start?

I implemented the solution 2 proposed by Corentin Dandoy below, but modified slightly to prevent a loop when looking up the root.

namespace AppBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class FrontControllerControllerController extends Controller
{
    /**
     * Forward the request to the appropriate controller
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function indexAction(Request $request)
    {
        // get the parameter that specifies the route to the 'real' homepage controller
        $homeroute = $this->container->getParameter('homeroute');
        $route = $request->query->get('route');

        // Convert the query-string route into a valid path route
        $path = '/'.$route;

        // if it is the route, then use the 'real' homepage controller, otherwise you end up in a routing loop!
        if ($path === '/')
        {
            $match = $this->get('router')->match('/' . $homeroute);
        } else {
            try {
                $match = $this->get('router')->match($path);
            } catch (ResourceNotFoundException $e) {

                throw $this->createNotFoundException('The route does not exist');
            }
        }

        $params = array(
            'request' => $request,
        );

        return $this->forward($match['_controller'], $params);
    }

}
like image 976
graney Avatar asked Sep 27 '22 10:09

graney


1 Answers

SOLUTION 1

One simple solution (not scalable though) is this :

namespace AppBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class MainController
{
    /**
     * @Route("/app", name="bizarro_app")
     */
    public function mainAction(Request $request)
    {
        $route = $request->query->get('route');

        switch ($route) {
            case 'blog':
                return $this->blogAction($request);
            default:
                throw $this->createNotFoundException('The route does not exist');
        }
    }

    protected function blogAction(Request $request)
    {
        // Your blog page here
        return new Response('...');
    }
}

SOLUTION 2

If you don't mind having the two kinds of routes available, you could try this :

namespace AppBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class MainController
{
    /**
     * @Route("/app", name="bizarro_app")
     */
    public function mainAction(Request $request)
    {
        $route = $request->query->get('route');

        // Convert the query-string route into a valid path
        $path = '/'.$route;

        try {
            $match = $this->get('router')->match($path);
        } catch (ResourceNotFoundException $e) {
            throw $this->createNotFoundException('The route does not exist');
        }

        $params = array(
            'request' => $request,
        );

        return $this->forward($match['_controller'], $params);
    }

    /**
    * @Route("/blog", name="bizarro_blog")
    */
    public function blogAction(Request $request)
    {
        // Your blog page here
        return new Response('...');
    }
}

That way, you benefit from Sf2 routing component. Be aware that I have not test it myself.

like image 99
Corentin Avatar answered Oct 18 '22 16:10

Corentin