0

In my Laravel-5.8 application, I have a multi-company application using a single database. Each table have a company_id derived from the company table as shown below:

id | company_name       |    subdomain
1  | Main               |
2  | Company1           |    company1
3  | Company2           |    company2

Main=>  localhost:8888/myapp
Company1=>localhost:8888/company1.myapp
Company2=>localhost:8888/company2.myapp

I created a middleware:

class VerifyDomain
{
 public function handle($request, Closure $next)
 {
    $domain == "myapp"; // your company app name
    $path = $request->getPathInfo(); // should return /company1.myapp or /company2.myapp or /myapp 
    if (strpos($path, ".") !== false) { // if path has dot.
        list($subdomain, $main) = explode('.', $path);
        if(strcmp($domain, $main) !== 0){
            abort(404); // if domain is not myapp then throw 404 page error
        }
    } else{
        if(strcmp($domain, $path) !== 0){
            abort(404); // if domain is not myapp then throw 404 page error
        }
        $subdomain = ""; // considering for main domain value is empty string.
    }

    $company = Company::where('subdomain', $subdomain)->firstOrFail(); // if not found then will throw 404

    $request->session()->put('subdomain', $company); //store it in session

    return $next($request);
 }
}

Already, I have two (2) route groups in the route/web.php wgich looks like this:

Route::get('/', ['as' => '/', 'uses' => 'IndexController@getLogin']);

Auth::routes();
Route::get('/dashboard', 'HomeController@index')->name('dashboard');

  // Config Module
  Route::group(['prefix' => 'config', 'as' => 'config.', 'namespace' => 'Config', 'middleware' => ['auth']], function () {
    Route::resource('countries', 'ConfigCountriesController');
    Route::resource('nationalities', 'ConfigNationalitiesController');
});

 // HR Module
  Route::group(['prefix' => 'hr', 'as' => 'hr.', 'namespace' => 'Hr', 'middleware' => ['auth']], function () { 
    Route::resource('designations', 'HrDesignationsController');
    Route::resource('departments', 'HrDepartmentsController');  
    Route::resource('employee_categories', 'HrEmployeeCategoriesController');

});

I have 2 issues:

  1. If subdomain field is null, then the route should be for main domain: Main=> localhost:8888/myapp else localhost:8888/company1.myapp or localhost:8888/company2.myapp

2.How do I accomodate the route groups above into this:

 Route::domain('localhost:8888/myapp')->group(function () {
   Route::get('/', function ($id) {
       //
    });
 });

Route::domain('localhost:8888/{subdomain}.myapp')->group(function () {
   Route::get('/', function ($company_name, $id) {
       $company = Company::where('subdomain', $subdomain)->firstOrFail();
       // send the value of $company to data to send different view data 
   });
});

1 Answer 1

1

I'm not really sure that i understand you clearly. But, I hope you'll understand me :)

First thing is you're "domain". I suppose it's not real domain, but just uri. And maybe you should use it something like that:

Auth::routes();

$defaultDomain = config('myconfig.default_domain_name', 'myapp');

// I'm not reccomend to you use localhost:8888 here.
Route::domain('localhost:8888')
    ->group([
        'middleware' => ['veryfy_domain'] // Add your VerifyDomain Middleware here
    ], function () {
        // Here you already have a 'subdomain' param in session

        // If you need special logic for default domain, you can out it here
        Route::group(['prefix' => '/' . $defaultDomain], function () {
            Route::get('/', function ($id) {
               //
            });     
        });


        // Code below will work only with companies.
        Route::group(['prefix' => '/{test}.' . $defaultDomain], function () {
            Route::get('/', ['as' => '/', 'uses' => 'IndexController@getLogin']);
            Route::get('/dashboard', 'HomeController@index')->name('dashboard');

              // Config Module
            Route::group(['prefix' => 'config', 'as' => 'config.', 'namespace' => 'Config', 'middleware' => ['auth']], function () {
                Route::resource('countries', 'ConfigCountriesController');
                Route::resource('nationalities', 'ConfigNationalitiesController');
            });

             // HR Module
            Route::group(['prefix' => 'hr', 'as' => 'hr.', 'namespace' => 'Hr', 'middleware' => ['auth']], function () { 
                Route::resource('designations', 'HrDesignationsController');
                Route::resource('departments', 'HrDepartmentsController');  
                Route::resource('employee_categories', 'HrEmployeeCategoriesController');
            });
        });
    });

And about your middleware. I see it smth like that:

class VerifyDomain
{
    public function handle($request, Closure $next)
    {
        $request->get('domain_name', $this->getBaseDomain());

        $company = Company::where('subdomain', $subdomain)->firstOrFail();

        $request->session()->put('subdomain', $company);

        return $next($request);
    }

    // Better to store it in config
    protected function getBaseDomain()
    {
        return config('myconfig.default_domain_name', 'myapp');
    }
}

If you really want to use different domains, I think you need in your nginx something like this:

server_name *.myapp myapp;

And of course in your hosts file.

Than you can check it like that: http://company.myapp http://company1.myapp http://myapp

Config example:

  1. Create new file your_project_dir/app/config/myconfig.php (name it as you want)
  2. Put this code in the file:
return [
  'default_domain_name' => 'myapp'
];
  1. Now you can use in in youre code as i suggest:
config('myconfig.default_domain_name');
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks so much, I really understand you. I have two concerns: 1. Will the domain also have all the routes in subdomain? 2. You said I should store it in config. How do I do that? Thanks
Thanks so much @ArtemTumanov, I really understand you. I have two concerns: 1. Will the domain also have all the routes in subdomain? 2. You said I should store it in config. How do I do that? Thanks
1. Yes, no problem with that. They in one parent route group and you can add mutual routes, or if you need, you can put some routes currently to base domain group, and it will work only for base domain (/myapp, not company.myapp). 2. It's easy, just add your custom config file to /app/config/. An example: app/config/myconfig.php. And return array from it: return ['default_domain_name' => 'myapp']; And it will work with code from the answer. Doc
Please can you give me a sample of the content (what should be in) of myconfig.php. Secondly, if I'm live server, what do I use to replace localhost:8888 as in Route::domain('localhost:8888')
You should put in config this: return ['default_domain_name' => 'myapp'];. I think that you don't need domain('localhost:8888'). Just use Route::group()
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.