Skip to content

Commit 28cc56d

Browse files
Merge branch '6.4' into 7.0
* 6.4: [FrameworkBundle] Add TemplateController to the list of allowed controllers for fragments [Cache][Lock] Fix PDO store not creating table + add tests Closes #51936-Added Missing translations for Czech (cs) in validators.cs.xlf file Added missing translations in turkish and updated validators.tr.xlf [Serializer] Fix denormalizing date intervals having both weeks and days [Validator] updated Turkish translation [Serializer] Remove wrong final tags [Serializer] Fix denormalize constructor arguments Add some more non-countable English nouns Add hint that changing input arguments has no effect register the virtual request stack together with common profiling services Don't lose checkpoint state when lock is acquired from another [DomCrawler] Revert "bug #52579 UriResolver support path with colons" [VarExporter] Fix handling mangled property names returned by __sleep() Update Github template for 7.1 Fix memory limit in PhpSubprocess unit test
2 parents 3241888 + adec730 commit 28cc56d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+428
-109
lines changed

.github/PULL_REQUEST_TEMPLATE.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
| Q | A
22
| ------------- | ---
3-
| Branch? | 6.4 for features / 5.4 or 6.3 for bug fixes <!-- see below -->
3+
| Branch? | 7.1 for features / 5.4, 6.3, 6.4, or 7.0 for bug fixes <!-- see below -->
44
| Bug fix? | yes/no
55
| New feature? | yes/no <!-- please update src/**/CHANGELOG.md files -->
66
| Deprecations? | yes/no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->

src/Symfony/Bundle/FrameworkBundle/Console/Application.php

+6
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,12 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI
107107
}
108108

109109
(new SymfonyStyle($input, $output))->warning('The "--profile" option needs the Stopwatch component. Try running "composer require symfony/stopwatch".');
110+
} elseif (!$container->has('.virtual_request_stack')) {
111+
if ($output instanceof ConsoleOutputInterface) {
112+
$output = $output->getErrorOutput();
113+
}
114+
115+
(new SymfonyStyle($input, $output))->warning('The "--profile" option needs the profiler integration. Try enabling the "framework.profiler" option.');
110116
} else {
111117
$command = new TraceableCommand($command, $container->get('debug.stopwatch'));
112118

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection;
13+
14+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
15+
use Symfony\Component\DependencyInjection\ContainerBuilder;
16+
use Symfony\Component\DependencyInjection\Reference;
17+
18+
class VirtualRequestStackPass implements CompilerPassInterface
19+
{
20+
public function process(ContainerBuilder $container): void
21+
{
22+
if ($container->has('.virtual_request_stack')) {
23+
return;
24+
}
25+
26+
if ($container->hasDefinition('debug.event_dispatcher')) {
27+
$container->getDefinition('debug.event_dispatcher')->replaceArgument(3, new Reference('request_stack', ContainerBuilder::NULL_ON_INVALID_REFERENCE));
28+
}
29+
30+
if ($container->hasDefinition('debug.log_processor')) {
31+
$container->getDefinition('debug.log_processor')->replaceArgument(0, new Reference('request_stack'));
32+
}
33+
}
34+
}

src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TestServiceContainerRealRefPass;
2121
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TestServiceContainerWeakRefPass;
2222
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\UnusedTagsPass;
23+
use Symfony\Bundle\FrameworkBundle\DependencyInjection\VirtualRequestStackPass;
2324
use Symfony\Component\Cache\Adapter\ApcuAdapter;
2425
use Symfony\Component\Cache\Adapter\ArrayAdapter;
2526
use Symfony\Component\Cache\Adapter\ChainAdapter;
@@ -171,6 +172,7 @@ public function build(ContainerBuilder $container): void
171172
$container->addCompilerPass(new RemoveUnusedSessionMarshallingHandlerPass());
172173
// must be registered after MonologBundle's LoggerChannelPass
173174
$container->addCompilerPass(new ErrorLoggerCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -32);
175+
$container->addCompilerPass(new VirtualRequestStackPass());
174176

175177
if ($container->getParameter('kernel.debug')) {
176178
$container->addCompilerPass(new AddDebugLogProcessorPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 2);

src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.php

-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
use Symfony\Component\HttpKernel\Controller\TraceableArgumentResolver;
1616
use Symfony\Component\HttpKernel\Controller\TraceableControllerResolver;
1717
use Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher;
18-
use Symfony\Component\HttpKernel\Debug\VirtualRequestStack;
1918

2019
return static function (ContainerConfigurator $container) {
2120
$container->services()
@@ -47,9 +46,5 @@
4746
->set('argument_resolver.not_tagged_controller', NotTaggedControllerValueResolver::class)
4847
->args([abstract_arg('Controller argument, set in FrameworkExtension')])
4948
->tag('controller.argument_value_resolver', ['priority' => -200])
50-
51-
->set('.virtual_request_stack', VirtualRequestStack::class)
52-
->args([service('request_stack')])
53-
->public()
5449
;
5550
};

src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.php

+5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
1313

1414
use Symfony\Bundle\FrameworkBundle\EventListener\ConsoleProfilerListener;
15+
use Symfony\Component\HttpKernel\Debug\VirtualRequestStack;
1516
use Symfony\Component\HttpKernel\EventListener\ProfilerListener;
1617
use Symfony\Component\HttpKernel\Profiler\FileProfilerStorage;
1718
use Symfony\Component\HttpKernel\Profiler\Profiler;
@@ -45,5 +46,9 @@
4546
service('router'),
4647
])
4748
->tag('kernel.event_subscriber')
49+
50+
->set('.virtual_request_stack', VirtualRequestStack::class)
51+
->args([service('request_stack')])
52+
->public()
4853
;
4954
};

src/Symfony/Bundle/FrameworkBundle/Resources/config/web.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
1515
use Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver;
16+
use Symfony\Bundle\FrameworkBundle\Controller\TemplateController;
1617
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
1718
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\BackedEnumValueResolver;
1819
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\DateTimeValueResolver;
@@ -41,7 +42,7 @@
4142
service('service_container'),
4243
service('logger')->ignoreOnInvalid(),
4344
])
44-
->call('allowControllers', [[AbstractController::class]])
45+
->call('allowControllers', [[AbstractController::class, TemplateController::class]])
4546
->tag('monolog.logger', ['channel' => 'request'])
4647

4748
->set('argument_metadata_factory', ArgumentMetadataFactory::class)

src/Symfony/Component/Cache/Adapter/DoctrineDbalAdapter.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,8 @@ private function getServerVersion(): string
375375
return $this->serverVersion;
376376
}
377377

378-
$conn = $this->conn->getWrappedConnection();
378+
// The condition should be removed once support for DBAL <3.3 is dropped
379+
$conn = method_exists($this->conn, 'getNativeConnection') ? $this->conn->getNativeConnection() : $this->conn->getWrappedConnection();
379380
if ($conn instanceof ServerInfoAwareConnection) {
380381
return $this->serverVersion = $conn->getServerVersion();
381382
}

src/Symfony/Component/Cache/Adapter/PdoAdapter.php

+19-2
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ protected function doSave(array $values, int $lifetime): array|bool
284284
try {
285285
$stmt = $conn->prepare($sql);
286286
} catch (\PDOException) {
287-
if (!$conn->inTransaction() || \in_array($this->driver, ['pgsql', 'sqlite', 'sqlsrv'], true)) {
287+
if ($this->isTableMissing($e) && (!$conn->inTransaction() || \in_array($this->driver, ['pgsql', 'sqlite', 'sqlsrv'], true))) {
288288
$this->createTable();
289289
}
290290
$stmt = $conn->prepare($sql);
@@ -319,7 +319,7 @@ protected function doSave(array $values, int $lifetime): array|bool
319319
try {
320320
$stmt->execute();
321321
} catch (\PDOException) {
322-
if (!$conn->inTransaction() || \in_array($this->driver, ['pgsql', 'sqlite', 'sqlsrv'], true)) {
322+
if ($this->isTableMissing($e) && (!$conn->inTransaction() || \in_array($this->driver, ['pgsql', 'sqlite', 'sqlsrv'], true))) {
323323
$this->createTable();
324324
}
325325
$stmt->execute();
@@ -367,4 +367,21 @@ private function getServerVersion(): string
367367
{
368368
return $this->serverVersion ??= $this->conn->getAttribute(\PDO::ATTR_SERVER_VERSION);
369369
}
370+
371+
private function isTableMissing(\PDOException $exception): bool
372+
{
373+
$driver = $this->driver;
374+
$code = $exception->getCode();
375+
376+
switch (true) {
377+
case 'pgsql' === $driver && '42P01' === $code:
378+
case 'sqlite' === $driver && str_contains($exception->getMessage(), 'no such table:'):
379+
case 'oci' === $driver && 942 === $code:
380+
case 'sqlsrv' === $driver && 208 === $code:
381+
case 'mysql' === $driver && 1146 === $code:
382+
return true;
383+
default:
384+
return false;
385+
}
386+
}
370387
}

src/Symfony/Component/Cache/Tests/Adapter/DoctrineDbalAdapterTest.php

+31-11
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
use Symfony\Component\Cache\Adapter\DoctrineDbalAdapter;
2525

2626
/**
27+
* @requires extension pdo_sqlite
28+
*
2729
* @group time-sensitive
2830
*/
2931
class DoctrineDbalAdapterTest extends AdapterTestCase
@@ -32,10 +34,6 @@ class DoctrineDbalAdapterTest extends AdapterTestCase
3234

3335
public static function setUpBeforeClass(): void
3436
{
35-
if (!\extension_loaded('pdo_sqlite')) {
36-
self::markTestSkipped('Extension pdo_sqlite required.');
37-
}
38-
3937
self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache');
4038
}
4139

@@ -107,13 +105,12 @@ public function testConfigureSchemaTableExists()
107105
}
108106

109107
/**
110-
* @dataProvider provideDsn
108+
* @dataProvider provideDsnWithSQLite
111109
*/
112-
public function testDsn(string $dsn, string $file = null)
110+
public function testDsnWithSQLite(string $dsn, string $file = null)
113111
{
114112
try {
115113
$pool = new DoctrineDbalAdapter($dsn);
116-
$pool->createTable();
117114

118115
$item = $pool->getItem('key');
119116
$item->set('value');
@@ -125,12 +122,35 @@ public function testDsn(string $dsn, string $file = null)
125122
}
126123
}
127124

128-
public static function provideDsn(): \Generator
125+
public static function provideDsnWithSQLite()
129126
{
130127
$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache');
131-
yield ['sqlite://localhost/'.$dbFile.'1', $dbFile.'1'];
132-
yield ['sqlite3:///'.$dbFile.'3', $dbFile.'3'];
133-
yield ['sqlite://localhost/:memory:'];
128+
yield 'SQLite file' => ['sqlite://localhost/'.$dbFile.'1', $dbFile.'1'];
129+
yield 'SQLite3 file' => ['sqlite3:///'.$dbFile.'3', $dbFile.'3'];
130+
yield 'SQLite in memory' => ['sqlite://localhost/:memory:'];
131+
}
132+
133+
/**
134+
* @requires extension pdo_pgsql
135+
*
136+
* @group integration
137+
*/
138+
public function testDsnWithPostgreSQL()
139+
{
140+
if (!$host = getenv('POSTGRES_HOST')) {
141+
$this->markTestSkipped('Missing POSTGRES_HOST env variable');
142+
}
143+
144+
try {
145+
$pool = new DoctrineDbalAdapter('pgsql://postgres:password@'.$host);
146+
147+
$item = $pool->getItem('key');
148+
$item->set('value');
149+
$this->assertTrue($pool->save($item));
150+
} finally {
151+
$pdo = new \PDO('pgsql:host='.$host.';user=postgres;password=password');
152+
$pdo->exec('DROP TABLE IF EXISTS cache_items');
153+
}
134154
}
135155

136156
protected function isPruned(DoctrineDbalAdapter $cache, string $name): bool

src/Symfony/Component/Cache/Tests/Adapter/PdoAdapterTest.php

+32-10
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
use Symfony\Component\Cache\Adapter\PdoAdapter;
1616

1717
/**
18+
* @requires extension pdo_sqlite
19+
*
1820
* @group time-sensitive
1921
*/
2022
class PdoAdapterTest extends AdapterTestCase
@@ -23,10 +25,6 @@ class PdoAdapterTest extends AdapterTestCase
2325

2426
public static function setUpBeforeClass(): void
2527
{
26-
if (!\extension_loaded('pdo_sqlite')) {
27-
self::markTestSkipped('Extension pdo_sqlite required.');
28-
}
29-
3028
self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache');
3129

3230
$pool = new PdoAdapter('sqlite:'.self::$dbFile);
@@ -68,13 +66,12 @@ public function testCleanupExpiredItems()
6866
}
6967

7068
/**
71-
* @dataProvider provideDsn
69+
* @dataProvider provideDsnSQLite
7270
*/
73-
public function testDsn(string $dsn, string $file = null)
71+
public function testDsnWithSQLite(string $dsn, string $file = null)
7472
{
7573
try {
7674
$pool = new PdoAdapter($dsn);
77-
$pool->createTable();
7875

7976
$item = $pool->getItem('key');
8077
$item->set('value');
@@ -86,11 +83,36 @@ public function testDsn(string $dsn, string $file = null)
8683
}
8784
}
8885

89-
public static function provideDsn()
86+
public static function provideDsnSQLite()
9087
{
9188
$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache');
92-
yield ['sqlite:'.$dbFile.'2', $dbFile.'2'];
93-
yield ['sqlite::memory:'];
89+
yield 'SQLite file' => ['sqlite:'.$dbFile.'2', $dbFile.'2'];
90+
yield 'SQLite in memory' => ['sqlite::memory:'];
91+
}
92+
93+
/**
94+
* @requires extension pdo_pgsql
95+
*
96+
* @group integration
97+
*/
98+
public function testDsnWithPostgreSQL()
99+
{
100+
if (!$host = getenv('POSTGRES_HOST')) {
101+
$this->markTestSkipped('Missing POSTGRES_HOST env variable');
102+
}
103+
104+
$dsn = 'pgsql:host='.$host.';user=postgres;password=password';
105+
106+
try {
107+
$pool = new PdoAdapter($dsn);
108+
109+
$item = $pool->getItem('key');
110+
$item->set('value');
111+
$this->assertTrue($pool->save($item));
112+
} finally {
113+
$pdo = new \PDO($dsn);
114+
$pdo->exec('DROP TABLE IF EXISTS cache_items');
115+
}
94116
}
95117

96118
protected function isPruned(PdoAdapter $cache, string $name): bool

src/Symfony/Component/Console/Event/ConsoleCommandEvent.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
namespace Symfony\Component\Console\Event;
1313

1414
/**
15-
* Allows to do things before the command is executed, like skipping the command or changing the input.
15+
* Allows to do things before the command is executed, like skipping the command or executing code before the command is
16+
* going to be executed.
17+
*
18+
* Changing the input arguments will have no effect.
1619
*
1720
* @author Fabien Potencier <fabien@symfony.com>
1821
*/

src/Symfony/Component/DomCrawler/Tests/UriResolverTest.php

+1-3
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,7 @@ public static function provideResolverTests()
8585
['foo', 'http://localhost?bar=1', 'http://localhost/foo'],
8686
['foo', 'http://localhost#bar', 'http://localhost/foo'],
8787

88-
['foo:1', 'http://localhost', 'http://localhost/foo:1'],
89-
['/bar:1', 'http://localhost', 'http://localhost/bar:1'],
90-
['foo/bar:1', 'http://localhost', 'http://localhost/foo/bar:1'],
88+
['http://', 'http://localhost', 'http://'],
9189
];
9290
}
9391
}

src/Symfony/Component/DomCrawler/UriResolver.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public static function resolve(string $uri, ?string $baseUri): string
3333
$uri = trim($uri);
3434

3535
// absolute URL?
36-
if (\is_string(parse_url($uri, \PHP_URL_SCHEME))) {
36+
if (null !== parse_url($uri, \PHP_URL_SCHEME)) {
3737
return $uri;
3838
}
3939

0 commit comments

Comments
 (0)