Skip to content

Commit

Permalink
PHPORM-259 Register MongoDB Session Handler with `SESSION_DRIVER=mong…
Browse files Browse the repository at this point in the history
…odb` (#3192)

* PHPORM-259 Register MongoDB Session Handler with SESSION_DRIVER=mongodb
* Explicit dependency to symfony/http-foundation
  • Loading branch information
GromNaN authored Nov 6, 2024
1 parent 4fcf67b commit 8cf9f66
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 2 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
5 changes: 5 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ parameters:
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
Expand Down
21 changes: 21 additions & 0 deletions src/MongoDBServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down
43 changes: 42 additions & 1 deletion tests/SessionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -14,7 +16,7 @@ protected function tearDown(): void
parent::tearDown();
}

public function testDatabaseSessionHandler()
public function testDatabaseSessionHandlerCompatibility()
{
$sessionId = '123';

Expand All @@ -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);
}
}

0 comments on commit 8cf9f66

Please sign in to comment.