Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 522594a

Browse filesBrowse files
committed
Merge branch '4.2'
* 4.2: [Phpunit] fixed support for PHP 5.3 Response prepare method update [Workflow] Added missing license header Fix case when multiple loaders are providing paths for the same namespace Check if Client exists when test.client does not exist, to provide clearer exception message throw TypeErrors to prepare for type hints in 5.0 [Form] Preventing validation of children if parent with Valid constraint has no validation groups [Form] Added ResetInterface to CachingFactoryDecorator Remove deprecated usage [Tests] fixed compatbility of assertEquals(): void Fixed usage of TranslatorInterface in form extension (fixes #30591) [Intl][4.2] Fix test [Intl] Fix test [Validator] Add the missing translations for the Arabic (ar) locale [Intl] Add compile binary Fix DebugCommand when chain loader is involved [Form] Fixed some phpdocs
2 parents 0b2a9d5 + 7e5dfcf commit 522594a
Copy full SHA for 522594a

38 files changed

+275-130Lines changed: 275 additions & 130 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public function __construct($entityManager)
4242
@trigger_error(sprintf('Injecting an instance of "%s" in "%s" is deprecated since Symfony 4.2, inject an instance of "%s" instead.', ClassMetadataFactory::class, __CLASS__, EntityManagerInterface::class), E_USER_DEPRECATED);
4343
$this->classMetadataFactory = $entityManager;
4444
} else {
45-
throw new \InvalidArgumentException(sprintf('$entityManager must be an instance of "%s", "%s" given.', EntityManagerInterface::class, \is_object($entityManager) ? \get_class($entityManager) : \gettype($entityManager)));
45+
throw new \TypeError(sprintf('$entityManager must be an instance of "%s", "%s" given.', EntityManagerInterface::class, \is_object($entityManager) ? \get_class($entityManager) : \gettype($entityManager)));
4646
}
4747
}
4848

Collapse file

‎src/Symfony/Bridge/PhpUnit/bin/simple-phpunit‎

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/PhpUnit/bin/simple-phpunit
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@ if ('phpdbg' === PHP_SAPI) {
7676
$PHP .= ' -qrr';
7777
}
7878

79-
$defaultEnvs = [
79+
$defaultEnvs = array(
8080
'COMPOSER' => 'composer.json',
8181
'COMPOSER_VENDOR_DIR' => 'vendor',
8282
'COMPOSER_BIN_DIR' => 'bin',
83-
];
83+
);
8484

8585
foreach ($defaultEnvs as $envName => $envValue) {
8686
if ($envValue !== getenv($envName)) {
Collapse file

‎src/Symfony/Bridge/Twig/Command/DebugCommand.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Twig/Command/DebugCommand.php
+60-32Lines changed: 60 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Symfony\Component\Console\Style\SymfonyStyle;
2121
use Symfony\Component\Finder\Finder;
2222
use Twig\Environment;
23+
use Twig\Loader\ChainLoader;
2324
use Twig\Loader\FilesystemLoader;
2425

2526
/**
@@ -36,6 +37,7 @@ class DebugCommand extends Command
3637
private $bundlesMetadata;
3738
private $twigDefaultPath;
3839
private $rootDir;
40+
private $filesystemLoaders;
3941

4042
public function __construct(Environment $twig, string $projectDir = null, array $bundlesMetadata = [], string $twigDefaultPath = null, string $rootDir = null)
4143
{
@@ -87,7 +89,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
8789
$name = $input->getArgument('name');
8890
$filter = $input->getOption('filter');
8991

90-
if (null !== $name && !$this->twig->getLoader() instanceof FilesystemLoader) {
92+
if (null !== $name && [] === $this->getFilesystemLoaders()) {
9193
throw new InvalidArgumentException(sprintf('Argument "name" not supported, it requires the Twig loader "%s"', FilesystemLoader::class));
9294
}
9395

@@ -150,9 +152,11 @@ private function displayPathsText(SymfonyStyle $io, string $name)
150152
$message = 'No template paths configured for your application';
151153
} else {
152154
$message = sprintf('No template paths configured for "@%s" namespace', $namespace);
153-
$namespaces = $this->twig->getLoader()->getNamespaces();
154-
foreach ($this->findAlternatives($namespace, $namespaces) as $namespace) {
155-
$alternatives[] = '@'.$namespace;
155+
foreach ($this->getFilesystemLoaders() as $loader) {
156+
$namespaces = $loader->getNamespaces();
157+
foreach ($this->findAlternatives($namespace, $namespaces) as $namespace) {
158+
$alternatives[] = '@'.$namespace;
159+
}
156160
}
157161
}
158162

@@ -243,25 +247,25 @@ private function displayGeneralJson(SymfonyStyle $io, $filter)
243247

244248
private function getLoaderPaths(string $name = null): array
245249
{
246-
/** @var FilesystemLoader $loader */
247-
$loader = $this->twig->getLoader();
248250
$loaderPaths = [];
249-
$namespaces = $loader->getNamespaces();
250-
if (null !== $name) {
251-
$namespace = $this->parseTemplateName($name)[0];
252-
$namespaces = array_intersect([$namespace], $namespaces);
253-
}
251+
foreach ($this->getFilesystemLoaders() as $loader) {
252+
$namespaces = $loader->getNamespaces();
253+
if (null !== $name) {
254+
$namespace = $this->parseTemplateName($name)[0];
255+
$namespaces = array_intersect([$namespace], $namespaces);
256+
}
254257

255-
foreach ($namespaces as $namespace) {
256-
$paths = array_map([$this, 'getRelativePath'], $loader->getPaths($namespace));
258+
foreach ($namespaces as $namespace) {
259+
$paths = array_map([$this, 'getRelativePath'], $loader->getPaths($namespace));
257260

258-
if (FilesystemLoader::MAIN_NAMESPACE === $namespace) {
259-
$namespace = '(None)';
260-
} else {
261-
$namespace = '@'.$namespace;
262-
}
261+
if (FilesystemLoader::MAIN_NAMESPACE === $namespace) {
262+
$namespace = '(None)';
263+
} else {
264+
$namespace = '@'.$namespace;
265+
}
263266

264-
$loaderPaths[$namespace] = $paths;
267+
$loaderPaths[$namespace] = array_merge($loaderPaths[$namespace] ?? [], $paths);
268+
}
265269
}
266270

267271
return $loaderPaths;
@@ -437,22 +441,22 @@ private function error(SymfonyStyle $io, string $message, array $alternatives =
437441

438442
private function findTemplateFiles(string $name): array
439443
{
440-
/** @var FilesystemLoader $loader */
441-
$loader = $this->twig->getLoader();
442-
$files = [];
443444
list($namespace, $shortname) = $this->parseTemplateName($name);
444445

445-
foreach ($loader->getPaths($namespace) as $path) {
446-
if (!$this->isAbsolutePath($path)) {
447-
$path = $this->projectDir.'/'.$path;
448-
}
449-
$filename = $path.'/'.$shortname;
446+
$files = [];
447+
foreach ($this->getFilesystemLoaders() as $loader) {
448+
foreach ($loader->getPaths($namespace) as $path) {
449+
if (!$this->isAbsolutePath($path)) {
450+
$path = $this->projectDir.'/'.$path;
451+
}
452+
$filename = $path.'/'.$shortname;
450453

451-
if (is_file($filename)) {
452-
if (false !== $realpath = realpath($filename)) {
453-
$files[] = $this->getRelativePath($realpath);
454-
} else {
455-
$files[] = $this->getRelativePath($filename);
454+
if (is_file($filename)) {
455+
if (false !== $realpath = realpath($filename)) {
456+
$files[] = $this->getRelativePath($realpath);
457+
} else {
458+
$files[] = $this->getRelativePath($filename);
459+
}
456460
}
457461
}
458462
}
@@ -535,4 +539,28 @@ private function isAbsolutePath(string $file): bool
535539
{
536540
return strspn($file, '/\\', 0, 1) || (\strlen($file) > 3 && ctype_alpha($file[0]) && ':' === $file[1] && strspn($file, '/\\', 2, 1)) || null !== parse_url($file, PHP_URL_SCHEME);
537541
}
542+
543+
/**
544+
* @return FilesystemLoader[]
545+
*/
546+
private function getFilesystemLoaders(): array
547+
{
548+
if (null !== $this->filesystemLoaders) {
549+
return $this->filesystemLoaders;
550+
}
551+
$this->filesystemLoaders = [];
552+
553+
$loader = $this->twig->getLoader();
554+
if ($loader instanceof FilesystemLoader) {
555+
$this->filesystemLoaders[] = $loader;
556+
} elseif ($loader instanceof ChainLoader) {
557+
foreach ($loader->getLoaders() as $l) {
558+
if ($l instanceof FilesystemLoader) {
559+
$this->filesystemLoaders[] = $l;
560+
}
561+
}
562+
}
563+
564+
return $this->filesystemLoaders;
565+
}
538566
}
Collapse file

‎src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Twig/Tests/Command/DebugCommandTest.php
+15-1Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\Console\Application;
1717
use Symfony\Component\Console\Tester\CommandTester;
1818
use Twig\Environment;
19+
use Twig\Loader\ChainLoader;
1920
use Twig\Loader\FilesystemLoader;
2021

2122
class DebugCommandTest extends TestCase
@@ -279,7 +280,16 @@ public function getDebugTemplateNameTestData()
279280
];
280281
}
281282

282-
private function createCommandTester(array $paths = [], array $bundleMetadata = [], string $defaultPath = null, string $rootDir = null): CommandTester
283+
public function testDebugTemplateNameWithChainLoader()
284+
{
285+
$tester = $this->createCommandTester(['templates/' => null], [], null, null, true);
286+
$ret = $tester->execute(['name' => 'base.html.twig'], ['decorated' => false]);
287+
288+
$this->assertEquals(0, $ret, 'Returns 0 in case of success');
289+
$this->assertContains('[OK]', $tester->getDisplay());
290+
}
291+
292+
private function createCommandTester(array $paths = [], array $bundleMetadata = [], string $defaultPath = null, string $rootDir = null, bool $useChainLoader = false): CommandTester
283293
{
284294
$projectDir = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures';
285295
$loader = new FilesystemLoader([], $projectDir);
@@ -291,6 +301,10 @@ private function createCommandTester(array $paths = [], array $bundleMetadata =
291301
}
292302
}
293303

304+
if ($useChainLoader) {
305+
$loader = new ChainLoader([$loader]);
306+
}
307+
294308
$application = new Application();
295309
$application->add(new DebugCommand(new Environment($loader), $projectDir, $bundleMetadata, $defaultPath, $rootDir));
296310
$command = $application->find('debug:twig');
Collapse file

‎src/Symfony/Bridge/Twig/composer.json‎

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Twig/composer.json
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"require": {
1919
"php": "^7.1.3",
2020
"symfony/contracts": "^1.0.2",
21-
"twig/twig": "^1.37.1|^2.6.2"
21+
"twig/twig": "^1.38.1|^2.7.1"
2222
},
2323
"require-dev": {
2424
"egulias/email-validator": "^2.0",
Collapse file

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
5656
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
5757
use Symfony\Component\Finder\Finder;
58+
use Symfony\Component\Form\ChoiceList\Factory\CachingFactoryDecorator;
5859
use Symfony\Component\Form\FormTypeExtensionInterface;
5960
use Symfony\Component\Form\FormTypeGuesserInterface;
6061
use Symfony\Component\Form\FormTypeInterface;
@@ -440,6 +441,11 @@ private function registerFormConfiguration(array $config, ContainerBuilder $cont
440441
if (!class_exists(Translator::class)) {
441442
$container->removeDefinition('form.type_extension.upload.validator');
442443
}
444+
if (!method_exists(CachingFactoryDecorator::class, 'reset')) {
445+
$container->getDefinition('form.choice_list_factory.cached')
446+
->clearTag('kernel.reset')
447+
;
448+
}
443449
}
444450

445451
private function registerEsiConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
Collapse file

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml‎

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757

5858
<service id="form.choice_list_factory.cached" class="Symfony\Component\Form\ChoiceList\Factory\CachingFactoryDecorator">
5959
<argument type="service" id="form.choice_list_factory.property_access"/>
60+
<tag name="kernel.reset" method="reset" />
6061
</service>
6162

6263
<service id="form.choice_list_factory" alias="form.choice_list_factory.cached" />
Collapse file

‎src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php
+4-1Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ protected static function createClient(array $options = [], array $server = [])
3636
try {
3737
$client = $kernel->getContainer()->get('test.client');
3838
} catch (ServiceNotFoundException $e) {
39-
throw new \LogicException('You cannot create the client used in functional tests if the BrowserKit component is not available. Try running "composer require symfony/browser-kit".');
39+
if (class_exists(Client::class)) {
40+
throw new \LogicException('You cannot create the client used in functional tests if the "framework.test" config is not set to true.');
41+
}
42+
throw new \LogicException('You cannot create the client used in functional tests if the BrowserKit component is not available. Try running "composer require symfony/browser-kit"');
4043
}
4144

4245
$client->setServerParameters($server);
Collapse file

‎src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function __construct(iterable $listeners, ExceptionListener $exceptionLis
4141
$this->logoutListener = $logoutListener;
4242
$this->config = $config;
4343
} else {
44-
throw new \InvalidArgumentException(sprintf('Argument 3 passed to %s() must be instance of %s or null, %s given.', __METHOD__, LogoutListener::class, \is_object($logoutListener) ? \get_class($logoutListener) : \gettype($logoutListener)));
44+
throw new \TypeError(sprintf('Argument 3 passed to %s() must be instance of %s or null, %s given.', __METHOD__, LogoutListener::class, \is_object($logoutListener) ? \get_class($logoutListener) : \gettype($logoutListener)));
4545
}
4646
}
4747

Collapse file

‎src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php
+7-9Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
* A list of choices with arbitrary data types.
1616
*
1717
* The user of this class is responsible for assigning string values to the
18-
* choices. Both the choices and their values are passed to the constructor.
19-
* Each choice must have a corresponding value (with the same array key) in
20-
* the value array.
18+
* choices annd for their uniqueness.
19+
* Both the choices and their values are passed to the constructor.
20+
* Each choice must have a corresponding value (with the same key) in
21+
* the values array.
2122
*
2223
* @author Bernhard Schussek <bschussek@gmail.com>
2324
*/
@@ -43,12 +44,6 @@ class ArrayChoiceList implements ChoiceListInterface
4344
* @var int[]|string[]
4445
*/
4546
protected $originalKeys;
46-
47-
/**
48-
* The callback for creating the value for a choice.
49-
*
50-
* @var callable
51-
*/
5247
protected $valueCallback;
5348

5449
/**
@@ -212,6 +207,8 @@ protected function flatten(array $choices, $value, &$choicesByValues, &$keysByVa
212207
/**
213208
* Checks whether the given choices can be cast to strings without
214209
* generating duplicates.
210+
* This method is responsible for preventing conflict between scalar values
211+
* and the empty value.
215212
*
216213
* @param array $choices The choices
217214
* @param array|null $cache The cache for previously checked entries. Internal
@@ -232,6 +229,7 @@ private function castableToString(array $choices, array &$cache = [])
232229
return false;
233230
}
234231

232+
// prevent having false casted to the empty string by isset()
235233
$choice = false === $choice ? '0' : (string) $choice;
236234

237235
if (isset($cache[$choice])) {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.