Hi great tutorial. I am trying to register new user from public like test1.example.com, test2.example.com etc. so when a client register do we need to edit 'hosts' file each client register, to add the subdomain programatically. Do we have any alternative solution to accept all wildcard subdomain in host file ? Thanks in advance
Hm... IIRC there is no possibility to use wildcards directly in hosts file so the only solution for it is to use some sort of local DNS server or you can use Symfony CLI dev server it has a proxy server which allows you to have dev domains for free but with some limitations
On the same theme of dynamic subdomains, how can I keep the same user authenticated when I switch between subdomains? I have the session / handler_id set to ~ in framework.yaml, not sure how to set the cookie domain.
Good question! Hm, actually, it should work our of the box with Symfony, but according to your question cookie domain should be as ".example.com" - note that dot before example.com - that means you want to use these cookies on example.com and all its subdomains.
Hi guys. I am trying to use that method in Symfony 4. But when I set currentSite with Listener and inject SiteManager to Controller Symfony create new Instance of SiteManager class and currentSite is null. Please help. Regards Mike
Interesting! I'm sure we can get this working! Can you post your listener and controller code? If setup correctly, Symfony should be using the same SiteManager instance in both the listener and controller. So, this "shouldn't" be happening - I bet something isn't quite right :).
Hmm. This all looks good to me. But, I have an idea. Can you show me your services.yml? I'm wondering if, while upgrading to the new "service magic", you may have accidentally registered the AccountManager service two times? Specifically, if you still have the old account.manager service declared, but you also have the new "service autoregistration" code (the lines with resource and exclude), then your service is being created two times. If that's the case, my guess is that you're passing the old one (with the snake case id) to your listener, while the controller "action injection" is definitely passing you the new service.
You were right! I had an old definition of services, after removing works fine:) but I have one more issue. In my listener, I have method which checks if there is user logged in. After update servies.yml Symfony says that I should use TokenStorageInterface instead of TokenStorage. What $tokenId should I add as a argument to getToken()?
There is a better way to get the logged in user in a service, by using the "Security" service. In this episode you can see how Ryan uses it: https://symfonycasts.com/sc...
And, specifically, I think you have the wrong TokenStorageInterface - there are (unfortunately) 2. If you tried the other one, it *would* work. But Diego is right - Security is easier!
Ya, no video download for this - it was just because it was the *only* video in all of these posts. But if you want, you can always download the mp4 that's streaming in the browser (open up network tools to get the URL).
Why is the event listener necessary? It may be my inexperience talking but it seems like anything involving events causes code to appear kind of magical unless you are already aware of it, so for me events are something to be avoided unless they are necessary. In this case it isn't really necessary since it's possible to inject the request directly into your service. Here's how: http://stackoverflow.com/qu...
What do you guys think? I'm still a novice to Symfony so I'd really appreciate some best-practices wisdom :)
Actually, you're right on all accounts. You would only *need* an event listener if you needed to actually *do* something with the current "Site" at the beginning of the request (e.g. maybe some Site's are locked down, so you redirect to the login page). But if you only need the information later from some service, then yea, just inject the service as you said. So, you're not missing anything at all - quite the opposite :).
The StackOverflow you linked to correctly injects the request_stack - so that's perfect. It does it via "setter" injection (that's the "calls" stuff). You can also just inject it via the constructor like any other normal service - just wanted to highlight that there's nothing special going on there.
Cheers!
P.S. Good question - maybe you're not such a novice ;)
Nice tutorial, This is exactly what i was looking for, this means that the site table needs to have relationship with every table that gets created so the data can be linked with the site that the content are meant for.
Exactly :). The trick is to keep your code organized and make sure that *all* queries include the WHERE statement for the correct site. I typically do this manually, but you can also have Doctrine automatically add that to the query (http://knpuniversity.com/sc.... It's a matter of taste.
Thanks Ryan for letting me know about the filter tutorial, I will look into that. Out of curiosity I was wondering if we have dynamic subdomains setup what happens if you want to change the look of one of the subdomains a bit for example change the logo or background color, how will that work since the code base behind the scene is all same? Does this mean that we will need to save the template parts in database which users can customise as per theirs needs or there is an easier alternate provided by Symfony?
It depends on *how* much needs to change. There are kind of 3 levels:
A) If you just need a different logo and different company name, just make sure your Site entity has fields for logo and "name" and print this in Twig! I usually make some custom Twig function like get_current_site(), or even make site() a global variable so that I have the Site object.
B) If you have a few different variants of part of your page (e.g. you have 15 sites, but they have 3 different themes), then you could use something like LiipThemeBundle and set the theme based on some property on the Site (e.g. Site.themeName)
C) If you parts of your page need to be completely different and you even need to be able to change those templates on production, then yes, you'll need to store at least some fragments of Twig in the database (which is ok, but this seems like a crazy requirement to me!)
Hi Ryan, I have been thinking if it is possible to create some sort of wildcard host in /etc/hosts like
*.lolnimals.l```
This way we don't have to hard code every host/subdomain? is this possible? Reason I am asking this is because I have this signup form where user provides the company name and then based on this company a url is generated for them to use the web app like http://companyname.example.com now the routing and all is fine but it is this /etc/hosts file I am thinking how to setup so I dont have to manually add every company name domain in it.
Actually, /etc/hosts is *not* dynamic like this. However, you *can* make DNS records on the web that are dynamic. In other words, this is a problem when developing locally, but not on production. There *are* ways to do this locally, but they're more complex than using /etc/hosts.
But check out Laravel's Valet: https://laravel.com/docs/5..... This is a standalone tool to help manage this type of thing. I haven't used it yet, but I believe it does something similar: it sets up something locally so that all *.dev sites point to your local machine. It might or might not work - but something worth checking (or you can try to dig to see how they do it).
Cheers!
Please, log in to vote for this comment
|
Share Comment
"Houston: no signs of life" Start the conversation!
24 Comments
Hi great tutorial. I am trying to register new user from public like test1.example.com, test2.example.com etc. so when a client register do we need to edit 'hosts' file each client register, to add the subdomain programatically. Do we have any alternative solution to accept all wildcard subdomain in host file ? Thanks in advance
Hey Nikhil EV
Hm... IIRC there is no possibility to use wildcards directly in hosts file so the only solution for it is to use some sort of local DNS server or you can use Symfony CLI dev server it has a proxy server which allows you to have dev domains for free but with some limitations
Cheers!
Terrific tutorial, works great.
On the same theme of dynamic subdomains, how can I keep the same user authenticated when I switch between subdomains? I have the session / handler_id set to ~ in framework.yaml, not sure how to set the cookie domain.
Hey Michael,
Good question! Hm, actually, it should work our of the box with Symfony, but according to your question cookie domain should be as ".example.com" - note that dot before example.com - that means you want to use these cookies on example.com and all its subdomains.
Cheers!
Hi guys. I am trying to use that method in Symfony 4. But when I set currentSite with Listener and inject SiteManager to Controller Symfony create new Instance of SiteManager class and currentSite is null. Please help. Regards Mike
Hey Mike Base!
Interesting! I'm sure we can get this working! Can you post your listener and controller code? If setup correctly, Symfony should be using the same SiteManager instance in both the listener and controller. So, this "shouldn't" be happening - I bet something isn't quite right :).
Cheers!
Thanks for the response Otto K., below my code (the code is customized to my app, but the behaviour is the same):
class DefaultController extends AbstractController
{
$this->get('account.manager')->getCurrentAccount();
`Hey Mike Base!
Hmm. This all looks good to me. But, I have an idea. Can you show me your services.yml? I'm wondering if, while upgrading to the new "service magic", you may have accidentally registered the AccountManager service two times? Specifically, if you still have the old
account.managerservice declared, but you also have the new "service autoregistration" code (the lines withresourceandexclude), then your service is being created two times. If that's the case, my guess is that you're passing the old one (with the snake case id) to your listener, while the controller "action injection" is definitely passing you the new service.Let me know!
Cheers!
You were right! I had an old definition of services, after removing works fine:) but I have one more issue. In my listener, I have method which checks if there is user logged in. After update servies.yml Symfony says that I should use TokenStorageInterface instead of TokenStorage. What $tokenId should I add as a argument to getToken()?
Hey Mike Base
There is a better way to get the logged in user in a service, by using the "Security" service. In this episode you can see how Ryan uses it: https://symfonycasts.com/sc...
Cheers!
And, specifically, I think you have the wrong TokenStorageInterface - there are (unfortunately) 2. If you tried the other one, it *would* work. But Diego is right - Security is easier!
Agree. Security works perfecto:) weaverryan weaverryan huge thanks for your help. Cheers!
Excelente!
Is it possible to download this video ? Is not the option in Download button
Ya, no video download for this - it was just because it was the *only* video in all of these posts. But if you want, you can always download the mp4 that's streaming in the browser (open up network tools to get the URL).
Cheers!
Why is the event listener necessary? It may be my inexperience talking but it seems like anything involving events causes code to appear kind of magical unless you are already aware of it, so for me events are something to be avoided unless they are necessary. In this case it isn't really necessary since it's possible to inject the request directly into your service. Here's how: http://stackoverflow.com/qu...
What do you guys think? I'm still a novice to Symfony so I'd really appreciate some best-practices wisdom :)
Hey Jeff!
Actually, you're right on all accounts. You would only *need* an event listener if you needed to actually *do* something with the current "Site" at the beginning of the request (e.g. maybe some Site's are locked down, so you redirect to the login page). But if you only need the information later from some service, then yea, just inject the service as you said. So, you're not missing anything at all - quite the opposite :).
The StackOverflow you linked to correctly injects the request_stack - so that's perfect. It does it via "setter" injection (that's the "calls" stuff). You can also just inject it via the constructor like any other normal service - just wanted to highlight that there's nothing special going on there.
Cheers!
P.S. Good question - maybe you're not such a novice ;)
Nice tutorial, This is exactly what i was looking for, this means that the site table needs to have relationship with every table that gets created so the data can be linked with the site that the content are meant for.
Exactly :). The trick is to keep your code organized and make sure that *all* queries include the WHERE statement for the correct site. I typically do this manually, but you can also have Doctrine automatically add that to the query (http://knpuniversity.com/sc.... It's a matter of taste.
Cheers!
Thanks Ryan for letting me know about the filter tutorial, I will look into that. Out of curiosity I was wondering if we have dynamic subdomains setup what happens if you want to change the look of one of the subdomains a bit for example change the logo or background color, how will that work since the code base behind the scene is all same? Does this mean that we will need to save the template parts in database which users can customise as per theirs needs or there is an easier alternate provided by Symfony?
It depends on *how* much needs to change. There are kind of 3 levels:
A) If you just need a different logo and different company name, just make sure your Site entity has fields for logo and "name" and print this in Twig! I usually make some custom Twig function like get_current_site(), or even make site() a global variable so that I have the Site object.
B) If you have a few different variants of part of your page (e.g. you have 15 sites, but they have 3 different themes), then you could use something like LiipThemeBundle and set the theme based on some property on the Site (e.g. Site.themeName)
C) If you parts of your page need to be completely different and you even need to be able to change those templates on production, then yes, you'll need to store at least some fragments of Twig in the database (which is ok, but this seems like a crazy requirement to me!)
I hope that helps!
Thanks Ryan, i will dig into this further
Hi Ryan, I have been thinking if it is possible to create some sort of wildcard host in /etc/hosts like
Hey Shairyar!
Actually, /etc/hosts is *not* dynamic like this. However, you *can* make DNS records on the web that are dynamic. In other words, this is a problem when developing locally, but not on production. There *are* ways to do this locally, but they're more complex than using /etc/hosts.
But check out Laravel's Valet: https://laravel.com/docs/5..... This is a standalone tool to help manage this type of thing. I haven't used it yet, but I believe it does something similar: it sets up something locally so that all *.dev sites point to your local machine. It might or might not work - but something worth checking (or you can try to dig to see how they do it).
Cheers!
"Houston: no signs of life"
Start the conversation!