Merge branch '3.4'

* 3.4:
  [HttpFoundation] Add Request::HEADER_X_FORWARDED_AWS_ELB const
  [DI] Avoid private call to Container::has()
  Fixing missing abstract attribute in XmlDumper
  [Form] Remove DateTimeToStringTransformer $parseUsingPipe option
  [Yaml] parse PHP constants in mapping keys
  don't call getTrustedHeaderName() if possible
  Fix file perms
  Fixed filename in help text for update-data.php
This commit is contained in:
Fabien Potencier 2017-05-25 16:11:32 -07:00
commit 4c7da9fc56
15 changed files with 136 additions and 99 deletions

View File

@ -1200,9 +1200,17 @@ EOF;
$conditions = array();
foreach ($services as $service) {
if ($this->container->hasDefinition($service) && !$this->container->getDefinition($service)->isPublic()) {
continue;
}
$conditions[] = sprintf("\$this->has('%s')", $service);
}
if (!$conditions) {
return '';
}
return implode(' && ', $conditions);
}

View File

@ -202,6 +202,10 @@ class XmlDumper extends Dumper
$service->setAttribute('autoconfigure', 'true');
}
if ($definition->isAbstract()) {
$service->setAttribute('abstract', 'true');
}
if ($callable = $definition->getConfigurator()) {
$configurator = $this->document->createElement('configurator');

View File

@ -19,6 +19,7 @@ use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface as SymfonyContainerInterface;
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Reference;
@ -598,4 +599,22 @@ class PhpDumperTest extends TestCase
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_subscriber.php', $dumper->dump());
}
public function testPrivateWithIgnoreOnInvalidReference()
{
require_once self::$fixturesPath.'/includes/classes.php';
$container = new ContainerBuilder();
$container->register('not_invalid', 'BazClass')
->setPublic(false);
$container->register('bar', 'BarClass')
->addMethodCall('setBaz', array(new Reference('not_invalid', SymfonyContainerInterface::IGNORE_ON_INVALID_REFERENCE)));
$container->compile();
$dumper = new PhpDumper($container);
eval('?>'.$dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Private_With_Ignore_On_Invalid_Reference')));
$container = new \Symfony_DI_PhpDumper_Test_Private_With_Ignore_On_Invalid_Reference();
$this->assertInstanceOf('BazClass', $container->get('bar')->getBaz());
}
}

View File

@ -183,4 +183,12 @@ class XmlDumperTest extends TestCase
$this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services24.xml'), $dumper->dump());
}
public function testDumpAbstractServices()
{
$container = include self::$fixturesPath.'/containers/container_abstract.php';
$dumper = new XmlDumper($container);
$this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services_abstract.xml'), $dumper->dump());
}
}

View File

@ -0,0 +1,12 @@
<?php
use Symfony\Component\DependencyInjection\ContainerBuilder;
$container = new ContainerBuilder();
$container
->register('foo', 'Foo')
->setAbstract(true)
;
return $container;

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="service_container" class="Symfony\Component\DependencyInjection\ContainerInterface" synthetic="true"/>
<service id="foo" class="Foo" abstract="true"/>
<service id="Psr\Container\ContainerInterface" alias="service_container" public="false"/>
<service id="Symfony\Component\DependencyInjection\ContainerInterface" alias="service_container" public="false"/>
</services>
</container>

0
src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php Executable file → Normal file
View File

0
src/Symfony/Component/Finder/Tests/GlobTest.php Executable file → Normal file
View File

View File

@ -40,13 +40,6 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer
*/
private $parseFormat;
/**
* Whether to parse by appending a pipe "|" to the parse format.
*
* @var bool
*/
private $parseUsingPipe;
/**
* Transforms a \DateTime instance to a string.
*
@ -55,16 +48,14 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer
* @param string $inputTimezone The name of the input timezone
* @param string $outputTimezone The name of the output timezone
* @param string $format The date format
* @param bool $parseUsingPipe Whether to parse by appending a pipe "|" to the parse format
*
* @throws UnexpectedTypeException if a timezone is not a string
*/
public function __construct($inputTimezone = null, $outputTimezone = null, $format = 'Y-m-d H:i:s', $parseUsingPipe = true)
public function __construct($inputTimezone = null, $outputTimezone = null, $format = 'Y-m-d H:i:s')
{
parent::__construct($inputTimezone, $outputTimezone);
$this->generateFormat = $this->parseFormat = $format;
$this->parseUsingPipe = $parseUsingPipe || null === $parseUsingPipe;
// See http://php.net/manual/en/datetime.createfromformat.php
// The character "|" in the format makes sure that the parts of a date
@ -74,7 +65,7 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer
// where the time corresponds to the current server time.
// With "|" and "Y-m-d", "2010-02-03" becomes "2010-02-03 00:00:00",
// which is at least deterministic and thus used here.
if ($this->parseUsingPipe && false === strpos($this->parseFormat, '|')) {
if (false === strpos($this->parseFormat, '|')) {
$this->parseFormat .= '|';
}
}
@ -143,70 +134,6 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer
}
try {
// On PHP versions < 5.3.7 we need to emulate the pipe operator
// and reset parts not given in the format to their equivalent
// of the UNIX base timestamp.
if (!$this->parseUsingPipe) {
list($year, $month, $day, $hour, $minute, $second) = explode('-', $dateTime->format('Y-m-d-H-i-s'));
// Check which of the date parts are present in the pattern
preg_match(
'/('.
'(?P<day>[djDl])|'.
'(?P<month>[FMmn])|'.
'(?P<year>[Yy])|'.
'(?P<hour>[ghGH])|'.
'(?P<minute>i)|'.
'(?P<second>s)|'.
'(?P<dayofyear>z)|'.
'(?P<timestamp>U)|'.
'[^djDlFMmnYyghGHiszU]'.
')*/',
$this->parseFormat,
$matches
);
// preg_match() does not guarantee to set all indices, so
// set them unless given
$matches = array_merge(array(
'day' => false,
'month' => false,
'year' => false,
'hour' => false,
'minute' => false,
'second' => false,
'dayofyear' => false,
'timestamp' => false,
), $matches);
// Reset all parts that don't exist in the format to the
// corresponding part of the UNIX base timestamp
if (!$matches['timestamp']) {
if (!$matches['dayofyear']) {
if (!$matches['day']) {
$day = 1;
}
if (!$matches['month']) {
$month = 1;
}
}
if (!$matches['year']) {
$year = 1970;
}
if (!$matches['hour']) {
$hour = 0;
}
if (!$matches['minute']) {
$minute = 0;
}
if (!$matches['second']) {
$second = 0;
}
$dateTime->setDate($year, $month, $day);
$dateTime->setTime($hour, $minute, $second);
}
}
if ($this->inputTimezone !== $this->outputTimezone) {
$dateTime->setTimezone(new \DateTimeZone($this->inputTimezone));
}

View File

@ -118,21 +118,9 @@ class DateTimeToStringTransformerTest extends DateTimeTestCase
/**
* @dataProvider dataProvider
*/
public function testReverseTransformUsingPipe($format, $input, $output)
public function testReverseTransform($format, $input, $output)
{
$reverseTransformer = new DateTimeToStringTransformer('UTC', 'UTC', $format, true);
$output = new \DateTime($output);
$this->assertDateTimeEquals($output, $reverseTransformer->reverseTransform($input));
}
/**
* @dataProvider dataProvider
*/
public function testReverseTransformWithoutUsingPipe($format, $input, $output)
{
$reverseTransformer = new DateTimeToStringTransformer('UTC', 'UTC', $format, false);
$reverseTransformer = new DateTimeToStringTransformer('UTC', 'UTC', $format);
$output = new \DateTime($output);

View File

@ -30,12 +30,13 @@ use Symfony\Component\HttpFoundation\Session\SessionInterface;
*/
class Request
{
const HEADER_FORWARDED = 0b00001;
const HEADER_X_FORWARDED_ALL = 0b11110;
const HEADER_X_FORWARDED_FOR = 2;
const HEADER_X_FORWARDED_HOST = 4;
const HEADER_X_FORWARDED_PROTO = 8;
const HEADER_X_FORWARDED_PORT = 16;
const HEADER_FORWARDED = 0b00001; // When using RFC 7239
const HEADER_X_FORWARDED_FOR = 0b00010;
const HEADER_X_FORWARDED_HOST = 0b00100;
const HEADER_X_FORWARDED_PROTO = 0b01000;
const HEADER_X_FORWARDED_PORT = 0b10000;
const HEADER_X_FORWARDED_ALL = 0b11110; // All "X-Forwarded-*" headers
const HEADER_X_FORWARDED_AWS_ELB = 0b11010; // AWS ELB doesn't send X-Forwarded-Host
/** @deprecated since version 3.3, to be removed in 4.0 */
const HEADER_CLIENT_IP = self::HEADER_X_FORWARDED_FOR;

View File

@ -119,7 +119,11 @@ class InlineFragmentRenderer extends RoutableFragmentRenderer
// Sub-request object will point to localhost as client ip and real client ip
// will be included into trusted header for client ip
try {
if ($trustedHeaderName = Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP, false)) {
if (Request::HEADER_X_FORWARDED_FOR & Request::getTrustedHeaderSet()) {
$currentXForwardedFor = $request->headers->get('X_FORWARDED_FOR', '');
$server['HTTP_X_FORWARDED_FOR'] = ($currentXForwardedFor ? $currentXForwardedFor.', ' : '').$request->getClientIp();
} elseif (method_exists(Request::class, 'getTrustedHeaderName') && $trustedHeaderName = Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP, false)) {
$currentXForwardedFor = $request->headers->get($trustedHeaderName, '');
$server['HTTP_'.$trustedHeaderName] = ($currentXForwardedFor ? $currentXForwardedFor.', ' : '').$request->getClientIp();

View File

@ -36,7 +36,7 @@ $argv = $_SERVER['argv'];
if ($argc > 3 || 2 === $argc && '-h' === $argv[1]) {
bailout(<<<'MESSAGE'
Usage: php update-icu-component.php <path/to/icu/source> <path/to/icu/build>
Usage: php update-data.php <path/to/icu/source> <path/to/icu/build>
Updates the ICU data for Symfony to the latest version of ICU.

View File

@ -159,7 +159,7 @@ class Parser
$this->refs[$isRef] = end($data);
}
} elseif (
self::preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|(?:![^\s]++\s++)?[^ \'"\[\{!].*?) *\:(\s++(?P<value>.+))?$#u', rtrim($this->currentLine), $values)
self::preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?(?:![^\s]++\s++)?[^ \'"\[\{!].*?) *\:(\s++(?P<value>.+))?$#u', rtrim($this->currentLine), $values)
&& (false === strpos($values['key'], ' #') || in_array($values['key'][0], array('"', "'")))
) {
if ($context && 'sequence' == $context) {
@ -172,7 +172,14 @@ class Parser
try {
Inline::$parsedLineNumber = $this->getRealCurrentLineNb();
$i = 0;
$key = Inline::parseScalar($values['key'], 0, null, $i, !(Yaml::PARSE_KEYS_AS_STRINGS & $flags));
$evaluateKey = !(Yaml::PARSE_KEYS_AS_STRINGS & $flags);
// constants in key will be evaluated anyway
if (isset($values['key'][0]) && '!' === $values['key'][0] && Yaml::PARSE_CONSTANT & $flags) {
$evaluateKey = true;
}
$key = Inline::parseScalar($values['key'], 0, null, $i, $evaluateKey);
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
$e->setSnippet($this->currentLine);

View File

@ -1717,9 +1717,59 @@ bar:
YAML;
$this->parser->parse($yaml);
}
public function testPhpConstantTagMappingKey()
{
$yaml = <<<YAML
transitions:
!php/const:Symfony\Component\Yaml\Tests\B::FOO:
from:
- !php/const:Symfony\Component\Yaml\Tests\B::BAR
to: !php/const:Symfony\Component\Yaml\Tests\B::BAZ
YAML;
$expected = array(
'transitions' => array(
'foo' => array(
'from' => array(
'bar',
),
'to' => 'baz',
),
),
);
$this->assertSame($expected, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT));
}
public function testPhpConstantTagMappingKeyWithKeysCastToStrings()
{
$yaml = <<<YAML
transitions:
!php/const:Symfony\Component\Yaml\Tests\B::FOO:
from:
- !php/const:Symfony\Component\Yaml\Tests\B::BAR
to: !php/const:Symfony\Component\Yaml\Tests\B::BAZ
YAML;
$expected = array(
'transitions' => array(
'foo' => array(
'from' => array(
'bar',
),
'to' => 'baz',
),
),
);
$this->assertSame($expected, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT | Yaml::PARSE_KEYS_AS_STRINGS));
}
}
class B
{
public $b = 'foo';
const FOO = 'foo';
const BAR = 'bar';
const BAZ = 'baz';
}