URL Rewriting from .htaccess with Symfony Routing

Viewed 1690

I have some trouble RewritingUrl with Symfony (2.8) My objective is to redirect some URL without having them changing in the browser bar.

I need this so the URL may have a custom, human-readable form, and being shareable.

The URL is also used in a Form thus why the data are sent in the ?param=data shape

Homewever, Symfony internal routing seems to not quite work with it ( or maybe have I overlooked some stuff but I've seeking up and down all day for this without finding the right answer )

Without the framework, in a .htaccess If a user went to

www.website.com/search/London/15

I would redirect them to

www.website.com/searchEngine?search_action[city]=London&search_action[radius]=15

Without changing the browser URL so searchEngine nevers shows up , with a simple RewriteRule

 RewriteRule ^search/(.*)/(.*)$ /searchEngine?search_action[city]=$1&search_action[radius]=$2 [L]

But once I try to use this same rule with Symfony ( in the .htaccess in the /web forlder, right ?),

www.website.com/search/London/15 land on a Symfony 404 Error Page

My guess is that Symfony tries to look for an internal /Search route, which does not exist as the URL is intended to silently redirect to SearchEngin through the .htaccess

SearchEngine route does exist and www.website.com/SearchEngine?search_action[city]=London&search_action[radius]=15 works very fine

So far, .htaccess and Symfony works together if I add the R flag to the RewriteRule

 RewriteRule ^search/(.*)/(.*)$ /searchEngine?search_action[city]=$1&search_action[radius]=$2 [R,L]

But that's because the URL changes in the browser as it is redirected to SearchEngine.

Is there a way so that Symfony knows that /search/London/15 leads to SearchEngine?search_action[city]=London&search_action[radius]=15, and works without the Url changing ?

Anyone have an idea as to what I should tweak for that ?

Routing

Quite really basic , a single Route just for that URL readable feature and Search, nothing too fancy.

routing.yml

research_action:
path:     /SearchEngine
defaults: { _controller: "MySearchBundle:Search:search" }

SearchController:searchAction

public function searchAction(Request $request)
{
    /*
       expect search_action[city]=London and search_action[radius]=15
    */
    $form = $this->createForm('MySearchBundle\Form\Type\SearchType',null);
    $form->handleRequest($request);
    if($form->isSubmitted() && $form->isValid())
    {
         //Get here without problem when from SearchEngine?search_action[city]=London&search_action[radius]=15
           /* 
               This is where Zhuli do the thing
             */

    }
  return $this->render('SomeDefaultPage.html.twig');
}

.htaccess

...
//Basic Symfony Routing stuff
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
#Doesn't work without that R tag
RewriteRule search/(.*)/(.*)$ /SearchEngine?search_action[city]=$1&search_action[radius]=$2 [R=301,L]
# Rewrite all other queries to the front controller.
RewriteRule .? %{ENV:BASE}/app.php [L]
.....
1 Answers

So I found something which is quite longer than just a rule in .htaccess, but I could not find another workaround.

I created a new Route which will forward the /search/London/15 query toward the SearchEngine

forward_action:
path:     /search/{city}/{radius}
defaults: { _controller: "MySearchBundle:Search:searchForward" }

Controller

In the Controller Action I retrieve the URL Attribute (city and radius ) that I pass to the Request:ParameterBag; which I then forward to the SearchEngineAction

  public function searchForwardAction(Request $request,$city,$radius)
  {
        //Putting the attribute in an array
        $query['city']=$city;
        $query['radius']=$radius;
        /*
           Which I pass to the request as a parameter
           The forward will treat this like a Get Query
           ?search_action[city]=$city&search_action[radius]=$radius
         */
        $request->query->set('search_action',$query);
        //Forwarding !
        return $this->forward('MySearchBundle:Search:search',  array('request' => $request));
}

Since I use forward() the URL on the browser stays like /Search/Kyoto/25 but return the result of /SearchEngine?search_action[city]=Kyoto&search_action[radius]=25

It works quite fine but the amount of code and work for just this URL rewriting becomes quite heavy if one compares it to normally a single rule in an .htaccess ( which still does not work properly)

And I will have to modify where the Search Form direct to

I doubt it to be THE best solution since it is quite ..complicated for a such simple task.

Anyone got better ?

Related