From 343ec55d77c29de5d8738e7e1e5857ab37cf49c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Tue, 5 Nov 2024 19:01:40 +0100 Subject: [PATCH 1/3] PHPORM-259 Register MongoDB Session Handler with SESSION_DRIVER=mongodb --- phpstan-baseline.neon | 25 ++++++++++++++++++++ src/MongoDBServiceProvider.php | 21 +++++++++++++++++ tests/SessionTest.php | 43 +++++++++++++++++++++++++++++++++- 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index e85adb7d2..26ca227e8 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,10 +1,35 @@ parameters: ignoreErrors: + - + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\\\:\\:pull\\(\\)\\.$#" + count: 1 + path: src/Auth/User.php + + - + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\\\:\\:push\\(\\)\\.$#" + count: 1 + path: src/Auth/User.php + + - + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\\\:\\:pull\\(\\)\\.$#" + count: 1 + path: src/Eloquent/Model.php + + - + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\\\:\\:push\\(\\)\\.$#" + count: 1 + path: src/Eloquent/Model.php + - message: "#^Access to an undefined property Illuminate\\\\Container\\\\Container\\:\\:\\$config\\.$#" count: 3 path: src/MongoDBBusServiceProvider.php + - + message: "#^Access to an undefined property Illuminate\\\\Foundation\\\\Application\\:\\:\\$config\\.$#" + count: 4 + path: src/MongoDBServiceProvider.php + - message: "#^Method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:push\\(\\) invoked with 3 parameters, 0 required\\.$#" count: 3 diff --git a/src/MongoDBServiceProvider.php b/src/MongoDBServiceProvider.php index 0932048c9..9db2122dc 100644 --- a/src/MongoDBServiceProvider.php +++ b/src/MongoDBServiceProvider.php @@ -10,6 +10,7 @@ use Illuminate\Filesystem\FilesystemAdapter; use Illuminate\Filesystem\FilesystemManager; use Illuminate\Foundation\Application; +use Illuminate\Session\SessionManager; use Illuminate\Support\ServiceProvider; use InvalidArgumentException; use League\Flysystem\Filesystem; @@ -20,6 +21,7 @@ use MongoDB\Laravel\Eloquent\Model; use MongoDB\Laravel\Queue\MongoConnector; use RuntimeException; +use Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler; use function assert; use function class_exists; @@ -53,6 +55,25 @@ public function register() }); }); + // Session handler for MongoDB + $this->app->resolving(SessionManager::class, function (SessionManager $sessionManager) { + $sessionManager->extend('mongodb', function (Application $app) { + $connectionName = $app->config->get('session.connection') ?: 'mongodb'; + $connection = $app->make('db')->connection($connectionName); + + assert($connection instanceof Connection, new InvalidArgumentException(sprintf('The database connection "%s" used for the session does not use the "mongodb" driver.', $connectionName))); + + return new MongoDbSessionHandler( + $connection->getMongoClient(), + $app->config->get('session.options', []) + [ + 'database' => $connection->getDatabaseName(), + 'collection' => $app->config->get('session.table') ?: 'sessions', + 'ttl' => $app->config->get('session.lifetime'), + ], + ); + }); + }); + // Add cache and lock drivers. $this->app->resolving('cache', function (CacheManager $cache) { $cache->extend('mongodb', function (Application $app, array $config): Repository { diff --git a/tests/SessionTest.php b/tests/SessionTest.php index 7ffbb51f0..ee086f5b8 100644 --- a/tests/SessionTest.php +++ b/tests/SessionTest.php @@ -3,7 +3,9 @@ namespace MongoDB\Laravel\Tests; use Illuminate\Session\DatabaseSessionHandler; +use Illuminate\Session\SessionManager; use Illuminate\Support\Facades\DB; +use Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler; class SessionTest extends TestCase { @@ -14,7 +16,7 @@ protected function tearDown(): void parent::tearDown(); } - public function testDatabaseSessionHandler() + public function testDatabaseSessionHandlerCompatibility() { $sessionId = '123'; @@ -30,4 +32,43 @@ public function testDatabaseSessionHandler() $handler->write($sessionId, 'bar'); $this->assertEquals('bar', $handler->read($sessionId)); } + + public function testDatabaseSessionHandlerRegistration() + { + $this->app['config']->set('session.driver', 'database'); + $this->app['config']->set('session.connection', 'mongodb'); + + $session = $this->app['session']; + $this->assertInstanceOf(SessionManager::class, $session); + $this->assertInstanceOf(DatabaseSessionHandler::class, $session->getHandler()); + + $this->assertSessionCanStoreInMongoDB($session); + } + + public function testMongoDBSessionHandlerRegistration() + { + $this->app['config']->set('session.driver', 'mongodb'); + $this->app['config']->set('session.connection', 'mongodb'); + + $session = $this->app['session']; + $this->assertInstanceOf(SessionManager::class, $session); + $this->assertInstanceOf(MongoDbSessionHandler::class, $session->getHandler()); + + $this->assertSessionCanStoreInMongoDB($session); + } + + private function assertSessionCanStoreInMongoDB(SessionManager $session): void + { + $session->put('foo', 'bar'); + $session->save(); + + $this->assertNotNull($session->getId()); + + $data = DB::connection('mongodb') + ->getCollection('sessions') + ->findOne(['_id' => $session->getId()]); + + self::assertIsObject($data); + self::assertSame($session->getId(), $data->_id); + } } From 7d02e84555ef7c844c80579a75d5f9da6593a210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Wed, 6 Nov 2024 10:04:14 +0100 Subject: [PATCH 2/3] Explicit dependency to symfony/http-foundation --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 9c958f1c4..68ec8bc4f 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,8 @@ "illuminate/database": "^10.30|^11", "illuminate/events": "^10.0|^11", "illuminate/support": "^10.0|^11", - "mongodb/mongodb": "^1.18" + "mongodb/mongodb": "^1.18", + "symfony/http-foundation": "^6.4|^7" }, "require-dev": { "mongodb/builder": "^0.2", From 9b16a8c0ef073bcc6ae9c85f4e529d2459a0dbd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Wed, 6 Nov 2024 11:51:33 +0100 Subject: [PATCH 3/3] PHPStan error format updated --- phpstan-baseline.neon | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 26ca227e8..7b34210ad 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,25 +1,5 @@ parameters: ignoreErrors: - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\\\:\\:pull\\(\\)\\.$#" - count: 1 - path: src/Auth/User.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\\\:\\:push\\(\\)\\.$#" - count: 1 - path: src/Auth/User.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\\\:\\:pull\\(\\)\\.$#" - count: 1 - path: src/Eloquent/Model.php - - - - message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\\\:\\:push\\(\\)\\.$#" - count: 1 - path: src/Eloquent/Model.php - - message: "#^Access to an undefined property Illuminate\\\\Container\\\\Container\\:\\:\\$config\\.$#" count: 3