diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MongoDbSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MongoDbSessionHandler.php index e8293e4dde..83465a92ff 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MongoDbSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MongoDbSessionHandler.php @@ -50,9 +50,9 @@ class MongoDbSessionHandler implements \SessionHandlerInterface $this->mongo = $mongo; $this->options = array_merge(array( - 'id_field' => 'sess_id', - 'data_field' => 'sess_data', - 'time_field' => 'sess_time', + 'id_field' => '_id', + 'data_field' => 'data', + 'time_field' => 'time', ), $options); } @@ -77,10 +77,9 @@ class MongoDbSessionHandler implements \SessionHandlerInterface */ public function destroy($sessionId) { - $this->getCollection()->remove( - array($this->options['id_field'] => $sessionId), - array('justOne' => true) - ); + $this->getCollection()->remove(array( + $this->options['id_field'] => $sessionId + )); return true; } @@ -90,11 +89,21 @@ class MongoDbSessionHandler implements \SessionHandlerInterface */ public function gc($lifetime) { - $time = new \MongoTimestamp(time() - $lifetime); + /* Note: MongoDB 2.2+ supports TTL collections, which may be used in + * place of this method by indexing the "time_field" field with an + * "expireAfterSeconds" option. Regardless of whether TTL collections + * are used, consider indexing this field to make the remove query more + * efficient. + * + * See: http://docs.mongodb.org/manual/tutorial/expire-data/ + */ + $time = new \MongoDate(time() - $lifetime); $this->getCollection()->remove(array( $this->options['time_field'] => array('$lt' => $time), )); + + return true; } /** @@ -102,16 +111,13 @@ class MongoDbSessionHandler implements \SessionHandlerInterface */ public function write($sessionId, $data) { - $data = array( - $this->options['id_field'] => $sessionId, - $this->options['data_field'] => new \MongoBinData($data, \MongoBinData::BYTE_ARRAY), - $this->options['time_field'] => new \MongoTimestamp() - ); - $this->getCollection()->update( array($this->options['id_field'] => $sessionId), - array('$set' => $data), - array('upsert' => true) + array('$set' => array( + $this->options['data_field'] => new \MongoBinData($data, \MongoBinData::BYTE_ARRAY), + $this->options['time_field'] => new \MongoDate(), + )), + array('upsert' => true, 'multiple' => false) ); return true; diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MongoDbSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MongoDbSessionHandlerTest.php index fb4811dfc5..409296ef1d 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MongoDbSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MongoDbSessionHandlerTest.php @@ -28,7 +28,7 @@ class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase protected function setUp() { if (!class_exists('\Mongo')) { - $this->markTestSkipped('MongoDbSessionHandler requires the php "mongo" extension'); + $this->markTestSkipped('MongoDbSessionHandler requires the mongo extension.'); } $this->mongo = $this->getMockBuilder('Mongo') @@ -36,9 +36,9 @@ class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase ->getMock(); $this->options = array( - 'id_field' => 'sess_id', - 'data_field' => 'sess_data', - 'time_field' => 'sess_time', + 'id_field' => '_id', + 'data_field' => 'data', + 'time_field' => 'time', 'database' => 'sf2-test', 'collection' => 'session-test' ); @@ -81,17 +81,17 @@ class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase $collection->expects($this->once()) ->method('update') - ->will($this->returnCallback(function($citeria, $updateData, $options) use ($that, &$data) { - $that->assertEquals(array($that->options['id_field'] => 'foo'), $citeria); - $that->assertEquals(array('upsert' => true), $options); + ->will($this->returnCallback(function($criteria, $updateData, $options) use ($that, &$data) { + $that->assertEquals(array($that->options['id_field'] => 'foo'), $criteria); + $that->assertEquals(array('upsert' => true, 'multiple' => false), $options); $data = $updateData['$set']; })); $this->assertTrue($this->storage->write('foo', 'bar')); - $this->assertEquals('foo', $data[$this->options['id_field']]); $this->assertEquals('bar', $data[$this->options['data_field']]->bin); + $that->assertInstanceOf('MongoDate', $data[$this->options['time_field']]); } public function testReplaceSessionData() @@ -118,7 +118,7 @@ class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase $collection->expects($this->exactly(2)) ->method('update') - ->will($this->returnCallback(function($citeria, $updateData, $options) use (&$data) { + ->will($this->returnCallback(function($criteria, $updateData, $options) use (&$data) { $data = $updateData; })); @@ -150,13 +150,9 @@ class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase $collection->expects($this->once()) ->method('remove') - ->with( - array($this->options['id_field'] => 'foo'), - array('justOne' => true) - ); + ->with(array($this->options['id_field'] => 'foo')); - - $this->storage->destroy('foo'); + $this->assertTrue($this->storage->destroy('foo')); } public function testGc() @@ -183,11 +179,11 @@ class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase $collection->expects($this->once()) ->method('remove') - ->will($this->returnCallback(function($citeria) use($that) { - $that->assertInstanceOf('MongoTimestamp', $citeria[$that->options['time_field']]['$lt']); - $that->assertGreaterThanOrEqual(time() - -1, $citeria[$that->options['time_field']]['$lt']->sec); + ->will($this->returnCallback(function($criteria) use($that) { + $that->assertInstanceOf('MongoDate', $criteria[$that->options['time_field']]['$lt']); + $that->assertGreaterThanOrEqual(time() - -1, $criteria[$that->options['time_field']]['$lt']->sec); })); - $this->storage->gc(-1); + $this->assertTrue($this->storage->gc(-1)); } }