Merge branch '4.4' into 5.2
* 4.4: [HttpFoundation] Fix return types of SessionHandler::gc() [Cache] Support decorated Dbal drivers in PdoAdapter [VarDumper] Support for intersection types
This commit is contained in:
commit
92d0594cd5
2
.github/patch-types.php
vendored
2
.github/patch-types.php
vendored
@ -16,6 +16,7 @@ foreach ($loader->getClassMap() as $class => $file) {
|
|||||||
case false !== strpos($file = realpath($file), '/vendor/'):
|
case false !== strpos($file = realpath($file), '/vendor/'):
|
||||||
case false !== strpos($file, '/src/Symfony/Bridge/PhpUnit/'):
|
case false !== strpos($file, '/src/Symfony/Bridge/PhpUnit/'):
|
||||||
case false !== strpos($file, '/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Article.php'):
|
case false !== strpos($file, '/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Article.php'):
|
||||||
|
case false !== strpos($file, '/src/Symfony/Component/Cache/Tests/Fixtures/DriverWrapper.php'):
|
||||||
case false !== strpos($file, '/src/Symfony/Component/Config/Tests/Fixtures/BadFileName.php'):
|
case false !== strpos($file, '/src/Symfony/Component/Config/Tests/Fixtures/BadFileName.php'):
|
||||||
case false !== strpos($file, '/src/Symfony/Component/Config/Tests/Fixtures/BadParent.php'):
|
case false !== strpos($file, '/src/Symfony/Component/Config/Tests/Fixtures/BadParent.php'):
|
||||||
case false !== strpos($file, '/src/Symfony/Component/Config/Tests/Fixtures/ParseError.php'):
|
case false !== strpos($file, '/src/Symfony/Component/Config/Tests/Fixtures/ParseError.php'):
|
||||||
@ -31,6 +32,7 @@ foreach ($loader->getClassMap() as $class => $file) {
|
|||||||
case false !== strpos($file, '/src/Symfony/Component/PropertyInfo/Tests/Fixtures/ParentDummy.php'):
|
case false !== strpos($file, '/src/Symfony/Component/PropertyInfo/Tests/Fixtures/ParentDummy.php'):
|
||||||
case false !== strpos($file, '/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ObjectOuter.php'):
|
case false !== strpos($file, '/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ObjectOuter.php'):
|
||||||
case false !== strpos($file, '/src/Symfony/Component/VarDumper/Tests/Fixtures/NotLoadableClass.php'):
|
case false !== strpos($file, '/src/Symfony/Component/VarDumper/Tests/Fixtures/NotLoadableClass.php'):
|
||||||
|
case false !== strpos($file, '/src/Symfony/Component/VarDumper/Tests/Fixtures/ReflectionIntersectionTypeFixture.php'):
|
||||||
continue 2;
|
continue 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,6 +473,15 @@ class PdoAdapter extends AbstractAdapter implements PruneableInterface
|
|||||||
case $driver instanceof \Doctrine\DBAL\Driver\PDO\SQLSrv\Driver:
|
case $driver instanceof \Doctrine\DBAL\Driver\PDO\SQLSrv\Driver:
|
||||||
$this->driver = 'sqlsrv';
|
$this->driver = 'sqlsrv';
|
||||||
break;
|
break;
|
||||||
|
case $driver instanceof \Doctrine\DBAL\Driver:
|
||||||
|
$this->driver = [
|
||||||
|
'mssql' => 'sqlsrv',
|
||||||
|
'oracle' => 'oci',
|
||||||
|
'postgresql' => 'pgsql',
|
||||||
|
'sqlite' => 'sqlite',
|
||||||
|
'mysql' => 'mysql',
|
||||||
|
][$driver->getDatabasePlatform()->getName()] ?? \get_class($driver);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
$this->driver = \get_class($driver);
|
$this->driver = \get_class($driver);
|
||||||
break;
|
break;
|
||||||
|
@ -11,13 +11,16 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Configuration;
|
||||||
use Doctrine\DBAL\Connection;
|
use Doctrine\DBAL\Connection;
|
||||||
use Doctrine\DBAL\Driver\AbstractMySQLDriver;
|
use Doctrine\DBAL\Driver\AbstractMySQLDriver;
|
||||||
|
use Doctrine\DBAL\Driver\Middleware;
|
||||||
use Doctrine\DBAL\DriverManager;
|
use Doctrine\DBAL\DriverManager;
|
||||||
use Doctrine\DBAL\Schema\Schema;
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
use PHPUnit\Framework\SkippedTestSuiteError;
|
use PHPUnit\Framework\SkippedTestSuiteError;
|
||||||
use Psr\Cache\CacheItemPoolInterface;
|
use Psr\Cache\CacheItemPoolInterface;
|
||||||
use Symfony\Component\Cache\Adapter\PdoAdapter;
|
use Symfony\Component\Cache\Adapter\PdoAdapter;
|
||||||
|
use Symfony\Component\Cache\Tests\Fixtures\DriverWrapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @group time-sensitive
|
* @group time-sensitive
|
||||||
@ -47,6 +50,31 @@ class PdoDbalAdapterTest extends AdapterTestCase
|
|||||||
return new PdoAdapter(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]), '', $defaultLifetime);
|
return new PdoAdapter(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]), '', $defaultLifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testConfigureSchemaDecoratedDbalDriver()
|
||||||
|
{
|
||||||
|
$connection = DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]);
|
||||||
|
if (!interface_exists(Middleware::class)) {
|
||||||
|
$this->markTestSkipped('doctrine/dbal v2 does not support custom drivers using middleware');
|
||||||
|
}
|
||||||
|
|
||||||
|
$middleware = $this->createMock(Middleware::class);
|
||||||
|
$middleware
|
||||||
|
->method('wrap')
|
||||||
|
->willReturn(new DriverWrapper($connection->getDriver()));
|
||||||
|
|
||||||
|
$config = new Configuration();
|
||||||
|
$config->setMiddlewares([$middleware]);
|
||||||
|
|
||||||
|
$connection = DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile], $config);
|
||||||
|
|
||||||
|
$adapter = new PdoAdapter($connection);
|
||||||
|
$adapter->createTable();
|
||||||
|
|
||||||
|
$item = $adapter->getItem('key');
|
||||||
|
$item->set('value');
|
||||||
|
$this->assertTrue($adapter->save($item));
|
||||||
|
}
|
||||||
|
|
||||||
public function testConfigureSchema()
|
public function testConfigureSchema()
|
||||||
{
|
{
|
||||||
$connection = DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]);
|
$connection = DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]);
|
||||||
|
48
src/Symfony/Component/Cache/Tests/Fixtures/DriverWrapper.php
Normal file
48
src/Symfony/Component/Cache/Tests/Fixtures/DriverWrapper.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?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\Cache\Tests\Fixtures;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Connection;
|
||||||
|
use Doctrine\DBAL\Driver;
|
||||||
|
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||||
|
use Doctrine\DBAL\Schema\AbstractSchemaManager;
|
||||||
|
|
||||||
|
class DriverWrapper implements Driver
|
||||||
|
{
|
||||||
|
/** @var Driver */
|
||||||
|
private $driver;
|
||||||
|
|
||||||
|
public function __construct(Driver $driver)
|
||||||
|
{
|
||||||
|
$this->driver = $driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function connect(array $params, $username = null, $password = null, array $driverOptions = []): Driver\Connection
|
||||||
|
{
|
||||||
|
return $this->driver->connect($params, $username, $password, $driverOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDatabasePlatform(): AbstractPlatform
|
||||||
|
{
|
||||||
|
return $this->driver->getDatabasePlatform();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSchemaManager(Connection $conn, AbstractPlatform $platform): AbstractSchemaManager
|
||||||
|
{
|
||||||
|
return $this->driver->getSchemaManager($conn, $platform);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getExceptionConverter(): Driver\API\ExceptionConverter
|
||||||
|
{
|
||||||
|
return $this->driver->getExceptionConverter();
|
||||||
|
}
|
||||||
|
}
|
@ -99,12 +99,13 @@ class MemcachedSessionHandler extends AbstractSessionHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return int|false
|
||||||
*/
|
*/
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function gc($maxlifetime)
|
public function gc($maxlifetime)
|
||||||
{
|
{
|
||||||
// not required here because memcached will auto expire the records anyhow.
|
// not required here because memcached will auto expire the records anyhow.
|
||||||
return true;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,7 +63,7 @@ class MigratingSessionHandler implements \SessionHandlerInterface, \SessionUpdat
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return int|false
|
||||||
*/
|
*/
|
||||||
#[\ReturnTypeWillChange]
|
#[\ReturnTypeWillChange]
|
||||||
public function gc($maxlifetime)
|
public function gc($maxlifetime)
|
||||||
|
@ -100,15 +100,14 @@ class MongoDbSessionHandler extends AbstractSessionHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return int|false
|
||||||
*/
|
*/
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function gc($maxlifetime)
|
public function gc($maxlifetime)
|
||||||
{
|
{
|
||||||
$this->getCollection()->deleteMany([
|
return $this->getCollection()->deleteMany([
|
||||||
$this->options['expiry_field'] => ['$lt' => new \MongoDB\BSON\UTCDateTime()],
|
$this->options['expiry_field'] => ['$lt' => new \MongoDB\BSON\UTCDateTime()],
|
||||||
]);
|
])->getDeletedCount();
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,11 +70,11 @@ class NullSessionHandler extends AbstractSessionHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return int|false
|
||||||
*/
|
*/
|
||||||
#[\ReturnTypeWillChange]
|
#[\ReturnTypeWillChange]
|
||||||
public function gc($maxlifetime)
|
public function gc($maxlifetime)
|
||||||
{
|
{
|
||||||
return true;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,7 +290,7 @@ class PdoSessionHandler extends AbstractSessionHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return int|false
|
||||||
*/
|
*/
|
||||||
#[\ReturnTypeWillChange]
|
#[\ReturnTypeWillChange]
|
||||||
public function gc($maxlifetime)
|
public function gc($maxlifetime)
|
||||||
@ -299,7 +299,7 @@ class PdoSessionHandler extends AbstractSessionHandler
|
|||||||
// This way, pruning expired sessions does not block them from being started while the current session is used.
|
// This way, pruning expired sessions does not block them from being started while the current session is used.
|
||||||
$this->gcCalled = true;
|
$this->gcCalled = true;
|
||||||
|
|
||||||
return true;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -116,10 +116,13 @@ class RedisSessionHandler extends AbstractSessionHandler
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @return int|false
|
||||||
*/
|
*/
|
||||||
public function gc($maxlifetime): bool
|
#[\ReturnTypeWillChange]
|
||||||
|
public function gc($maxlifetime)
|
||||||
{
|
{
|
||||||
return true;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -114,7 +114,7 @@ abstract class AbstractRedisSessionHandlerTestCase extends TestCase
|
|||||||
|
|
||||||
public function testGcSession()
|
public function testGcSession()
|
||||||
{
|
{
|
||||||
$this->assertTrue($this->storage->gc(123));
|
$this->assertIsInt($this->storage->gc(123));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testUpdateTimestamp()
|
public function testUpdateTimestamp()
|
||||||
|
@ -121,11 +121,12 @@ class TestSessionHandler extends AbstractSessionHandler
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function gc($maxLifetime): bool
|
#[\ReturnTypeWillChange]
|
||||||
|
public function gc($maxLifetime)
|
||||||
{
|
{
|
||||||
echo __FUNCTION__, "\n";
|
echo __FUNCTION__, "\n";
|
||||||
|
|
||||||
return true;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function doRead($sessionId): string
|
protected function doRead($sessionId): string
|
||||||
|
@ -113,7 +113,7 @@ class MemcachedSessionHandlerTest extends TestCase
|
|||||||
|
|
||||||
public function testGcSession()
|
public function testGcSession()
|
||||||
{
|
{
|
||||||
$this->assertTrue($this->storage->gc(123));
|
$this->assertIsInt($this->storage->gc(123));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -184,9 +184,14 @@ class MongoDbSessionHandlerTest extends TestCase
|
|||||||
->willReturnCallback(function ($criteria) {
|
->willReturnCallback(function ($criteria) {
|
||||||
$this->assertInstanceOf(\MongoDB\BSON\UTCDateTime::class, $criteria[$this->options['expiry_field']]['$lt']);
|
$this->assertInstanceOf(\MongoDB\BSON\UTCDateTime::class, $criteria[$this->options['expiry_field']]['$lt']);
|
||||||
$this->assertGreaterThanOrEqual(time() - 1, round((string) $criteria[$this->options['expiry_field']]['$lt'] / 1000));
|
$this->assertGreaterThanOrEqual(time() - 1, round((string) $criteria[$this->options['expiry_field']]['$lt'] / 1000));
|
||||||
|
|
||||||
|
$result = $this->createMock(\MongoDB\DeleteResult::class);
|
||||||
|
$result->method('getDeletedCount')->willReturn(42);
|
||||||
|
|
||||||
|
return $result;
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->assertTrue($this->storage->gc(1));
|
$this->assertSame(42, $this->storage->gc(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetConnection()
|
public function testGetConnection()
|
||||||
|
@ -102,7 +102,7 @@ class ReflectionCaster
|
|||||||
$prefix.'allowsNull' => $c->allowsNull(),
|
$prefix.'allowsNull' => $c->allowsNull(),
|
||||||
$prefix.'isBuiltin' => $c->isBuiltin(),
|
$prefix.'isBuiltin' => $c->isBuiltin(),
|
||||||
];
|
];
|
||||||
} elseif ($c instanceof \ReflectionUnionType) {
|
} elseif ($c instanceof \ReflectionUnionType || $c instanceof \ReflectionIntersectionType) {
|
||||||
$a[$prefix.'allowsNull'] = $c->allowsNull();
|
$a[$prefix.'allowsNull'] = $c->allowsNull();
|
||||||
self::addMap($a, $c, [
|
self::addMap($a, $c, [
|
||||||
'types' => 'getTypes',
|
'types' => 'getTypes',
|
||||||
|
@ -18,6 +18,7 @@ use Symfony\Component\VarDumper\Tests\Fixtures\ExtendsReflectionTypeFixture;
|
|||||||
use Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo;
|
use Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo;
|
||||||
use Symfony\Component\VarDumper\Tests\Fixtures\LotsOfAttributes;
|
use Symfony\Component\VarDumper\Tests\Fixtures\LotsOfAttributes;
|
||||||
use Symfony\Component\VarDumper\Tests\Fixtures\NotLoadableClass;
|
use Symfony\Component\VarDumper\Tests\Fixtures\NotLoadableClass;
|
||||||
|
use Symfony\Component\VarDumper\Tests\Fixtures\ReflectionIntersectionTypeFixture;
|
||||||
use Symfony\Component\VarDumper\Tests\Fixtures\ReflectionNamedTypeFixture;
|
use Symfony\Component\VarDumper\Tests\Fixtures\ReflectionNamedTypeFixture;
|
||||||
use Symfony\Component\VarDumper\Tests\Fixtures\ReflectionUnionTypeFixture;
|
use Symfony\Component\VarDumper\Tests\Fixtures\ReflectionUnionTypeFixture;
|
||||||
|
|
||||||
@ -94,7 +95,7 @@ Closure($x) {
|
|||||||
$b: & 123
|
$b: & 123
|
||||||
}
|
}
|
||||||
file: "%sReflectionCasterTest.php"
|
file: "%sReflectionCasterTest.php"
|
||||||
line: "87 to 87"
|
line: "88 to 88"
|
||||||
}
|
}
|
||||||
EOTXT
|
EOTXT
|
||||||
, $var
|
, $var
|
||||||
@ -244,6 +245,26 @@ EOTXT
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8.1
|
||||||
|
*/
|
||||||
|
public function testReflectionParameterIntersection()
|
||||||
|
{
|
||||||
|
$f = eval('return function (Traversable&Countable $a) {};');
|
||||||
|
$var = new \ReflectionParameter($f, 0);
|
||||||
|
|
||||||
|
$this->assertDumpMatchesFormat(
|
||||||
|
<<<'EOTXT'
|
||||||
|
ReflectionParameter {
|
||||||
|
+name: "a"
|
||||||
|
position: 0
|
||||||
|
typeHint: "Traversable&Countable"
|
||||||
|
}
|
||||||
|
EOTXT
|
||||||
|
, $var
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @requires PHP 7.4
|
* @requires PHP 7.4
|
||||||
*/
|
*/
|
||||||
@ -308,6 +329,34 @@ EOTXT
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8.1
|
||||||
|
*/
|
||||||
|
public function testReflectionIntersectionType()
|
||||||
|
{
|
||||||
|
$var = (new \ReflectionProperty(ReflectionIntersectionTypeFixture::class, 'a'))->getType();
|
||||||
|
$this->assertDumpMatchesFormat(
|
||||||
|
<<<'EOTXT'
|
||||||
|
ReflectionIntersectionType {
|
||||||
|
allowsNull: false
|
||||||
|
types: array:2 [
|
||||||
|
0 => ReflectionNamedType {
|
||||||
|
name: "Traversable"
|
||||||
|
allowsNull: false
|
||||||
|
isBuiltin: false
|
||||||
|
}
|
||||||
|
1 => ReflectionNamedType {
|
||||||
|
name: "Countable"
|
||||||
|
allowsNull: false
|
||||||
|
isBuiltin: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
EOTXT
|
||||||
|
, $var
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @requires PHP 8
|
* @requires PHP 8
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symfony\Component\VarDumper\Tests\Fixtures;
|
||||||
|
|
||||||
|
class ReflectionIntersectionTypeFixture
|
||||||
|
{
|
||||||
|
public \Traversable&\Countable $a;
|
||||||
|
}
|
Reference in New Issue
Block a user