merged branch drak/session_detect (PR #7571)
This PR was squashed before being merged into the master branch (closes #7571).
Discussion
----------
[2.3] Handle PHP sessions started outside of Symfony
| Q | A
| ------------- | ---
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets |
| License | MIT
| Doc PR | symfony/symfony-docs#2474
This PR brings a way to allow Symfony2 to manage a session started outside of Symfony in such a way that quite explicit. It also introduces more robust detection of previously started sessions under PHP 5.3 and supports real session status detection under PHP 5.4
Commits
-------
df99902
[2.3] Handle PHP sessions started outside of Symfony
This commit is contained in:
commit
7bf8933662
|
@ -318,6 +318,7 @@ class FrameworkExtension extends Extension
|
|||
if (null == $config['handler_id']) {
|
||||
// Set the handler class to be null
|
||||
$container->getDefinition('session.storage.native')->replaceArgument(1, null);
|
||||
$container->getDefinition('session.storage.php_bridge')->replaceArgument(1, null);
|
||||
} else {
|
||||
$container->setAlias('session.handler', $config['handler_id']);
|
||||
}
|
||||
|
@ -327,6 +328,7 @@ class FrameworkExtension extends Extension
|
|||
$this->addClassesToCompile(array(
|
||||
'Symfony\\Bundle\\FrameworkBundle\\EventListener\\SessionListener',
|
||||
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage',
|
||||
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\PhpBridgeSessionStorage',
|
||||
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeFileSessionHandler',
|
||||
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Proxy\\AbstractProxy',
|
||||
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Proxy\\SessionHandlerProxy',
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
<parameter key="session.flashbag.class">Symfony\Component\HttpFoundation\Session\Flash\FlashBag</parameter>
|
||||
<parameter key="session.attribute_bag.class">Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag</parameter>
|
||||
<parameter key="session.storage.native.class">Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage</parameter>
|
||||
<parameter key="session.storage.php_bridge.class">Symfony\Component\HttpFoundation\Session\Storage\PhpBridgeSessionStorage</parameter>
|
||||
<parameter key="session.storage.mock_file.class">Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage</parameter>
|
||||
<parameter key="session.handler.native_file.class">Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler</parameter>
|
||||
<parameter key="session_listener.class">Symfony\Bundle\FrameworkBundle\EventListener\SessionListener</parameter>
|
||||
|
@ -26,6 +27,10 @@
|
|||
<argument type="service" id="session.handler" />
|
||||
</service>
|
||||
|
||||
<service id="session.storage.php_bridge" class="%session.storage.php_bridge.class%">
|
||||
<argument type="service" id="session.handler" />
|
||||
</service>
|
||||
|
||||
<service id="session.flash_bag" class="%session.flashbag.class%" public="false" />
|
||||
|
||||
<service id="session.attribute_bag" class="%session.attribute_bag.class%" public="false" />
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
namespace Symfony\Component\HttpFoundation\Session\Storage;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
|
||||
|
@ -91,9 +92,9 @@ class NativeSessionStorage implements SessionStorageInterface
|
|||
* upload_progress.min-freq, "1"
|
||||
* url_rewriter.tags, "a=href,area=href,frame=src,form=,fieldset="
|
||||
*
|
||||
* @param array $options Session configuration options.
|
||||
* @param object $handler SessionHandlerInterface.
|
||||
* @param MetadataBag $metaBag MetadataBag.
|
||||
* @param array $options Session configuration options.
|
||||
* @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $handler
|
||||
* @param MetadataBag $metaBag MetadataBag.
|
||||
*/
|
||||
public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null)
|
||||
{
|
||||
|
@ -130,27 +131,28 @@ class NativeSessionStorage implements SessionStorageInterface
|
|||
return true;
|
||||
}
|
||||
|
||||
// catch condition where session was started automatically by PHP
|
||||
if (!$this->started && !$this->closed && $this->saveHandler->isActive()
|
||||
&& $this->saveHandler->isSessionHandlerInterface()) {
|
||||
$this->loadSession();
|
||||
if (version_compare(phpversion(), '5.4.0', '>=') && \PHP_SESSION_ACTIVE === session_status()) {
|
||||
throw new \RuntimeException('Failed to start the session: already started by PHP.');
|
||||
}
|
||||
|
||||
return true;
|
||||
if (version_compare(phpversion(), '5.4.0', '<') && isset($_SESSION) && session_id()) {
|
||||
// not 100% fool-proof, but is the most reliable way to determine if a session is active in PHP 5.3
|
||||
throw new \RuntimeException('Failed to start the session: already started by PHP ($_SESSION is set).');
|
||||
}
|
||||
|
||||
if (ini_get('session.use_cookies') && headers_sent()) {
|
||||
throw new \RuntimeException('Failed to start the session because headers have already been sent.');
|
||||
}
|
||||
|
||||
// start the session
|
||||
// ok to try and start the session
|
||||
if (!session_start()) {
|
||||
throw new \RuntimeException('Failed to start the session');
|
||||
}
|
||||
|
||||
$this->loadSession();
|
||||
|
||||
if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
|
||||
$this->saveHandler->setActive(false);
|
||||
// This condition matches only PHP 5.3 with internal save handlers
|
||||
$this->saveHandler->setActive(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -215,7 +217,8 @@ class NativeSessionStorage implements SessionStorageInterface
|
|||
{
|
||||
session_write_close();
|
||||
|
||||
if (!$this->saveHandler->isWrapper() && !$this->getSaveHandler()->isSessionHandlerInterface()) {
|
||||
if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
|
||||
// This condition matches only PHP 5.3 with internal save handlers
|
||||
$this->saveHandler->setActive(false);
|
||||
}
|
||||
|
||||
|
@ -329,7 +332,7 @@ class NativeSessionStorage implements SessionStorageInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* Registers save handler as a PHP session handler.
|
||||
* Registers session save handler as a PHP session handler.
|
||||
*
|
||||
* To use internal PHP session save handlers, override this method using ini_set with
|
||||
* session.save_handler and session.save_path e.g.
|
||||
|
@ -337,21 +340,35 @@ class NativeSessionStorage implements SessionStorageInterface
|
|||
* ini_set('session.save_handler', 'files');
|
||||
* ini_set('session.save_path', /tmp');
|
||||
*
|
||||
* or pass in a NativeSessionHandler instance which configures session.save_handler in the
|
||||
* constructor, for a template see NativeFileSessionHandler or use handlers in
|
||||
* composer package drak/native-session
|
||||
*
|
||||
* @see http://php.net/session-set-save-handler
|
||||
* @see http://php.net/sessionhandlerinterface
|
||||
* @see http://php.net/sessionhandler
|
||||
* @see http://github.com/drak/NativeSession
|
||||
*
|
||||
* @param object $saveHandler Default null means NativeProxy.
|
||||
* @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $saveHandler
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setSaveHandler($saveHandler = null)
|
||||
{
|
||||
// Wrap $saveHandler in proxy
|
||||
if (!$saveHandler instanceof AbstractProxy &&
|
||||
!$saveHandler instanceof NativeSessionHandler &&
|
||||
!$saveHandler instanceof \SessionHandlerInterface &&
|
||||
null !== $saveHandler) {
|
||||
throw new \InvalidArgumentException('Must be instance of AbstractProxy or NativeSessionHandler; implement \SessionHandlerInterface; or be null.');
|
||||
}
|
||||
|
||||
// Wrap $saveHandler in proxy and prevent double wrapping of proxy
|
||||
if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) {
|
||||
$saveHandler = new SessionHandlerProxy($saveHandler);
|
||||
} elseif (!$saveHandler instanceof AbstractProxy) {
|
||||
$saveHandler = new NativeProxy();
|
||||
$saveHandler = version_compare(phpversion(), '5.4.0', '>=') ?
|
||||
new SessionHandlerProxy(new \SessionHandler()) : new NativeProxy();
|
||||
}
|
||||
|
||||
$this->saveHandler = $saveHandler;
|
||||
|
||||
if ($this->saveHandler instanceof \SessionHandlerInterface) {
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
<?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;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
|
||||
|
||||
/**
|
||||
* Allows session to be started by PHP and managed by Symfony2
|
||||
*
|
||||
* @author Drak <drak@zikula.org>
|
||||
*/
|
||||
class PhpBridgeSessionStorage extends NativeSessionStorage
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $handler
|
||||
* @param MetadataBag $metaBag MetadataBag
|
||||
*/
|
||||
public function __construct($handler = null, MetadataBag $metaBag = null)
|
||||
{
|
||||
$this->setMetadataBag($metaBag);
|
||||
$this->setSaveHandler($handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function start()
|
||||
{
|
||||
if ($this->started && !$this->closed) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->loadSession();
|
||||
if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
|
||||
// This condition matches only PHP 5.3 + internal save handlers
|
||||
$this->saveHandler->setActive(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
// clear out the bags and nothing else that may be set
|
||||
// since the purpose of this driver is to share a handler
|
||||
foreach ($this->bags as $bag) {
|
||||
$bag->clear();
|
||||
}
|
||||
|
||||
// reconnect the bags to the session
|
||||
$this->loadSession();
|
||||
}
|
||||
}
|
|
@ -72,16 +72,31 @@ abstract class AbstractProxy
|
|||
*/
|
||||
public function isActive()
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4.0', '>=')) {
|
||||
return $this->active = \PHP_SESSION_ACTIVE === session_status();
|
||||
}
|
||||
|
||||
return $this->active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the active flag.
|
||||
*
|
||||
* Has no effect under PHP 5.4+ as status is detected
|
||||
* automatically in isActive()
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param Boolean $flag
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function setActive($flag)
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4.0', '>=')) {
|
||||
throw new \LogicException('This method is disabled in PHP 5.4.0+');
|
||||
}
|
||||
|
||||
$this->active = (bool) $flag;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,11 +11,15 @@
|
|||
|
||||
namespace Symfony\Component\HttpFoundation\Tests\Session\Storage;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler;
|
||||
use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
|
||||
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
|
||||
|
||||
/**
|
||||
* Test class for NativeSessionStorage.
|
||||
|
@ -28,6 +32,28 @@ use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
|
|||
*/
|
||||
class NativeSessionStorageTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
private $savePath;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
ini_set('session.save_handler', 'files');
|
||||
ini_set('session.save_path', $this->savePath = sys_get_temp_dir().'/sf2test');
|
||||
if (!is_dir($this->savePath)) {
|
||||
mkdir($this->savePath);
|
||||
}
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
session_write_close();
|
||||
array_map('unlink', glob($this->savePath.'/*'));
|
||||
if (is_dir($this->savePath)) {
|
||||
rmdir($this->savePath);
|
||||
}
|
||||
|
||||
$this->savePath = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
*
|
||||
|
@ -75,7 +101,6 @@ class NativeSessionStorageTest extends \PHPUnit_Framework_TestCase
|
|||
$storage->regenerate();
|
||||
$this->assertNotEquals($id, $storage->getId());
|
||||
$this->assertEquals(7, $storage->getBag('attributes')->get('lucky'));
|
||||
|
||||
}
|
||||
|
||||
public function testRegenerateDestroy()
|
||||
|
@ -126,32 +151,132 @@ class NativeSessionStorageTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals($options, $gco);
|
||||
}
|
||||
|
||||
public function testSetSaveHandler()
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testSetSaveHandlerException()
|
||||
{
|
||||
$storage = $this->getStorage();
|
||||
$storage->setSaveHandler(new \StdClass());
|
||||
$storage->setSaveHandler(new \StdClass);
|
||||
}
|
||||
|
||||
public function testSetSaveHandler53()
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4.0', '>=')) {
|
||||
$this->markTestSkipped('Test skipped, for PHP 5.3 only.');
|
||||
}
|
||||
|
||||
ini_set('session.save_handler', 'files');
|
||||
$storage = $this->getStorage();
|
||||
$storage->setSaveHandler();
|
||||
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler());
|
||||
$storage->setSaveHandler(null);
|
||||
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler());
|
||||
$storage->setSaveHandler(new NativeSessionHandler());
|
||||
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler());
|
||||
$storage->setSaveHandler(new SessionHandlerProxy(new SessionHandler()));
|
||||
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
|
||||
$storage->setSaveHandler(new SessionHandler());
|
||||
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
|
||||
$storage->setSaveHandler(new NativeProxy());
|
||||
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler());
|
||||
}
|
||||
|
||||
public function testSetSaveHandlerPHP53()
|
||||
public function testSetSaveHandler54()
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4.0', '<')) {
|
||||
$this->markTestSkipped('Test skipped, for PHP 5.4 only.');
|
||||
}
|
||||
|
||||
ini_set('session.save_handler', 'files');
|
||||
$storage = $this->getStorage();
|
||||
$storage->setSaveHandler();
|
||||
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
|
||||
$storage->setSaveHandler(null);
|
||||
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
|
||||
$storage->setSaveHandler(new SessionHandlerProxy(new NativeSessionHandler()));
|
||||
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
|
||||
$storage->setSaveHandler(new NativeSessionHandler());
|
||||
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
|
||||
$storage->setSaveHandler(new SessionHandlerProxy(new SessionHandler()));
|
||||
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
|
||||
$storage->setSaveHandler(new SessionHandler());
|
||||
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
*/
|
||||
public function testStartedOutside53()
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4.0', '>=')) {
|
||||
$this->markTestSkipped('Test skipped, for PHP 5.3 only.');
|
||||
}
|
||||
|
||||
$storage = $this->getStorage();
|
||||
$storage->setSaveHandler(new NativeFileSessionHandler());
|
||||
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy', $storage->getSaveHandler());
|
||||
|
||||
$this->assertFalse(isset($_SESSION));
|
||||
|
||||
session_start();
|
||||
$this->assertTrue(isset($_SESSION));
|
||||
// PHP session might have started, but the storage driver has not, so false is correct here
|
||||
$this->assertFalse($storage->isStarted());
|
||||
|
||||
$key = $storage->getMetadataBag()->getStorageKey();
|
||||
$this->assertFalse(isset($_SESSION[$key]));
|
||||
$storage->start();
|
||||
}
|
||||
|
||||
public function testSetSaveHandlerPHP54()
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
*/
|
||||
public function testCanStartOutside54()
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4.0', '<')) {
|
||||
$this->markTestSkipped('Test skipped, for PHP 5.4+ only.');
|
||||
$this->markTestSkipped('Test skipped, for PHP 5.4 only.');
|
||||
}
|
||||
|
||||
$storage = $this->getStorage();
|
||||
$storage->setSaveHandler(new NullSessionHandler());
|
||||
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
|
||||
|
||||
$this->assertFalse(isset($_SESSION));
|
||||
$this->assertFalse($storage->getSaveHandler()->isActive());
|
||||
$this->assertFalse($storage->isStarted());
|
||||
|
||||
session_start();
|
||||
$this->assertTrue(isset($_SESSION));
|
||||
$this->assertTrue($storage->getSaveHandler()->isActive());
|
||||
// PHP session might have started, but the storage driver has not, so false is correct here
|
||||
$this->assertFalse($storage->isStarted());
|
||||
|
||||
$key = $storage->getMetadataBag()->getStorageKey();
|
||||
$this->assertFalse(isset($_SESSION[$key]));
|
||||
$storage->start();
|
||||
}
|
||||
}
|
||||
|
||||
class SessionHandler implements \SessionHandlerInterface
|
||||
{
|
||||
public function open($savePath, $sessionName)
|
||||
{
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
}
|
||||
|
||||
public function read($id)
|
||||
{
|
||||
}
|
||||
|
||||
public function write($id, $data)
|
||||
{
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
}
|
||||
|
||||
public function gc($maxlifetime)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
<?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;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\PhpBridgeSessionStorage;
|
||||
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
|
||||
|
||||
/**
|
||||
* Test class for PhpSessionStorage.
|
||||
*
|
||||
* @author Drak <drak@zikula.org>
|
||||
*
|
||||
* These tests require separate processes.
|
||||
*
|
||||
* @runTestsInSeparateProcesses
|
||||
*/
|
||||
class PhpSessionStorageTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
private $savePath;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
ini_set('session.save_handler', 'files');
|
||||
ini_set('session.save_path', $this->savePath = sys_get_temp_dir().'/sf2test');
|
||||
if (!is_dir($this->savePath)) {
|
||||
mkdir($this->savePath);
|
||||
}
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
session_write_close();
|
||||
array_map('unlink', glob($this->savePath.'/*'));
|
||||
if (is_dir($this->savePath)) {
|
||||
rmdir($this->savePath);
|
||||
}
|
||||
|
||||
$this->savePath = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PhpBridgeSessionStorage
|
||||
*/
|
||||
protected function getStorage()
|
||||
{
|
||||
$storage = new PhpBridgeSessionStorage();
|
||||
$storage->registerBag(new AttributeBag);
|
||||
|
||||
return $storage;
|
||||
}
|
||||
|
||||
public function testPhpSession53()
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4.0', '>=')) {
|
||||
$this->markTestSkipped('Test skipped, for PHP 5.3 only.');
|
||||
}
|
||||
|
||||
$storage = $this->getStorage();
|
||||
|
||||
$this->assertFalse(isset($_SESSION));
|
||||
$this->assertFalse($storage->getSaveHandler()->isActive());
|
||||
|
||||
session_start();
|
||||
$this->assertTrue(isset($_SESSION));
|
||||
// in PHP 5.3 we cannot reliably tell if a session has started
|
||||
$this->assertFalse($storage->getSaveHandler()->isActive());
|
||||
// PHP session might have started, but the storage driver has not, so false is correct here
|
||||
$this->assertFalse($storage->isStarted());
|
||||
|
||||
$key = $storage->getMetadataBag()->getStorageKey();
|
||||
$this->assertFalse(isset($_SESSION[$key]));
|
||||
$storage->start();
|
||||
$this->assertTrue(isset($_SESSION[$key]));
|
||||
}
|
||||
|
||||
public function testPhpSession54()
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4.0', '<')) {
|
||||
$this->markTestSkipped('Test skipped, for PHP 5.4 only.');
|
||||
}
|
||||
|
||||
$storage = $this->getStorage();
|
||||
|
||||
$this->assertFalse(isset($_SESSION));
|
||||
$this->assertFalse($storage->getSaveHandler()->isActive());
|
||||
$this->assertFalse($storage->isStarted());
|
||||
|
||||
session_start();
|
||||
$this->assertTrue(isset($_SESSION));
|
||||
// in PHP 5.4 we can reliably detect a session started
|
||||
$this->assertTrue($storage->getSaveHandler()->isActive());
|
||||
// PHP session might have started, but the storage driver has not, so false is correct here
|
||||
$this->assertFalse($storage->isStarted());
|
||||
|
||||
$key = $storage->getMetadataBag()->getStorageKey();
|
||||
$this->assertFalse(isset($_SESSION[$key]));
|
||||
$storage->start();
|
||||
$this->assertTrue(isset($_SESSION[$key]));
|
||||
}
|
||||
|
||||
public function testClear()
|
||||
{
|
||||
$storage = $this->getStorage();
|
||||
session_start();
|
||||
$_SESSION['drak'] = 'loves symfony';
|
||||
$storage->getBag('attributes')->set('symfony', 'greatness');
|
||||
$key = $storage->getBag('attributes')->getStorageKey();
|
||||
$this->assertEquals($_SESSION[$key], array('symfony' => 'greatness'));
|
||||
$this->assertEquals($_SESSION['drak'], 'loves symfony');
|
||||
$storage->clear();
|
||||
$this->assertEquals($_SESSION[$key], array());
|
||||
$this->assertEquals($_SESSION['drak'], 'loves symfony');
|
||||
}
|
||||
}
|
|
@ -86,19 +86,54 @@ class AbstractProxyTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertFalse($this->proxy->isWrapper());
|
||||
}
|
||||
|
||||
public function testIsActive()
|
||||
public function testIsActivePhp53()
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4.0', '>=')) {
|
||||
$this->markTestSkipped('Test skipped, for PHP 5.3 only.');
|
||||
}
|
||||
|
||||
$this->assertFalse($this->proxy->isActive());
|
||||
}
|
||||
|
||||
public function testSetActive()
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testIsActivePhp54()
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4.0', '<')) {
|
||||
$this->markTestSkipped('Test skipped, for PHP 5.4 only.');
|
||||
}
|
||||
|
||||
$this->assertFalse($this->proxy->isActive());
|
||||
session_start();
|
||||
$this->assertTrue($this->proxy->isActive());
|
||||
}
|
||||
|
||||
public function testSetActivePhp53()
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4.0', '>=')) {
|
||||
$this->markTestSkipped('Test skipped, for PHP 5.3 only.');
|
||||
}
|
||||
|
||||
$this->proxy->setActive(true);
|
||||
$this->assertTrue($this->proxy->isActive());
|
||||
$this->proxy->setActive(false);
|
||||
$this->assertFalse($this->proxy->isActive());
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @expectedException \LogicException
|
||||
*/
|
||||
public function testSetActivePhp54()
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4.0', '<')) {
|
||||
$this->markTestSkipped('Test skipped, for PHP 5.4 only.');
|
||||
}
|
||||
|
||||
$this->proxy->setActive(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
|
@ -113,12 +148,30 @@ class AbstractProxyTest extends \PHPUnit_Framework_TestCase
|
|||
/**
|
||||
* @expectedException \LogicException
|
||||
*/
|
||||
public function testNameException()
|
||||
public function testNameExceptionPhp53()
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4.0', '>=')) {
|
||||
$this->markTestSkipped('Test skipped, for PHP 5.3 only.');
|
||||
}
|
||||
|
||||
$this->proxy->setActive(true);
|
||||
$this->proxy->setName('foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @expectedException \LogicException
|
||||
*/
|
||||
public function testNameExceptionPhp54()
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4.0', '<')) {
|
||||
$this->markTestSkipped('Test skipped, for PHP 5.4 only.');
|
||||
}
|
||||
|
||||
session_start();
|
||||
$this->proxy->setName('foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
|
@ -133,9 +186,27 @@ class AbstractProxyTest extends \PHPUnit_Framework_TestCase
|
|||
/**
|
||||
* @expectedException \LogicException
|
||||
*/
|
||||
public function testIdException()
|
||||
public function testIdExceptionPhp53()
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4.0', '>=')) {
|
||||
$this->markTestSkipped('Test skipped, for PHP 5.3 only.');
|
||||
}
|
||||
|
||||
$this->proxy->setActive(true);
|
||||
$this->proxy->setId('foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @expectedException \LogicException
|
||||
*/
|
||||
public function testIdExceptionPhp54()
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4.0', '<')) {
|
||||
$this->markTestSkipped('Test skipped, for PHP 5.4 only.');
|
||||
}
|
||||
|
||||
session_start();
|
||||
$this->proxy->setId('foo');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
|
|||
class SessionHandlerProxyTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var PHPUnit_Framework_MockObject_Matcher
|
||||
* @var \PHPUnit_Framework_MockObject_Matcher
|
||||
*/
|
||||
private $mock;
|
||||
|
||||
|
@ -52,7 +52,11 @@ class SessionHandlerProxyTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
$this->assertFalse($this->proxy->isActive());
|
||||
$this->proxy->open('name', 'id');
|
||||
$this->assertTrue($this->proxy->isActive());
|
||||
if (version_compare(phpversion(), '5.4.0', '<')) {
|
||||
$this->assertTrue($this->proxy->isActive());
|
||||
} else {
|
||||
$this->assertFalse($this->proxy->isActive());
|
||||
}
|
||||
}
|
||||
|
||||
public function testOpenFalse()
|
||||
|
|
Reference in New Issue