Symfony2 route based on host. With parameters - symfony

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

Related

How to set _locale dynamically based on host

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 }

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

Route with optional parameter is not working in Symfony 2

I am experiencing some issues with optional parameters in my routes. I think I did it properly according to the documentation but still it is not working.
So I have the following route defined:
test_wizard:
pattern: /test/wizard/{testName}/{step}/
defaults: { _controller: TestBundle:Wizard:wizard, step: 1 }
and would like the route to be able to be called by /test/wizard/someTestName and then fill in the step parameter with the default value of 1 but everytime I call the route just with the test name I get the following instead:
No route found for "GET /test/wizard/someTestName"
When I call the route by /test/wizard/someTestName/1/ itworks just fine. Why is my defined default value for step not working? Any suggestions? Thanks.
It is not possible to make a parameter optional if you have a character after it (/ in your case). You have to define two routes:
test_wizard:
pattern: /test/wizard/{testName}
defaults: { _controller: TestBundle:Wizard:wizard }
test_wizard_optional:
pattern: /test/wizard/{testName}/{step}/
defaults: { _controller: TestBundle:Wizard:wizard, step: 1 }

Symfony2 can't find route for an action

I'm doing a bundle with google drive api that lists files. I have in the IndexAction an if that sees if the user needs to give permission or already gave. If needs, then I get the url from google and redirect to that link.
In google console I put as redirect link:
www.googlebundle/firstTime
In my GoogleDriveController I've got the
public function firstTimeAction() {
(...)
}
And in my routing I got this:
FilesGoogleDriveBundle_firstTime:
pattern: /firstTime
defaults: { _controller: "FilesGoogleDriveBundle:GoogleDrive:firstTime" }
requirements: { _method: get }
FilesGoogleDriveBundle_homepage:
pattern: /Drive/{id}
defaults: { _controller: FilesGoogleDriveBundle:GoogleDrive:index }
But I get this error in prod.log:
[2012-11-26 16:50:14] request.ERROR: Symfony\Component\HttpKernel\Exception\NotFoundHttpException: No route found for "GET /firstTime" (uncaught exception) at /var/www/Symfony/app/cache/prod/classes.php line 4564 [] []
Does anyone know what's happening?
First make sure that symfony see your router rule.
In project root directory put
php app/console router:debug | grep FilesGoogleDriveBundle_firstTime
You should get something like this
FilesGoogleDriveBundle_firstTime GET /firstTime
The last value is the URL for this action.
FilesGoogleDriveBundle_firstTime:
pattern: /firstTime
defaults: { _controller: FilesGoogleDriveBundle:GoogleDrive:firstTime }
requirements:
_method: GET
Try this.
seems like a cache problem, clear the cache for the prod environment:
php app/console cache:clear --env=prod

Symfony2 i18n routing - defining an array of requirements

Is it possible to define an array of locales used in Symfony2 routing rules, so that I won't have to repeat it over and over in every route and alter it for each route separately in case I change the supported languages list?
I know it's very easy to do a quick search & replace in routing.yml, but the issue's scope could be easily expanded so that it provokes a question like this: is it possible to provide this locale array externally (i.e. to have it read from a database)?
For clarification - here is an example of what I have now:
page_show:
pattern: /{_locale}/page/{slug}
defaults: { _controller: myCompanymyBundle:Cms:pageShow }
requirements:
_locale: en|pl
slug: "[^,]+"
news_archive:
pattern: /{_locale}/news/archive
defaults: { _controller: myCompanymyBundle:Cms:newsArchive }
requirements:
_locale: en|pl
And here is an example of what I'd like to have:
page_show:
pattern: /{_locale}/page/{slug}
defaults: { _controller: myCompanymyBundle:Cms:pageShow }
requirements:
_locale: languages
slug: "[^,]+"
news_archive:
pattern: /{_locale}/news/archive
defaults: { _controller: myCompanymyBundle:Cms:newsArchive }
requirements:
_locale: languages
Where languages is an array, be it a YAML array or a PHP array provided externally; it's not really substantial.
This could be very helpful to further ease the configuration of the application I'm writing. I'd like to extract as much configuration as possible into the config.yml file. So that if I decide that, for instance, I want to add a new language quickly and I already support it in the business logic and templating layers, I just have to modify the languages array in config.yml and voila, it's done.
Thats something that bugs me every time. The only thing I could offer is to put your requirement params into app/config/parameters.yml
# src/App/Resources/config/routing.yml
sport:
pattern: /{_locale}/{sport}
defaults: { _controller: App:Vote:vote }
requirements: { _locale: %routing_locales%, sport: %routing_sports% }
# app/config/parameters.yml
parameters:
# routing requirement regex
routing_sports: 'hockey|football' # available sports so far
routing_locales: 'de|fr' # available locales so far

Resources