I'm trying to have multiple domains in my Laravel 5.1 app
Route::group(['domain' => 'api.example.local'], function() {
Route::resource('users', 'ResultController');
});
Route::group(['domain' => 'www.example.local'], function() {
Route::resource('home', 'HomeController');
});
When i doing the unit test for the api.example.local
public function testApiCall() {
$this->get('v1/users')->seeJson(['data' => 'users']);
}
However, this approach has failed and it's returning 404 request.
Therefore, i changed my test url to something like this
public function testApiCall() {
$this->get('http://api.example.local/v1/users')->seeJson(['data' => 'users']);
}
Finally, it's green for the unit test.
I'm wondering if this is the correct way to do it?
In additional, I will have different environment, for example http://api.example.stage/v1/users. Is that means I need to change the change the url to http://api.example.stage/v1/users when I'm doing unit test for stage?
It's almost the same for me but I'm setting ENV variables.
.env
FOO_DOMAIN=foo.example.com
WWW_DOMAIN=www.example.com
Routes
Route::domain(env('WWW_DOMAIN'))->group(function () {
Route::get('/', 'IndexController#index')->name('index');
});
Route::domain(env('FOO_DOMAIN'))->group(function () {
Route::get('/', 'FoolishController#index')->name('foolish');
});
Phpunit
$this->get('https://' . env('WWW_DOMAIN') . '/')
->assertSuccessful()
->assertSeeInOrder(['Home']);
Yes, this is quite correct way to me. I do the same.
I just use call instead of get
$this->call('GET',...
$this->assertResponseOk();
Related
I am new in laravel, I am creating a subdomain in same project main domain localhost.vibrant-invitations.com and subdomain sadmin.localhost.vibrant-invitations.com on local, now I want to get subdomain value like sadmin. I am trying following the code
Route::group(['domain' => '{subdomain}.localhost.vibrant-invitations.com'], function () {
Route::get('/', function ($subdomain) {
$name = DB::table('users')->where('name', $subdomain)->get();
dd($name);
});
});
Route::get('/', function () {
return "This will respond to all other '/' requests.";
});
this is always returning "This will respond to all other '/' requests", Route group with a domain is not working.
My laravel version 5.3
Please help me to solve this.
Regards
Yash
I have an app which requires different HomeControllerdepending on subdomain I'm using. So for example domain.mydomain.com/news should point to one controller and mydomain.com/news to other.
Is there any way to use interfaces in routes since now I'm getting an error that my interface is not instantiable:
Route::controller('home', 'RouterInterface', [
'getIndex' => 'home.index'
]);
Even if this somehow worked, I don't know where would I even inject concrete classes in order for this to pull adequate method?
Try this way
Route::group(['domain' => 'domain.mydomain.com'], function()
{
Route::any('/news', function()
{
return 'My sub domain';
});
});
Route::group(['domain' => 'mydomain.com'], function()
{
Route::any('/news', function()
{
return 'My main domain';
});
});
I use laravel framework I want to use more than one guard in my route like :
Route::group([ 'middleware' => 'jwt.auth', 'guard' => ['biker','customer','operator']], function () {}
I have a script in AuthServiceProvider.php like below in boot section:
$this->app['router']->matched(function (\Illuminate\Routing\Events\RouteMatched $event) {
$route = $event->route;
if (!array_has($route->getAction(), 'guard')) {
return;
}
$routeGuard = array_get($route->getAction(), 'guard');
$this->app['auth']->resolveUsersUsing(function ($guard = null) use ($routeGuard) {
return $this->app['auth']->guard($routeGuard)->user();
});
$this->app['auth']->setDefaultDriver($routeGuard);
});
That work with just one guard in route like 'guard'=>'biker'
So how change that code in AuthServiceProvider.php to work with more than one gaurd in route
I know this is an old question but I just went through this issue and figured out how to solve it by myself. This might be useful for someone else. The solution is very simple, you just have to specify each guard after the name of your middleware separated by commas like this:
Route::group(['middleware' => ['auth:biker,customer,operator'], function() {
// ...
});
The guards are then sent to \Illuminate\Auth\Middleware\Authenticate function authenticate(array $guards) which checks every guard provided in the array.
This works for Laravel 5.4.
Also works for Laravel 6.0.
I have one installation of Laravel on which I wish to run 3 sites (addon domains). I am using Laravel's route grouping method to grab each domain. However, I need to be able to know which domain I am working with inside of each group. What is the best way to do this? I have the following code:
Route::group(array('domain' => 'domainone.com'), function($domain = 'domainone')
{
Route::get('/', function($domain) {
//
});
});
^ Which doesn't work.
The notes suggest using wildcards in the URL, eg.
Route::group(array('domain' => '{domain}.com'), function()
{
Route::get('/', function($domain) {
//
});
});
However, I would prefer a different method, as I can't really use this during development on my local server. Is there any way that is more like my first method, in which I can just manually declare a key for each domain?
EDIT: I also then need to pass that domain variable to a controller, which I am also struggling to work out how to do?
Thanks.
EDIT 2
My problem is that I am not using subdomains, I am using domains; I have 3 separate domains for 3 sister sites that are running on the same installation of Laravel. So I have 3 route groups, one for each domain. Moreover, I don't want to request the domain variable using {domain}.com each time, I want to tell Laravel the domain in each case, then pass that domain as a variable to the appropriate controller within each group. Here is my example code:
$domain1 = 'domain1.com';
$domain2 = 'domain2.com';
$domain3 = 'domain3.com';
Route::group(array('domain' => $domain1), function(){
Route::get('/', 'PrimaryController#somefunction1'); // <-- I want to access $domain1 in my controller
});
Route::group(array('domain' => $domain2), function(){
Route::get('/', 'PrimaryController#somefunction2'); // <-- ...and $domain2
});
Route::group(array('domain' => $domain3), function(){
Route::get('/', 'PrimaryController#somefunction3'); // <-- ...and $domain3
});
This is an option for your first method:
$domain = 'domainone';
Route::group(array('domain' => $domain.'.com'), function() use ($domain)
{
Route::get('/', function() use ($domain) {
echo "$domain";
});
});
You can pass watever you like to your controllers, via groups too, you just need to add one more level.
$subdomain = 'atlanta';
$domain = 'domainone';
Route::group(array('domain' => "$subdomain.$domain.com"), function()
{
Route::group(array('domain' => '{subdomain}.{domain}.com'), function()
{
Route::get('testdomain', function($subdomain, $domain) {
dd("closure: subdomain: $subdomain - domain: $domain");
});
Route::get('testdomaincontroller', 'FooController#index');
});
});
By doing this you have to understand that your first two variables passed to your controller action will always be $subdomain and $subdomain. Here's a controller to show it, which you can use to test those routes too:
class FooController extends Controller {
public function index($subdomain, $domain)
{
dd("controller: subdomain: $subdomain - domain: $domain");
}
}
You'll have two different routes with this:
http://yourdomain.dev/testdomain
http://yourdomain.dev/testdomaincontroller
I accomplish this with the following two steps:
First, using the Laravel documentation example, I pull the subdomain down and assign it to {account}.
Route::group(array('domain' => '{account}.myapp.com'), function()
From here, any controller you assign to a route within this group will have the ability to inject this {account} data in to its functions.
Note: you can't access it in the constructor. Each function in the Controller that needs to use this data will need a parameter created for it. Like this:
/**
* The $subdomain variable below will capture the data stored in
* {account} in your route group. Note that you can name this variable
* anything you'd like.
*/
public function showCreateBankAccount($subdomain) {
echo "This is your subdomain: " . $subdomain;
}
I'm building an application where a subdomain points to a user. How can I get the subdomain-part of the address elsewhere than in a route?
Route::group(array('domain' => '{subdomain}.project.dev'), function() {
Route::get('foo', function($subdomain) {
// Here I can access $subdomain
});
// How can I get $subdomain here?
});
I've built a messy work-around, though:
Route::bind('subdomain', function($subdomain) {
// Use IoC to store the variable for use anywhere
App::bindIf('subdomain', function($app) use($subdomain) {
return $subdomain;
});
// We are technically replacing the subdomain-variable
// However, we don't need to change it
return $subdomain;
});
The reason I want to use the variable outside a route is to establish a database-connection based on that variable.
Shortly after this question was asked, Laravel implemented a new method for getting the subdomain inside the routing code. It can be used like this:
Route::group(array('domain' => '{subdomain}.project.dev'), function() {
Route::get('foo', function($subdomain) {
// Here I can access $subdomain
});
$subdomain = Route::input('subdomain');
});
See "Accessing A Route Parameter Value" in the docs.
$subdomain is injected in the actual Route callback, it is undefined inside the group closure because the Request has not been parsed yet.
I don't see why would you need to have it available inside the group closure BUT outside of the actual Route callback.
If want you want is to have it available everywhere ONCE the Request has been parsed, you could setup an after filter to store the $subdomain value:
Config::set('request.subdomain', Route::getCurrentRoute()->getParameter('subdomain'));
Update: applying a group filter to setup a database connection.
Route::filter('set_subdomain_db', function($route, $request)
{
//set your $db here based on $route or $request information.
//set it to a config for example, so it si available in all
//the routes this filter is applied to
Config::set('request.subdomain', 'subdomain_here');
Config::set('request.db', 'db_conn_here');
});
Route::group(array(
'domain' => '{subdomain}.project.dev',
'before' => 'set_subdomain_db'
), function() {
Route::get('foo', function() {
Config::get('request.subdomain');
});
Route::get('bar', function() {
Config::get('request.subdomain');
Config::get('request.db');
});
});
Above won't work in Laravel 5.4 or 5.6. Please test this one:
$subdomain = array_first(explode('.', request()->getHost()));
Way with macro:
Request::macro('subdomain', function () {
return current(explode('.', $this->getHost()));
});
Now you can use it:
$request->subdomain();
in the route call
$route = Route::getCurrentRoute();
and now you should have access to everything the route has. I.e.
$route = Route::getCurrentRoute();
$subdomain = $route->getParameter('subdomain');
YOU CAN GET THE SUBDOMAIN LIKE THIS
Route::getCurrentRoute()->subdomain