Merge branch '3.0'

* 3.0:
  fixed issue with PHP 5.3
  The WebProcessor now forwards the client IP
  minor changes
  [#17878] Fixing a bug where scalar values caused invalid ordering
  [#17724] Fixing autowiring bug where if some args are set, new ones are put in the wrong spot
  bumped Symfony version to 2.3.39
  updated VERSION for 2.3.38
  update CONTRIBUTORS for 2.3.38
  updated CHANGELOG for 2.3.38
This commit is contained in:
Fabien Potencier 2016-03-01 12:09:33 +01:00
commit fce909a1ef
5 changed files with 385 additions and 171 deletions

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,7 @@ class WebProcessor extends BaseWebProcessor
{
if ($event->isMasterRequest()) {
$this->serverData = $event->getRequest()->server->all();
$this->serverData['REMOTE_ADDR'] = $event->getRequest()->getClientIp();
}
}
}

View File

@ -33,6 +33,23 @@ class WebProcessorTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($server['HTTP_REFERER'], $record['extra']['referrer']);
}
public function testUseRequestClientIp()
{
Request::setTrustedProxies(array('192.168.0.1'));
list($event, $server) = $this->createRequestEvent(array('X_FORWARDED_FOR' => '192.168.0.2'));
$processor = new WebProcessor();
$processor->onKernelRequest($event);
$record = $processor($this->getRecord());
$this->assertCount(5, $record['extra']);
$this->assertEquals($server['REQUEST_URI'], $record['extra']['url']);
$this->assertEquals($server['X_FORWARDED_FOR'], $record['extra']['ip']);
$this->assertEquals($server['REQUEST_METHOD'], $record['extra']['http_method']);
$this->assertEquals($server['SERVER_NAME'], $record['extra']['server']);
$this->assertEquals($server['HTTP_REFERER'], $record['extra']['referrer']);
}
public function testCanBeConstructedWithExtraFields()
{
if (!$this->isExtraFieldsSupported()) {
@ -53,18 +70,22 @@ class WebProcessorTest extends \PHPUnit_Framework_TestCase
/**
* @return array
*/
private function createRequestEvent()
private function createRequestEvent($additionalServerParameters = array())
{
$server = array(
'REQUEST_URI' => 'A',
'REMOTE_ADDR' => 'B',
'REQUEST_METHOD' => 'C',
'SERVER_NAME' => 'D',
'HTTP_REFERER' => 'E',
$server = array_merge(
array(
'REQUEST_URI' => 'A',
'REMOTE_ADDR' => '192.168.0.1',
'REQUEST_METHOD' => 'C',
'SERVER_NAME' => 'D',
'HTTP_REFERER' => 'E',
),
$additionalServerParameters
);
$request = new Request();
$request->server->replace($server);
$request->headers->replace($server);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
->disableOriginalConstructor()

View File

@ -71,13 +71,20 @@ class AutowirePass implements CompilerPassInterface
$arguments = $definition->getArguments();
foreach ($constructor->getParameters() as $index => $parameter) {
$argumentExists = array_key_exists($index, $arguments);
if ($argumentExists && '' !== $arguments[$index]) {
if (array_key_exists($index, $arguments) && '' !== $arguments[$index]) {
continue;
}
try {
if (!$typeHint = $parameter->getClass()) {
// no default value? Then fail
if (!$parameter->isOptional()) {
throw new RuntimeException(sprintf('Unable to autowire argument index %d ($%s) for the service "%s". If this is an object, give it a type-hint. Otherwise, specify this argument\'s value explicitly.', $index, $parameter->name, $id));
}
// specifically pass the default value
$arguments[$index] = $parameter->getDefaultValue();
continue;
}
@ -110,12 +117,13 @@ class AutowirePass implements CompilerPassInterface
$value = $parameter->getDefaultValue();
}
if ($argumentExists) {
$definition->replaceArgument($index, $value);
} else {
$definition->addArgument($value);
}
$arguments[$index] = $value;
}
// it's possible index 1 was set, then index 0, then 2, etc
// make sure that we re-order so they're injected as expected
ksort($arguments);
$definition->setArguments($arguments);
}
/**

View File

@ -297,6 +297,121 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase
$arguments = $container->getDefinition('bar')->getArguments();
$this->assertSame('foo', (string) $arguments[0]);
}
public function testSomeSpecificArgumentsAreSet()
{
$container = new ContainerBuilder();
$container->register('foo', __NAMESPACE__.'\Foo');
$container->register('a', __NAMESPACE__.'\A');
$container->register('dunglas', __NAMESPACE__.'\Dunglas');
$container->register('multiple', __NAMESPACE__.'\MultipleArguments')
->setAutowired(true)
// set the 2nd (index 1) argument only: autowire the first and third
// args are: A, Foo, Dunglas
->setArguments(array(
1 => new Reference('foo'),
));
$pass = new AutowirePass();
$pass->process($container);
$definition = $container->getDefinition('multiple');
$this->assertEquals(
array(
new Reference('a'),
new Reference('foo'),
new Reference('dunglas'),
),
$definition->getArguments()
);
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
* @expectedExceptionMessage Unable to autowire argument index 1 ($foo) for the service "arg_no_type_hint". If this is an object, give it a type-hint. Otherwise, specify this argument's value explicitly.
*/
public function testScalarArgsCannotBeAutowired()
{
$container = new ContainerBuilder();
$container->register('a', __NAMESPACE__.'\A');
$container->register('dunglas', __NAMESPACE__.'\Dunglas');
$container->register('arg_no_type_hint', __NAMESPACE__.'\MultipleArguments')
->setAutowired(true);
$pass = new AutowirePass();
$pass->process($container);
$container->getDefinition('arg_no_type_hint');
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
* @expectedExceptionMessage Unable to autowire argument index 1 ($foo) for the service "not_really_optional_scalar". If this is an object, give it a type-hint. Otherwise, specify this argument's value explicitly.
*/
public function testOptionalScalarNotReallyOptionalThrowException()
{
$container = new ContainerBuilder();
$container->register('a', __NAMESPACE__.'\A');
$container->register('lille', __NAMESPACE__.'\Lille');
$container->register('not_really_optional_scalar', __NAMESPACE__.'\MultipleArgumentsOptionalScalarNotReallyOptional')
->setAutowired(true);
$pass = new AutowirePass();
$pass->process($container);
}
public function testOptionalScalarArgsDontMessUpOrder()
{
$container = new ContainerBuilder();
$container->register('a', __NAMESPACE__.'\A');
$container->register('lille', __NAMESPACE__.'\Lille');
$container->register('with_optional_scalar', __NAMESPACE__.'\MultipleArgumentsOptionalScalar')
->setAutowired(true);
$pass = new AutowirePass();
$pass->process($container);
$definition = $container->getDefinition('with_optional_scalar');
$this->assertEquals(
array(
new Reference('a'),
// use the default value
'default_val',
new Reference('lille'),
),
$definition->getArguments()
);
}
public function testOptionalScalarArgsNotPassedIfLast()
{
$container = new ContainerBuilder();
$container->register('a', __NAMESPACE__.'\A');
$container->register('lille', __NAMESPACE__.'\Lille');
$container->register('with_optional_scalar_last', __NAMESPACE__.'\MultipleArgumentsOptionalScalarLast')
->setAutowired(true);
$pass = new AutowirePass();
$pass->process($container);
$definition = $container->getDefinition('with_optional_scalar_last');
$this->assertEquals(
array(
new Reference('a'),
new Reference('lille'),
// third arg shouldn't *need* to be passed
// but that's hard to "pull of" with autowiring, so
// this assumes passing the default val is ok
'some_val',
),
$definition->getArguments()
);
}
}
class Foo
@ -421,3 +536,28 @@ class NotGuessableArgumentForSubclass
{
}
}
class MultipleArguments
{
public function __construct(A $k, $foo, Dunglas $dunglas)
{
}
}
class MultipleArgumentsOptionalScalar
{
public function __construct(A $a, $foo = 'default_val', Lille $lille = null)
{
}
}
class MultipleArgumentsOptionalScalarLast
{
public function __construct(A $a, Lille $lille, $foo = 'some_val')
{
}
}
class MultipleArgumentsOptionalScalarNotReallyOptional
{
public function __construct(A $a, $foo = 'default_val', Lille $lille)
{
}
}