diff --git a/src/DoctrineServiceProvider.php b/src/DoctrineServiceProvider.php index e13599df..290b1a53 100644 --- a/src/DoctrineServiceProvider.php +++ b/src/DoctrineServiceProvider.php @@ -8,6 +8,7 @@ use Doctrine\ORM\Mapping\ClassMetadataFactory; use Faker\Factory as FakerFactory; use Faker\Generator as FakerGenerator; +use Illuminate\Contracts\Http\Kernel as HttpKernel; use Illuminate\Support\ServiceProvider; use InvalidArgumentException; use LaravelDoctrine\ORM\Auth\DoctrineUserProvider; @@ -28,6 +29,7 @@ use LaravelDoctrine\ORM\Console\SchemaValidateCommand; use LaravelDoctrine\ORM\Exceptions\ExtensionNotFound; use LaravelDoctrine\ORM\Extensions\ExtensionManager; +use LaravelDoctrine\ORM\Http\Middleware\BootExtensions; use LaravelDoctrine\ORM\Testing\Factory as EntityFactory; use LaravelDoctrine\ORM\Validation\DoctrinePresenceVerifier; @@ -40,9 +42,7 @@ public function boot() { $this->extendAuthManager(); - $this->app['events']->listen('router.matched', function () { - $this->app->make(ExtensionManager::class)->boot(); - }); + $this->bootExtensionManager(); if (!$this->isLumen()) { $this->publishes([ @@ -226,6 +226,32 @@ protected function extendAuthManager() }); } + /** + * Boots the extension manager at the appropriate time depending on if the app + * is running as Laravel HTTP, Lumen HTTP or in a console environment + */ + protected function bootExtensionManager() + { + // If running in console we can boot immediately + if (php_sapi_name() === 'cli') { + $this->app->make(ExtensionManager::class)->boot(); + + return; + } + + // If running a HTTP Request in Laravel we want to push in middleware so we + // boot after the session start. Some extensions make use of the session + // to find out who the currently authenticated user is, e.g Loggable + if (!$this->isLumen()) { + $this->app->make(HttpKernel::class)->pushMiddleware(BootExtensions::class); + + return; + } + + // Add BootExtension to the end of the Lumen middleware stack + $this->app->middleware([BootExtensions::class]); + } + /** * Register the Entity factory instance in the container. * diff --git a/src/Http/Middleware/BootExtensions.php b/src/Http/Middleware/BootExtensions.php new file mode 100644 index 00000000..406936d5 --- /dev/null +++ b/src/Http/Middleware/BootExtensions.php @@ -0,0 +1,35 @@ +manager = $manager; + } + + /** + * @param \Illuminate\Http\Request $request + * @param Closure $next + * + * @return mixed + */ + public function handle($request, Closure $next) + { + $this->manager->boot(); + + return $next($request); + } +} diff --git a/tests/Http/Middleware/BootExtensionsTest.php b/tests/Http/Middleware/BootExtensionsTest.php new file mode 100644 index 00000000..1c0a1bb1 --- /dev/null +++ b/tests/Http/Middleware/BootExtensionsTest.php @@ -0,0 +1,36 @@ +shouldReceive('boot') + ->once() + ->getMock(); + + $requestMock = m::mock(Illuminate\Http\Request::class); + + $called = false; + + $nextMock = function () use (&$called) { + $called = true; + }; + + /** @noinspection PhpParamsInspection */ + $middleware = new BootExtensions($kernelMock); + + /** @noinspection PhpParamsInspection */ + $middleware->handle($requestMock, $nextMock); + + $this->assertTrue($called); + } +}