How to set _locale dynamically based on host - symfony

Is there any way to set _locale parameter of routing configuration as a function call or an expression result? I have multiple hosts running on the same symfony app, and there is an i18n turned on. Everything is working fine, but now i need to have another locales set for a specified host.
Right now my routing config looks like
app:
resource: '#AppBundle/Controller/'
...
requirements:
_locale: '%route_locales%'
...
and i have something like this in parameters:
...
route_locales: en|de|fr
...
That would be perfect if i can use something like
"#=service('AppBundle\\\\...\\\\LocalesConfigurator').getLocales()"
as a _locale: value to get this value based on a function call result. Or maybe there are some other options to get another _locale set for a specified host?

You can do it like #Jakumi suggested (via env params passed from server)
or using only application logic:
In route_locales put all possible locales that can be used in any host.
Validate incoming _locale inside "request listener" depending on request host - if some _locale is not allowed for host then return 404 response or show 404 error page etc.

Seems like i've found at least one solutuin, thanks to Jakumi for the idea. I've created a parameter in my config file, which receives an environment varaible. Then i use this parameter in my routing file. The main idea is that i can control this environment variable value using bootstrap file. So it looks like
bootstrap.php (in the example it's just a static value, but in a real life this value will depend on host).
bootstrap.php
...
$_SERVER['SYMFONY__ROUTE__LOCALES'] = 'en|es';
...
config.yml
parameters:
route_locales: '%route.locales%'
routing.yml
app:
resource: '#AppBundle/Controller/'
...
requirements:
_locale: '%route_locales%'
...
I don't realy like this solution, and will be thankful for any better solutions, but at least it does what i want.

I was in the same issue some months ago and I was able to found a solution that worked correctly, but there may also be some better ones.
As I needed different route names to be loaded depending on the locale (i.e. /contact in English and /contacto in Spanish) what I did was creating the methods in the controller and creating an individual link to them in routes.yaml
contact-en:
path: /contact/
controller: App\Controller\ContactController::index
host: domain1.tld
contact-es:
path: /contacto/
controller: App\Controller\ContactController::index
host: domain2.tld
Then I created an EventListener called LocaleSwitcher:
class LocaleSwitcher
{
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
$host = $request->getHost();
switch($host) {
case 'domain1.tld': {
$request->setLocale('en');
break;
}
case 'domain2.tld': {
$request->setLocale('es');
break;
}
}
}
}
And then adding it in services.yaml for event kernel.request and priority 20:
App\EventListener\LocaleSwitcher:
tags:
- { name: kernel.event_listener, event: kernel.request, priority: 20 }

Related

Optional Prefix part in Route

I'm trying to create a rather complex-route schema and I'm stuck.
Routes that I wan't to match
/books indexAction
/books/show showAction
/books/authorname indexAction
/books/authorname/show showAction
Current Setup
Routing.yml
actions:
resource: routing/actions.yml
prefix: /books/{authorname}
requirements:
authorname: ".*"
defaults:
authorname: ''
routing/actions.yml
books_index:
path: ""
defaults: { _controller:bookController:indexAction }
books_show:
path: "/show"
defaults: { _controller:bookController:showAction }
This Setup currently matches only:
/books/ indexAction
/books/show showAction
/books/authorname indexAction
/books/authorname/show showAction
but not
/books
The reasons why I split those routes into two files is that in reality the actions contain much more routes, also there is other routing-categories then the actions.
I know I could define the /books route manually without a prefix but I want to avoid this as this schema will be used for many different modules.
You need a /book prefix in any case.
One solution is to define separate entries in your routing.yml for that. One with /books prefix and the second with /books/{authorname}.
index:
resource: routing/actions.yml
prefix: /books
show:
resource: routing/actions.yml
prefix: /books/{authorname}
It's not so elegant, but in this case you can get rid of extra requirements section.
Hope this helps!

How to set correctly my routes files (url) with symfony2.5 with WAMP server

I set my route files in my Symfony2.5 project. But i have this problem when I launched my application with Wamp server (localhost on Windows):
No route found for "GET /" (from "http://localhost/girSymfony/web/")
404 Not Found - NotFoundHttpException
1 linked Exception: ResourceNotFoundException »
This is the url used when the application is lauched on WampServer: http://localhost/girSymfony/web/
When I tried with this URL http://localhost/girSymfony/web/I have the 404 error as mentioned above.
But if I try with this url: http://localhost/girSymfony/web/gir/homepage it works; I would like the application arrive and run directly on this url. How can i do that?
This is my Gir/WelcomeBundle/Ressource/config/routing.yml file code:
girWelcomeBundle_HomePage:
pattern: /homepage
defaults: { _controller: GirWelcomeBundle:HomePage:index }
requirements:
methods: GET
schemes:  https
And this my app/config/routing.yml file code:
GirWelcomeBundle:
resource: "#GirWelcomeBundle/Resources/config/routing.yml"
prefix: /gir
And here's my controller code for Gir/WelcomeBundle/Controller/HomePageController.php:
<?php
namespace Gir\WelcomeBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class HomePageController extends Controller
{
public function indexAction()
{
return $this->render('GirWelcomeBundle:HomePage:index.html.twig');
}
}
Like you can see, I set the routes files, but I just forgot something because I have the 404 error.
I think my application don't use the right direction and the right URL , how can I fix it ?
New edit: Note that I 've set WAMP and Symfony in order when I run my application I arrive directly on the HomePage index
You are on development environemt , you should have to use url like this
Example:
registration:
pattern: /registration
defaults: { _controller: UserBundle:Registration:registration }
http://localhost/girSymfony/web/app_dev.php/registration

symfony2: How to prevent FOSRestBundle from adding _api to route names and /api to urls?

I have an EventApiController class that looks like the following
Class EventApiController
{
public function getAction($event_id)
{
// ...
}
public function putAction($event_id)
{
// ...
}
}
Using the Friends of Symfony bundle's route generate i am expecting the route to look like
CalendarBundle_get_events [GET] /api/v1/events/{event_id}.{_format}
CalendarBundle_put_events [PUT] /api/v1/events/{event_id}.{_format}
However it seems like the Route generator automatically adds a post fix /api to all of the routes so the route looks like. And the documentation does not show this as the expected behaviour as well.
CalendarBundle_get_events_api [GET] /api/v1/events/{event_id}/api.{_format}
CalendarBundle_put_events_api [PUT] /api/v1/events/{event_id}/api.{_format}
Does anyone know how to get rid of the /api post fix from the generated link? I am using FOS/ResutBundle version 1.3.1
My config.yml for fos_rest
fos_rest:
routing_loader:
default_format: json
include_format: true
view:
view_response_listener: true
And the routing.yml looks like this in my Bundle
event_api:
type: rest
resource: "#CalendarBundle/Controller/EventsApiController.php"
prefix: /api/v1
name_prefix: CalendarBundle_
It's the Api in EventApiController that gets detected as route resource by FOSRestBundle.
You can override the resource name like this in order to prevent the _api route name and /api urls:
use FOS\RestBundle\Routing\ClassResourceInterface;
/**
* #RouteResource("Event")
*/
Class EventApiController implements ClassResourceInterface
{

Define route without ending slash when importing route in Symfony 2.5?

In file: HardCoreMore/HRAPIBundle/Resources/config/routing.yml
I have imported route like this:
hr_api_company:
resource: "#HRAPIBundle/Resources/config/routing/company.yml"
prefix: /company
And in file: HardCoreMore/HRAPIBundle/Resources/config/routing/company.yml
I have defined route for creating company like this:
hardcoremore_hr_api_company_create:
pattern: /
defaults: { _controller: HRAPIBundle:Company:create }
methods: [POST]
Now the route is matched with following url:
POST company/
but it is not matched when I called it with:
POST company
How can I define route without ending slash when importing route and prefixing it?
this is not possible, see : https://github.com/symfony/symfony/issues/4322
I hope this has helped

Symfony2 route based on host. With parameters

I have followed the instructions here:
http://symfony.com/doc/current/components/routing/hostname_pattern.html
To make the route based on the host. However I want to use parameters instead of hard coding. The documentation says you can use service parameters, but I seem to be having trouble getting the parameters to work.
Here is the code from routing.yml:
rc_course_new:
pattern: /course/new
host: "{ domain }"
defaults: { _controller: CoursesRCWizardBundle:Wizard:new }
requirements:
domain: "%rc_domain%"
And here is the code from services.yml:
parameters:
rc_domain: my.domain.com
I get this error (looks like it is not picking up the parameter but seeing it as a hard code):
Oops! Google Chrome could not find { domain }
Managed to fix this:
In the routing:
rc_course_new:
pattern: /course/new
host: "%rc_domain%"
defaults: { _controller: CoursesRCWizardBundle:Wizard:new }
In the services (might work better in the parameters file) file:
parameters:
rc_domain: my.domain.com

Resources