How to rewrite URL passed on to Symfony Router? - symfony

I know that URL rewrite is done on webserver. And that is actually what is happening.
However my app reside in subfolder, and that sub-folder is passed along.
Question: So how can I configure router to skipp/remove that part of url that is used for routing? Maybe some Symfony event can be used for such purpose?
Info:
Symfony 2.8
PHP 5.6
IIS 8

Use a listener if you have to:
Pass the Router as an argument in the service definition
#router
use a onKernelRequest with a GetResponseEvent
public function onKernelRequest(GetResponseEvent $event)
use the Request and Response to create a new sub request
// No redirect, we create a new sub request
$subRequest = $request->duplicate([], null, [
'_controller' => $route['controller'],
'_route' => $route['route']
]);
$response = $this->kernel->handle(
$subRequest, HttpKernelInterface::SUB_REQUEST);
$event->setResponse($response);
if you need a redirect:
$url = $this->router->generate($route['target']);
$response = new RedirectResponse($url);
$event->setResponse($response);
This is the gist of it and it is working fine for an in-house solution where the user can define a redirect for part of the application. So it should be working as well to rewrite all the paths.
HTH
~thoroc
(sorry for the bad formatting)

Use the symfony router to rewrite a part of your base url is not a good idea.
Look at the web server configuration and make a specific vhost for your app that points to the web directory, or update the default .htaccess located in the web folder of your app.
http://symfony.com/doc/current/cookbook/configuration/web_server_configuration.html

Related

Symfony2 and WebRTC, routing issue

So I use Pubnub for WebRTC in my Symfony 2 application, and all works well, apart from the showing of videos of other users. What happens is that when a user connects, an url gets generated like this one:
mediastream:http://www.domain.com/cd024a62-02fa-42eb-8f52-621074ea887e
These url's are temporary, and the only purpose is to serve as a way to connect video streams. After the WebRTC session the do not exist anymore and they are impossible to predict.
Since the Symfony router cannot find a route to 'http://www.domain.com/cd024a62-02fa-42eb-8f52-621074ea887e', the stream is never showed (www.domain.com is the url to the symfony application in this example).
What I could do is adapt the exisiting scripts so that all video streams look like 'http://www.domain.com/video/cd024a62-02fa-42eb-8f52-621074ea887e', but in that case any route with prefix /video/ should be left alone by Symfony.
Any ideas?
In the end I found a solution. As a last routing rule I added:
display_blob:
defaults: { _controller: Bundlename:Main:blob }
path: /{blob}
Then I created a function in the Main controller:
public function blobAction(Request $request)
{
$path = $request->getUri();
return $this->render($path);
}
Of course I need to do some filtering of the URL itself and check if it really is a stream, but for now I am happy it works.

WebTestCase, Silex and $_GET

I'm experiencing some issues on a WebTestCase using Silex: on one of my controller's action, I need a parameter passed through a normal $_GET (I have to as it's an URL, and Apaches interprets the %2F if it's outside of the query string -- see Url Variables with %2f not handled by silex for example)
Here's how my route is defined:
$controller
->get('/get', <controller action>)
->value('url', (!empty($_GET['url']) ? $_GET['url'] : false));
It works fine in browser, but it doesn't seem to be working inside a WebTestCase like this one: $_GET stays empty...
$client = $this->createClient();
$client->request('GET', '/get?url=' . urlencode($url));
edit
I just did a quick experiment: if I do the following in my route:
$controller
->get('/get/{url}', <action>)
->assert('url', '.*');
And this in the test:
$client = $this->createClient();
$client->request('GET', '/get/' . urlencode($url));
Everything if fine, $url gets passed to the controller... but well, it doesn't work on the browser anymore as it passes through Apache.
The server globals (like $_GET) are populated by Apache. When running the functional test, Apache is skipped so $_GET is not populated anymore. Instead of using the server globals, you should use the Request object to extract the GET parameters. This way, the framework will intercept both the PHPUnit injected variables and the Apache injected variables; it will then make them available in your action method via a Request object that can be injected as a function parameter.
Sample how to extract the url parameter:
$url = $request->query->get('url');

Symfony2: How to get Authentication Listener config values into another service?

I'm working on creating an authentication provider for Symfony 2 that allows users to authenticate with the single sign on protocol called CAS.
My Authentication Listener extends from AbstractAuthenticationListener. One of the config params is check_path, which is the path/route that triggers the authentication listener to authenticate the request.
I need check_path when I construct the URL to the CAS server (so CAS server knows where to return the user to), which is easy, since my custom Entry Point class is passed the configuration array when it's constructed in my security Factory.
The hard part is that I also need check_path outside of the listener, like during authentication inside my Authentication Provider class. I need it because when CAS server sends the user back to the app, it passes a "ticket" parameter that must be validated. To validate it, I send a curl request to CAS server that must contain the ticket as well as the original check_path that was used.
As a wrote this, I realized that I could get the current URL of the page request when I'm inside the Authentication Provider (since it's check_path that triggers it anyway), but that seems off, and I'd rather get the config value directly to re-construct the service URL. It also doesn't help me when I want to use check_path elsewhere, like when constructing a logout URL to the CAS server which also required the check_path.
EDIT: The createAuthProvider method of AbstractFactory is passed both the config and the container, but I cannot modify any of my services in here because they are not yet part of the container. Perhaps if I had a way to add a compiler pass after my services are loaded and somehow having access to the listener config?
Can you pass check_path as parameter to your listener?
If it defined in your config or parameters file you can pass it to your listener like this:
your_authentication_listener:
class: YourBundle\Listener\AuthenticationListener
arguments: ['%check_path%']
tags:
...
(If I understood you correct.)
You can make %check_path%(or a namespaced version of it) a 'normal' parameter:
Inside of DependencyInjection, there are (by default) two classes responsible for defining and loading your bundle's configuration. In there you can also inject your configuration into your service container.
DependencyInjection\Configuration is where you define which configurations are available in your bundle, what type they should be etc.
DependencyInjection\YourBundleNameExtension is where you can load your configuration and also add them to the service container.
If you have not done anything in there yet, your Extension's load()-method should look something like this:
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader(
$container,
new FileLocator(__DIR__.'/../Resources/config')
);
$loader->load('services.yml');
}
$config holds your bundle's configuration in the form of an array, so if we imagine your YAML config file looks like this:
your_bundle_name:
check_path: foo
Your $config will look like that:
array( 'check_path' => 'foo' )
So now, all you have to do is add this configuration to the container. Inside your load()-method simply add something like:
$container->setParameter(
'my_bundle_name.check_path',
$config['check_path']
);
Inside your services.yml you can now use %my_bundle_name.check_path% like every other parameter:
my_bundle_name.security.authentication.provider:
class: MyBundleName\Security\Core\Authentication\Provider\MyAuthenticationProvider
arguments: ['%my_bundle_name.check_path%']
For more details, have a look at Symfony's documentation [1,
2]

Symfony Dev Toolbar not loading (wrong route)

I'm building a CMS style application with dynamic routing. So far it seems to work fine but the output doesn't honor the environment for WDT, assets and links... it always links to /whatever instead of /app_dev.php/whatever.
Dynamic routing is implemented via kernel.request listener. The relevant code is on gist. Do I need to pass the current environment to Twig at some moment?
Edit:
The problem appears when in DEV mode... no problem when in production mode.
Thanks to #AdrienBrault I finally solved the issue by using a Controller to do the rendering.
In the RequestListener I added a new route to the RouteCollection of the router indicating the controller which will handle the request.
$route = new Route($path, array(
'_controller' => 'CmsBundle:Routing:routing',
));
$this->router->getRouteCollection()->add('cms', $route);
In the controller it was a bit harder to get the original URL, but finally I solved it by querying the routers RouteCollection with the name assigned in the previous add() method.

Symfony2 Functional Testing $crawler Not Working

I have found that the functional tests in Symfony2 always try to request pages as "http://localhost"
My environment is setup with virtual hosts so I have my application at "http://symfony.dev"
After some testing I have found that if I run:
var_dump($client->getResponse()->getContent());
I will get the page I want, but if I var_dump the $crawler I can see that rather than requesting a page like "http://symfony.dev/page" it requested "http://localhost/page"
That gives a 404 so I am unable to test forms and so on.
Is there anyway to set the base URL to get this to work? Should I instead use something different like Selenium?
I found that I can pass the domain in to the Client. I will just make a base WebTestCase with this functionality so my tests work.
$client = static::createClient(array(), array('HTTP_HOST' => 'symfony.dev'));
$client->followRedirects(true);

Resources