Skip to content

Commit

Permalink
Merge branch '4.4' into 5.3
Browse files Browse the repository at this point in the history
* 4.4:
  [HttpClient] Remove deprecated usage of `GuzzleHttp\Promise\queue`
  [PropertyAccess] Fix handling of uninitialized property of anonymous class
  [DependencyInjection] fix test
  ResolveBindingsPass remove loading of class iterable
  [FrameworkBundle] Avoid calling rtrim(null, '/') in AssetsInstallCommand
  [DependencyInjection] Fix nested env var with resolve processor
  Allow OutputFormatter::escape() to be used for escaping URLs used in <href>
  allow a zero time-limit
  [DependencyInjection] Ignore argument type check in CheckTypeDeclarationsPass if it's a Definition with a factory
  [Validators] Add translations for Slovak #43735
  • Loading branch information
nicolas-grekas committed Jan 12, 2022
2 parents 66dda4e + 9b9397f commit 8fb0f58
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 3 deletions.
4 changes: 4 additions & 0 deletions Compiler/CheckTypeDeclarationsPass.php
Expand Up @@ -210,6 +210,10 @@ private function checkType(Definition $checkedDefinition, $value, \ReflectionPar
$class = null;

if ($value instanceof Definition) {
if ($value->getFactory()) {
return;
}

$class = $value->getClass();

if ($class && isset(self::BUILTIN_TYPES[strtolower($class)])) {
Expand Down
2 changes: 1 addition & 1 deletion Compiler/ResolveBindingsPass.php
Expand Up @@ -126,7 +126,7 @@ protected function processValue($value, bool $isRoot = false)
$this->unusedBindings[$bindingId] = [$key, $this->currentId, $bindingType, $file];
}

if (preg_match('/^(?:(?:array|bool|float|int|string|([^ $]++)) )\$/', $key, $m)) {
if (preg_match('/^(?:(?:array|bool|float|int|string|iterable|([^ $]++)) )\$/', $key, $m)) {
$bindingNames[substr($key, \strlen($m[0]))] = $binding;
}

Expand Down
10 changes: 8 additions & 2 deletions EnvVarProcessor.php
Expand Up @@ -272,11 +272,17 @@ public function getEnv(string $prefix, string $name, \Closure $getEnv)
}

if ('resolve' === $prefix) {
return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($name) {
return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($name, $getEnv) {
if (!isset($match[1])) {
return '%';
}
$value = $this->container->getParameter($match[1]);

if (str_starts_with($match[1], 'env(') && str_ends_with($match[1], ')') && 'env()' !== $match[1]) {
$value = $getEnv(substr($match[1], 4, -1));
} else {
$value = $this->container->getParameter($match[1]);
}

if (!is_scalar($value)) {
throw new RuntimeException(sprintf('Parameter "%s" found when resolving env var "%s" must be scalar, "%s" given.', $match[1], $name, get_debug_type($value)));
}
Expand Down
14 changes: 14 additions & 0 deletions Tests/Compiler/CheckTypeDeclarationsPassTest.php
Expand Up @@ -996,6 +996,20 @@ public function testCallableClass()

$this->addToAssertionCount(1);
}

public function testIgnoreDefinitionFactoryArgument()
{
$container = new ContainerBuilder();
$container->register('bar', Bar::class)
->setArguments([
(new Definition(Foo::class))
->setFactory([Foo::class, 'createStdClass']),
]);

(new CheckTypeDeclarationsPass())->process($container);

$this->addToAssertionCount(1);
}
}

class CallableClass
Expand Down
23 changes: 23 additions & 0 deletions Tests/Compiler/ResolveBindingsPassTest.php
Expand Up @@ -28,6 +28,7 @@
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum;
use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy;
use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedEnumArgumentDummy;
use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedIterableArgumentDummy;
use Symfony\Component\DependencyInjection\Tests\Fixtures\ParentNotExists;
use Symfony\Component\DependencyInjection\Tests\Fixtures\WithTarget;
use Symfony\Component\DependencyInjection\TypedReference;
Expand Down Expand Up @@ -212,6 +213,28 @@ public function testEmptyBindingTypehint()
$pass->process($container);
}

public function testIterableBindingTypehint()
{
$autoloader = static function ($class) {
if ('iterable' === $class) {
throw new \RuntimeException('We should not search pseudo-type iterable as class');
}
};
spl_autoload_register($autoloader);

$container = new ContainerBuilder();
$definition = $container->register('bar', NamedIterableArgumentDummy::class);
$definition->setBindings([
'iterable $items' => new TaggedIteratorArgument('foo'),
]);
$pass = new ResolveBindingsPass();
$pass->process($container);

$this->assertInstanceOf(TaggedIteratorArgument::class, $container->getDefinition('bar')->getArgument(0));

spl_autoload_unregister($autoloader);
}

/**
* @requires PHP 8
*/
Expand Down
103 changes: 103 additions & 0 deletions Tests/EnvVarProcessorTest.php
Expand Up @@ -506,6 +506,109 @@ public function testRequireFile()
$this->assertEquals('foo', $result);
}

/**
* @dataProvider validResolve
*/
public function testGetEnvResolve($value, $processed)
{
$container = new ContainerBuilder();
$container->setParameter('bar', $value);
$container->compile();

$processor = new EnvVarProcessor($container);

$result = $processor->getEnv('resolve', 'foo', function () {
return '%bar%';
});

$this->assertSame($processed, $result);
}

public function validResolve()
{
return [
['string', 'string'],
[1, '1'],
[1.1, '1.1'],
[true, '1'],
[false, ''],
];
}

public function testGetEnvResolveNoMatch()
{
$processor = new EnvVarProcessor(new Container());

$result = $processor->getEnv('resolve', 'foo', function () {
return '%%';
});

$this->assertSame('%', $result);
}

/**
* @dataProvider notScalarResolve
*/
public function testGetEnvResolveNotScalar($value)
{
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('Parameter "bar" found when resolving env var "foo" must be scalar');

$container = new ContainerBuilder();
$container->setParameter('bar', $value);
$container->compile();

$processor = new EnvVarProcessor($container);

$processor->getEnv('resolve', 'foo', function () {
return '%bar%';
});
}

public function notScalarResolve()
{
return [
[null],
[[]],
];
}

public function testGetEnvResolveNestedEnv()
{
$container = new ContainerBuilder();
$container->setParameter('env(BAR)', 'BAR in container');
$container->compile();

$processor = new EnvVarProcessor($container);
$getEnv = \Closure::fromCallable([$processor, 'getEnv']);

$result = $processor->getEnv('resolve', 'foo', function ($name) use ($getEnv) {
return 'foo' === $name ? '%env(BAR)%' : $getEnv('string', $name, function () {});
});

$this->assertSame('BAR in container', $result);
}

public function testGetEnvResolveNestedRealEnv()
{
$_ENV['BAR'] = 'BAR in environment';

$container = new ContainerBuilder();
$container->setParameter('env(BAR)', 'BAR in container');
$container->compile();

$processor = new EnvVarProcessor($container);
$getEnv = \Closure::fromCallable([$processor, 'getEnv']);

$result = $processor->getEnv('resolve', 'foo', function ($name) use ($getEnv) {
return 'foo' === $name ? '%env(BAR)%' : $getEnv('string', $name, function () {});
});

$this->assertSame('BAR in environment', $result);

unset($_ENV['BAR']);
}

/**
* @dataProvider validCsv
*/
Expand Down
5 changes: 5 additions & 0 deletions Tests/Fixtures/CheckTypeDeclarationsPass/Foo.php
Expand Up @@ -23,4 +23,9 @@ public static function createArray(): array
{
return [];
}

public static function createStdClass(): \stdClass
{
return new \stdClass();
}
}
19 changes: 19 additions & 0 deletions Tests/Fixtures/NamedIterableArgumentDummy.php
@@ -0,0 +1,19 @@
<?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\DependencyInjection\Tests\Fixtures;

class NamedIterableArgumentDummy
{
public function __construct(iterable $items)
{
}
}

0 comments on commit 8fb0f58

Please sign in to comment.