Add mongodb session storage
Some changes based on @stof and @stloyd suggestions Some changes based on @vicb suggestions Some changes based on @vicb suggestions Add changes
This commit is contained in:
parent
4d8461f243
commit
40df3bf86f
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
|
||||
|
||||
/**
|
||||
* MongoDB session handler
|
||||
*
|
||||
* @author Markus Bachmann <markus.bachmann@bachi.biz>
|
||||
*/
|
||||
class MongoDbSessionHandler implements \SessionHandlerInterface
|
||||
{
|
||||
/**
|
||||
* @var \Mongo
|
||||
*/
|
||||
private $mongo;
|
||||
|
||||
/**
|
||||
* @var \MongoCollection
|
||||
*/
|
||||
private $collection;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \Mongo $mongo A "Mongo" instance
|
||||
* @param array $options An associative array of field options
|
||||
*
|
||||
* @throws \InvalidArgumentException When "database" or "collection" not provided
|
||||
*/
|
||||
public function __construct(\Mongo $mongo, array $options)
|
||||
{
|
||||
if (!isset($options['database']) || !isset($options['collection'])) {
|
||||
throw new \InvalidArgumentException('You must provide the "database" and "collection" option for MongoDBSessionHandler');
|
||||
}
|
||||
|
||||
$this->mongo = $mongo;
|
||||
|
||||
$this->options = array_merge(array(
|
||||
'id_field' => 'sess_id',
|
||||
'data_field' => 'sess_data',
|
||||
'time_field' => 'sess_time',
|
||||
), $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function open($savePath, $sessionName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function destroy($sessionId)
|
||||
{
|
||||
$this->getCollection()->remove(
|
||||
array($this->options['id_field'] => $sessionId),
|
||||
array('justOne' => true)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function gc($lifetime)
|
||||
{
|
||||
$time = new \MongoTimestamp(time() - $lifetime);
|
||||
|
||||
$this->getCollection()->remove(array(
|
||||
$this->options['time_field'] => array('$lt' => $time),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc]
|
||||
*/
|
||||
public function write($sessionId, $data)
|
||||
{
|
||||
$data = array(
|
||||
$this->options['id_field'] => $sessionId,
|
||||
$this->options['data_field'] => new \MongoBinData($data),
|
||||
$this->options['time_field'] => new \MongoTimestamp()
|
||||
);
|
||||
|
||||
$this->getCollection()->update(
|
||||
array($this->options['id_field'] => $sessionId),
|
||||
array('$set' => $data),
|
||||
array('upsert' => true)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function read($sessionId)
|
||||
{
|
||||
$dbData = $this->getCollection()->findOne(array(
|
||||
$this->options['id_field'] => $sessionId,
|
||||
));
|
||||
|
||||
return null === $dbData ? '' : $dbData[$this->options['data_field']]->bin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a "MongoCollection" instance
|
||||
*
|
||||
* @return \MongoCollection
|
||||
*/
|
||||
private function getCollection()
|
||||
{
|
||||
if (null === $this->collection) {
|
||||
$this->collection = $this->mongo->selectDB($this->options['database'])->selectCollection($this->options['collection']);
|
||||
}
|
||||
|
||||
return $this->collection;
|
||||
}
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler;
|
||||
|
||||
/**
|
||||
* @author Markus Bachmann <markus.bachmann@bachi.biz>
|
||||
*/
|
||||
class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
private static $mongo;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (class_exists('\Mongo')) {
|
||||
try {
|
||||
self::$mongo = new \Mongo();
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
if (null === self::$mongo) {
|
||||
$this->markTestSkipped('MongoDbSessionHandler requires the php "mongo" extension and a mongodb server on localhost');
|
||||
}
|
||||
|
||||
$this->options = array('database' => 'sf2-test', 'collection' => 'session-test');
|
||||
$this->options = array('database' => 'sf2-test', 'collection' => 'session-test');
|
||||
|
||||
$this->storage = new MongoDbSessionHandler(self::$mongo, $this->options);
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
self::$mongo->dropDB($this->options['database']);
|
||||
}
|
||||
|
||||
public function testOpenMethodAlwaysReturnTrue()
|
||||
{
|
||||
$this->assertTrue($this->storage->open('test', 'test'), 'The "open" method should always return true');
|
||||
}
|
||||
|
||||
public function testCloseMethodAlwaysReturnTrue()
|
||||
{
|
||||
$this->assertTrue($this->storage->close(), 'The "close" method should always return true');
|
||||
}
|
||||
|
||||
public function testWrite()
|
||||
{
|
||||
$this->assertTrue($this->storage->write('foo', 'bar'));
|
||||
$this->assertEquals('bar', $this->storage->read('foo'));
|
||||
}
|
||||
|
||||
public function testReplaceSessionData()
|
||||
{
|
||||
$this->storage->write('foo', 'bar');
|
||||
$this->storage->write('foo', 'foobar');
|
||||
|
||||
$coll = self::$mongo->selectDB($this->options['database'])->selectCollection($this->options['collection']);
|
||||
|
||||
$this->assertEquals('foobar', $this->storage->read('foo'));
|
||||
$this->assertEquals(1, $coll->find(array('sess_id' => 'foo'))->count());
|
||||
}
|
||||
|
||||
public function testDestroy()
|
||||
{
|
||||
$this->storage->write('foo', 'bar');
|
||||
$this->storage->destroy('foo');
|
||||
|
||||
$this->assertEquals('', $this->storage->read('foo'));
|
||||
}
|
||||
|
||||
public function testGc()
|
||||
{
|
||||
$this->storage->write('foo', 'bar');
|
||||
$this->storage->write('bar', 'foo');
|
||||
|
||||
$coll = self::$mongo->selectDB($this->options['database'])->selectCollection($this->options['collection']);
|
||||
|
||||
$this->assertEquals(2, $coll->count());
|
||||
$this->storage->gc(-1);
|
||||
$this->assertEquals(0, $coll->count());
|
||||
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user