Symfony2 - Managing routes involving 2 kinds of bundle - symfony

I am a beginner in Symfony2, and I am working on Symfony2 project in which a kind of general bundle, let say CoreBundle, is managing all the routes (in this form, first.domain/a-route, second.domain/a-route, third.domain/a-route,...) of the website. Now I have been creating FirstBundle, SecondBundle, ThirdBundle with the idea to "transfer" the management of routes of each subdomain (firt, second, third,...) to the related bundle.
Beginning with the transfer of routes from CoreBundle to FirstBundle by editing /app/config/routing.yml file from:
resource: "#ProjectFirstBundle/Resources/config/routing.yml"
prefix: /
host: "{subdomain}.{domain}"
defaults: { _controller: ProjectFirstBundle:Public:aroute }
domain: %project_domain%
requirements:
domain: "%project_domain%"
subdomain: 'first'
to:
resource: "#ProjectFirstBundle/Resources/config/routing.yml"
prefix: /
And then creating FirstBundle/Resources/config/routing.yml file with the following content:
project_first_aroute:
path: /a-route
host: "{subdomain}.{domain}"
defaults: { _controller: ProjectFirstBundle:Public:aroute }
domain: %project_domain%
requirements:
domain: "%project_domain%"
subdomain: 'first'
And of course I have created controller and view files using the same schema as CoreBundle (by making an adaptation -- inheritance for .twig files). As the result, the following exception is being returned when running first.domain/a-route:
Fatal error: Uncaught exception 'Symfony\Component\Yaml\Exception\ParseException' with message 'Unable to parse at line 15 (near " domain: %project_domain%").' in
Any suggestions as to how I can effectively achieve my goal?
Thanks in advance for your help.

I Came to find out that I should have created FirstBundle/Resources/config/routing.yml file as followed:
project_first_aroute:
path: /a-route
host: "{subdomain}.{domain}"
defaults: { _controller: ProjectFirstBundle:Public:aroute, domain: "%project_domain%" }
requirements:
domain: "%project_domain%"
subdomain: 'first'

The error message is a syntax error from the Yaml Parser.
Please note that correct idention is essential in a Yaml File and check if you need to wrap %project_domain in quotes on the first occurence (see stackoverflow syntax highlighting, it looks odd).
-
Debugging routes in Symfony2
app/console router:debug

Related

Access Denied for view and download routes in SonataMediaBundle and Symfony 4

I use Symfony 4 (more precise 4.1) with SonataAdminBundle and SonataMediaBundle.
This is my config/routes/sonata_media.yaml:
sonata_media_gallery:
resource: '#SonataMediaBundle/Resources/config/routing/gallery.xml'
prefix: /media/gallery
sonata_media:
resource: '#SonataMediaBundle/Resources/config/routing/media.xml'
prefix: /media
If I run php bin/console debug:router there are the following routes in the output:
sonata_media_gallery_index ANY ANY ANY /media/gallery/
sonata_media_gallery_view ANY ANY ANY /media/gallery/view/{id}
sonata_media_view ANY ANY ANY /media/view/{id}/{format}
sonata_media_download ANY ANY ANY /media/download/{id}/{format}
The first two routes work fine, but when I try the other two routes, for example:
http://localhost:8000/media/view/
http://localhost:8000/media/view/1/default
http://localhost:8000/media/download/1
http://localhost:8000/media/download/1/default
then I always get AccessDeniedException, even though I'm authenticated as ROLE_SUPER_ADMIN.
The error happens in vendor/sonata-project/media-bundle/src/Controller/MediaController.php in downloadAction and in viewAction. I was digging around in the source code, but can't find the reason for the exception thrown.
After some research I found the culprit and solved the problem. Here I'd like to share my knowledge.
As I mentioned in the question, the exceptions were thrown from:
vendor/sonata-project/media-bundle/src/Controller/MediaController.php
in the methods downloadAction and viewAction. It was the following if-condition:
if (!$this->get('sonata.media.pool')->getDownloadSecurity($media)->isGranted($media, $this->getCurrentRequest())) {
throw new AccessDeniedException();
}
which is present in both methods. This led me to vendor/sonata-project/media-bundle/src/Provider/Pool.php, and further to vendor/sonata-project/media-bundle/src/Security/RolesDownloadStrategy.php. I couldn't find any bug or problem there, but it opened my eyes to another position in my own configuration:
access_control:
- { path: ^/admin/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
- { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
How could I be so stupid? The path /media is not declared in security.yml and can be accessed by not authenticated users. The SonataMediaBundle requires per default ROLE_ADMIN or ROLE_SUPER_ADMIN for downloading/viewing the media.
The routes for the Gallery were accessible because vendor/sonata-project/media-bundle/src/Controller/GalleryController.php doesn't check if access is granted.
After finding the culprit the question was which approach to chose to solve the problem
1) Change the route prefix:
sonata_media:
resource: '#SonataMediaBundle/Resources/config/routing/media.xml'
prefix: /admin/media
The declared path in security.yml covers now the media and ROLE_ADMIN and ROLE_SUPER_ADMIN can access the routes.
Disadvantage: what if you want to expose the media outside of the admin? And what if other roles should be able to access them.
2) Declare a new path in security.yml:
access_control:
- { path: ^/media/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
Now we can expose the media outside of the admin. But the other issue is still there: what if other roles need to access the media?
3) Configure another download strategy in the config for SonataMedia:
sonata_media:
# ...
contexts:
default: # the default context is mandatory
download:
strategy: sonata.media.security.connected_strategy
mode: http
# ...
and adjust the path:
access_control:
# ...
- { path: ^/media/, role: [IS_AUTHENTICATED_FULLY, IS_AUTHENTICATED_REMEMBERED] }
# ...
Now every logged in user can access the media. This solution worked for me.
However it is not a one-size-fits-all recipe. Please check the chapter security from the official documentation to get more detailed information.

Symfony: how to set default subdomain in a group subdomains?

Symfony version: 3.0
I have set multiple sub-domains for my project:
www.example.com, en.example.com and so on.
for one article page the url is:
www.example.com/article-1.html
en.example.com/article-1.html
if i add a sub-domain for the current domain:
article.www.example.com, article.en.example.com
the article.www.example.com is not good solution, i want to remove the www sub domain is article.example.com, when user open the en.example.com, the article.en.example.com is working.
how to do it?
i don't want to make a route file for each language site.
You can do it on the main routing file in /app/config by adding an host field at the same level as your path field and default field. The host field should contain the domain and subdomain you want, like in this example :
english_homepage:
path: /
host: article.example.com
default: { _controller: AcmeDemoBundle:Main:articles }
main_homepage:
path: /
host: www.example.com
default: { _controller: AcmeDemoBundle:Main:homepage }
You can also use placeholder, parameters, and other possibilities.
With them, you should be able to create variable subdomains to fit your needs.
For more information, read this : How to Match a Route Based on the Host

How do I ignore the top level domain when using host to route to a subdomain in Symfony?

I have a website that I'm testing locally using domain.lc. The website has a subdomain sub.domain.lc that routes to a different controller, like this:
my_bundle:
host: sub.domain.lc
resource: "#MyBundle/Controller/"
type: annotation
prefix: /
The subdomain routes to my bundle because of the host, but I would like it to also route to this bundle using sub.domain.com. Is there a way to ignore the top level domain using the host?
You can use placeholder like this:
my_bundle:
resource: "#MyBundle/Controller/"
type: annotation
prefix: /
host: "{domain}"
defaults:
domain: "%domain%"
requirements:
domain: "sub\.domain\.(lc|com)"
But there is a problem with generating absolute URLs. It depends on where your app is currently running (loc or com) and you need to specify it as container parameter (parameters.yml is good place). Link to similar problem.
Although kba did provide an answer that helped me very much and I will in fact accept his answer as the right one, I want to show you what my route ended up looking like:
my_bundle:
host: sub.domain.{tld}
resource: "#MyBundle/Controller/"
type: annotation
prefix: /
requirements:
tld: lc|nl
defaults:
tld: nl
I didn't use the Service Container Parameter in my route, because I know my domain won't change. Only my top level domain can change.

Symfony Routing with variable host

I am using the current version of Symfony and want to define a route with a specific subdomain. This is what I have:
xyz:
resource: "#XYZ/Controller/"
type: annotation
prefix: /
host: "xyz.symfony.dev"
I want to have symfony.dev variable, only xyz as a subdomain is a static value. How can I realize this? I don't get it in the documentation.
I'm not good with regex but this answer your question:
xyz:
resource: "#XYZ/Controller/"
type: annotation
prefix: /
host: "xyz.{domain}.{ltd}"
requirements:
domain: "([a-z0-9-])+"
ltd: "([a-z])+"
EDIT: Regex added

Symfony2 and hostname problems

I can try to map the url the next way:
en.test.example.local | en.example.com
AND
admin.test.example.local | admin.example.com
With admin I don't have any problem working fine but, when I try to begin the uri with a variable the symfony say:
Malformed inline YAML string ({locale}{enviroment}example.{domain})...
The config is the next:
# web urls
example_web:
host: {locale}{enviroment}example.{domain}
requirements: { locale: en , enviroment: .|.\w+., domain: local|com }
resource: "#ExampleWebBundle/Resources/config/routing.yml"
prefix: /
# admin urls
example_admin:
host: admin{enviroment}example.{domain}
requirements: { enviroment: .|.\w+., domain: local|com }
resource: "#ExampleAdminBundle/Resources/config/routing.yml"
prefix: /
If I put this:
# web urls
example_web:
host: en{enviroment}example.{domain}
requirements: { locale: en , enviroment: .|.\w+., domain: local|com }
resource: "#ExampleWebBundle/Resources/config/routing.yml"
prefix: /
working fine, but is a multilanguage application and I need the multilanguage by "subdomain"
My mistake was very very simple :P
host: "{_locale}.{enviroment}.example.{domain}"
missing double quotes furthermore using _locale for save in session for translate thank cheesemacfly
Why don't you use the _local parameter (symfony.com/doc/master/book/…)?
Well I resolved it with this information: Symfony2 Routing - route subdomains
But if anyone know a better answer, please tell me :)

Resources