Dynamic subdomain routing

Submitted by jaketoolson - 9 years ago

On many occasions, I use the subdomain to generate dynamic routes and a custom user experience. The current Laravel subdomain filter, requires a lot of extra work when generating routes. Each time you generate a route, using the laravel route() helper, you have to pass the subdomain as the first parameter. This provides an alternative method without having to pass the subdomain to route(). https://github.com/laravel/laravel/issues/2515 for additional follow-up

// Sample route, with a "before" filter called "domain_access"
Route::group(array('before' => 'domain_access'), function() {
   // routes
   Route::get('test', ['as' => 'test.index', 'uses' => 'TestController@index']);
});

// The acutal filter method called "domain_access"
Route::filter('domain_access', function(){

    // Checks subdomain is valid and exists in DB.
    $validProgram = \My\Models\Programs::check();
    if( ! $validProgram)
    {
        return Redirect::to('/');
    }
});

// The method within the filter called 'check'
// Returns Bool/Object
public static function check()
{
    $server = explode('.', Request::server('HTTP_HOST'));
    $subdomain = $server[0];
    $needsLookup = true;

    // Does a cached index already exist?
    if(Cache::has('user'))
    {
        $program = Cache::get('');
        // Compare the cached program against the subdomain.
        if($subdomain == $program)
        {
            $needsLookup = false;
            return $program;
        }
    }

    // Do I need to go and lookup the subdomain and confirm it's valid?
    if ($needsLookup )
    {
        Cache::forget('program');
        $program = static::lookupUsing('alias', $subdomain);
        if( ! $program)
        {
            return false;
            
        }
        else
        {
            Cache::put('program', $program, Config::get('session.lifetime'));
            return $program;
            
        }
    }
}
    
// Generate route, subdomain does not need to be passed
<a href="{{ route('test.index')}}"></a>