2015-05-11 17 views
8

Während building multi-tenancy packages for Laravel 5 musste ich herausfinden, wie Middleware dynamisch aus Code hinzufügen. Im Vergleich zu this question on SO möchte ich nicht die Http/Kernel-Definitionen berühren.Dynamische Middleware für Laravel 5

Während der Initialisierung der Anwendung überprüfe ich, ob der angeforderte Hostname in der Datenbank bekannt ist und ob dieser Hostname eine Umleitung zu einem primären Hostnamen oder ssl erfordert.

Da Sie das Http/Kernel nicht als Paket berühren möchten, müssen wir den Dienstanbieter verwenden.

Anforderungen:

  • dynamisch Middleware hinzufügen, ohne Http/Kernel
  • Verwendung Dienstleister und Response-Objekt anstelle von "Hacks" zu berühren

Antwort

3

Die Lösung ist dynamisch die Middleware in die registrieren Kernel. Zuerst Ihre Middleware schreiben, zum Beispiel:

<?php namespace HynMe\MultiTenant\Middleware; 

use App; 
use Closure; 
use Illuminate\Contracts\Routing\Middleware; 

class HostnameMiddleware implements Middleware 
{ 
    public function handle($request, Closure $next) 
    { 
     /* @var \HynMe\MultiTenant\Models\Hostname */ 
     $hostname = App::make('HynMe\Tenant\Hostname'); 
     if(!is_null($redirect = $hostname->redirectActionRequired())) 
      return $redirect; 

     return $next($request); 
    } 
} 

Jetzt in Ihrem service provider den folgenden Code in der boot() Methode verwendet diese Middleware auf den Kernel hinzuzufügen:

$this->app->make('Illuminate\Contracts\Http\Kernel')->prependMiddleware('HynMe\MultiTenant\Middleware\HostnameMiddleware'); 

zu beantworten, was redirectActionRequired() Methode in dem tut hostname Objekt:

/** 
* Identifies whether a redirect is required for this hostname 
* @return \Illuminate\Http\RedirectResponse|null 
*/ 
public function redirectActionRequired() 
{ 
    // force to new hostname 
    if($this->redirect_to) 
     return $this->redirectToHostname->redirectActionRequired(); 
    // @todo also add ssl check once ssl certificates are support 
    if($this->prefer_https && !Request::secure()) 
     return redirect()->secure(Request::path()); 

    // if default hostname is loaded and this is not the default hostname 
    if(Request::getHttpHost() != $this->hostname) 
     return redirect()->away("http://{$this->hostname}/" . (Request::path() == '/' ? null : Request::path())); 

    return null; 
} 

Wenn Sie routeMiddleware dynamisch registrieren müssen, verwenden Sie Folgendes in Ihrem s Dienstleister;

$this->app['router']->middleware('shortname', Vendor\Some\Class::class); 

Bitte fügen Sie Kommentare hinzu, wenn Sie Fragen zu dieser Implementierung haben.