From 44d57a340fe5e23b94ad5f38f0cc605dd9265f0c Mon Sep 17 00:00:00 2001 From: Jakub Zalas Date: Sun, 18 Oct 2015 21:45:35 +0100 Subject: [PATCH 1/7] [HttpKernel] Remove a duplicate test for the EsiFragmentRenderer Since the request was made a required argument to the `render()` method in #6829, this test became a duplicate of `testRenderFallbackToInlineStrategyIfEsiNotSupported()`. --- .../HttpKernel/Tests/Fragment/EsiFragmentRendererTest.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Tests/Fragment/EsiFragmentRendererTest.php b/src/Symfony/Component/HttpKernel/Tests/Fragment/EsiFragmentRendererTest.php index 2b9016d082..ffcee4511a 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Fragment/EsiFragmentRendererTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Fragment/EsiFragmentRendererTest.php @@ -19,12 +19,6 @@ use Symfony\Component\HttpKernel\UriSigner; class EsiFragmentRendererTest extends \PHPUnit_Framework_TestCase { - public function testRenderFallbackToInlineStrategyIfNoRequest() - { - $strategy = new EsiFragmentRenderer(new Esi(), $this->getInlineStrategy(true)); - $strategy->render('/', Request::create('/')); - } - public function testRenderFallbackToInlineStrategyIfEsiNotSupported() { $strategy = new EsiFragmentRenderer(new Esi(), $this->getInlineStrategy(true)); From 2c9b283e01ce8d8fc5fb25b31615a79df96e2ea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Ro=C3=9Fkamp?= Date: Wed, 14 Oct 2015 12:34:59 +0200 Subject: [PATCH 2/7] [Form] Simplify DateTimeToStringTransformer Avoid unneeded catch and re-throw of the same exception. --- .../DateTimeToStringTransformer.php | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php index fdcfeee8ec..80c31a725c 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php @@ -90,7 +90,7 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer * Transforms a DateTime object into a date string with the configured format * and timezone. * - * @param \DateTime|\DateTimeInterface $dateTime A DateTime object + * @param \DateTime|\DateTimeInterface $value A DateTime object * * @return string A value as produced by PHP's date() function * @@ -142,21 +142,21 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer throw new TransformationFailedException('Expected a string.'); } + $outputTz = new \DateTimeZone($this->outputTimezone); + $dateTime = \DateTime::createFromFormat($this->parseFormat, $value, $outputTz); + + $lastErrors = \DateTime::getLastErrors(); + + if (0 < $lastErrors['warning_count'] || 0 < $lastErrors['error_count']) { + throw new TransformationFailedException( + implode(', ', array_merge( + array_values($lastErrors['warnings']), + array_values($lastErrors['errors']) + )) + ); + } + try { - $outputTz = new \DateTimeZone($this->outputTimezone); - $dateTime = \DateTime::createFromFormat($this->parseFormat, $value, $outputTz); - - $lastErrors = \DateTime::getLastErrors(); - - if (0 < $lastErrors['warning_count'] || 0 < $lastErrors['error_count']) { - throw new TransformationFailedException( - implode(', ', array_merge( - array_values($lastErrors['warnings']), - array_values($lastErrors['errors']) - )) - ); - } - // 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. @@ -224,8 +224,6 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer if ($this->inputTimezone !== $this->outputTimezone) { $dateTime->setTimezone(new \DateTimeZone($this->inputTimezone)); } - } catch (TransformationFailedException $e) { - throw $e; } catch (\Exception $e) { throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e); } From d9ac57123dff6d29e8e62d81cc06df7c4673be21 Mon Sep 17 00:00:00 2001 From: Alex Silcock Date: Thu, 8 Oct 2015 15:18:26 +0100 Subject: [PATCH 3/7] [HttpFoundation] Fixes /0 subnet handling in IpUtils --- src/Symfony/Component/HttpFoundation/IpUtils.php | 13 +++++++------ .../Component/HttpFoundation/Tests/IpUtilsTest.php | 6 +++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/IpUtils.php b/src/Symfony/Component/HttpFoundation/IpUtils.php index fb906b6812..e08301ece1 100644 --- a/src/Symfony/Component/HttpFoundation/IpUtils.php +++ b/src/Symfony/Component/HttpFoundation/IpUtils.php @@ -57,18 +57,19 @@ class IpUtils * @param string $requestIp IPv4 address to check * @param string $ip IPv4 address or subnet in CIDR notation * - * @return bool Whether the IP is valid + * @return bool Whether the request IP matches the IP, or whether the request IP is within the CIDR subnet. */ public static function checkIp4($requestIp, $ip) { if (false !== strpos($ip, '/')) { - if ('0.0.0.0/0' === $ip) { - return true; - } - list($address, $netmask) = explode('/', $ip, 2); - if ($netmask < 1 || $netmask > 32) { + if ($netmask === '0') { + // Ensure IP is valid - using ip2long below implicitly validates, but we need to do it manually here + return filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); + } + + if ($netmask < 0 || $netmask > 32) { return false; } } else { diff --git a/src/Symfony/Component/HttpFoundation/Tests/IpUtilsTest.php b/src/Symfony/Component/HttpFoundation/Tests/IpUtilsTest.php index 0002478246..e87baea34a 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/IpUtilsTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/IpUtilsTest.php @@ -30,13 +30,13 @@ class IpUtilsTest extends \PHPUnit_Framework_TestCase array(true, '192.168.1.1', '192.168.1.1/1'), array(true, '192.168.1.1', '192.168.1.0/24'), array(false, '192.168.1.1', '1.2.3.4/1'), - array(false, '192.168.1.1', '192.168.1/33'), + array(false, '192.168.1.1', '192.168.1.1/33'), // invalid subnet array(true, '192.168.1.1', array('1.2.3.4/1', '192.168.1.0/24')), array(true, '192.168.1.1', array('192.168.1.0/24', '1.2.3.4/1')), array(false, '192.168.1.1', array('1.2.3.4/1', '4.3.2.1/1')), array(true, '1.2.3.4', '0.0.0.0/0'), - array(false, '1.2.3.4', '256.256.256/0'), - array(false, '1.2.3.4', '192.168.1.0/0'), + array(true, '1.2.3.4', '192.168.1.0/0'), + array(false, '1.2.3.4', '256.256.256/0'), // invalid CIDR notation ); } From ab8cc29814c066c442899214bbccc889b188e114 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 19 Oct 2015 16:17:09 +0200 Subject: [PATCH 4/7] [Process] Inherit env vars by default in PhpProcess --- src/Symfony/Component/BrowserKit/Client.php | 3 +-- src/Symfony/Component/BrowserKit/composer.json | 2 +- .../Component/ClassLoader/ClassCollectionLoader.php | 2 +- src/Symfony/Component/Process/PhpProcess.php | 12 ++++++------ src/Symfony/Component/Process/Process.php | 4 ++-- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/Symfony/Component/BrowserKit/Client.php b/src/Symfony/Component/BrowserKit/Client.php index 95b6419db2..1370f1c838 100644 --- a/src/Symfony/Component/BrowserKit/Client.php +++ b/src/Symfony/Component/BrowserKit/Client.php @@ -334,8 +334,7 @@ abstract class Client */ protected function doRequestInProcess($request) { - // We set the TMPDIR (for Macs) and TEMP (for Windows), because on these platforms the temp directory changes based on the user. - $process = new PhpProcess($this->getScript($request), null, array('TMPDIR' => sys_get_temp_dir(), 'TEMP' => sys_get_temp_dir())); + $process = new PhpProcess($this->getScript($request), null, null); $process->run(); if (!$process->isSuccessful() || !preg_match('/^O\:\d+\:/', $process->getOutput())) { diff --git a/src/Symfony/Component/BrowserKit/composer.json b/src/Symfony/Component/BrowserKit/composer.json index 13ac1b9b68..429aa0cb07 100644 --- a/src/Symfony/Component/BrowserKit/composer.json +++ b/src/Symfony/Component/BrowserKit/composer.json @@ -20,7 +20,7 @@ "symfony/dom-crawler": "~2.0,>=2.0.5" }, "require-dev": { - "symfony/process": "~2.0,>=2.0.5", + "symfony/process": "~2.3.34|~2.7,>=2.7.6", "symfony/css-selector": "~2.0,>=2.0.5" }, "suggest": { diff --git a/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php b/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php index e576e5c62b..88bd500f1d 100644 --- a/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php +++ b/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php @@ -283,7 +283,7 @@ class ClassCollectionLoader $traits = array(); - if (function_exists('get_declared_traits')) { + if (method_exists('ReflectionClass', 'getTraits')) { foreach ($classes as $c) { foreach (self::resolveDependencies(self::computeTraitDeps($c), $c) as $trait) { if ($trait !== $c) { diff --git a/src/Symfony/Component/Process/PhpProcess.php b/src/Symfony/Component/Process/PhpProcess.php index e5777ea22a..1adbd977ad 100644 --- a/src/Symfony/Component/Process/PhpProcess.php +++ b/src/Symfony/Component/Process/PhpProcess.php @@ -27,13 +27,13 @@ class PhpProcess extends Process /** * Constructor. * - * @param string $script The PHP script to run (as a string) - * @param string $cwd The working directory - * @param array $env The environment variables - * @param int $timeout The timeout in seconds - * @param array $options An array of options for proc_open + * @param string $script The PHP script to run (as a string) + * @param string|null $cwd The working directory or null to use the working dir of the current PHP process + * @param array|null $env The environment variables or null to use the same environment as the current PHP process + * @param int $timeout The timeout in seconds + * @param array $options An array of options for proc_open */ - public function __construct($script, $cwd = null, array $env = array(), $timeout = 60, array $options = array()) + public function __construct($script, $cwd = null, array $env = null, $timeout = 60, array $options = array()) { $executableFinder = new PhpExecutableFinder(); if (false === $php = $executableFinder->find()) { diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index 64f6d15cb9..7580c17d82 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -121,7 +121,7 @@ class Process * * @param string $commandline The command line to run * @param string|null $cwd The working directory or null to use the working dir of the current PHP process - * @param array|null $env The environment variables or null to inherit + * @param array|null $env The environment variables or null to use the same environment as the current PHP process * @param string|null $stdin The STDIN content * @param int|float|null $timeout The timeout in seconds or null to disable * @param array $options An array of options for proc_open @@ -851,7 +851,7 @@ class Process $this->env = array(); foreach ($env as $key => $value) { - $this->env[(binary) $key] = (binary) $value; + $this->env[$key] = (string) $value; } return $this; From ad4d0eb79ab5ec006f9ae68bacdf43d2ee855e97 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Wed, 21 Oct 2015 14:43:04 +0200 Subject: [PATCH 5/7] Remove dead code in the PropertyPath constructor Custom singulars have been removed from the component before merging it in Symfony, but the code parsing them was only removed partially. --- .../Component/PropertyAccess/PropertyPath.php | 18 --------- .../Tests/PropertyAccessorCollectionTest.php | 39 ------------------- .../Tests/PropertyAccessorTest.php | 9 ----- 3 files changed, 66 deletions(-) diff --git a/src/Symfony/Component/PropertyAccess/PropertyPath.php b/src/Symfony/Component/PropertyAccess/PropertyPath.php index 9e44d8b752..4d964c2d8a 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyPath.php +++ b/src/Symfony/Component/PropertyAccess/PropertyPath.php @@ -36,13 +36,6 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface */ private $elements = array(); - /** - * The singular forms of the elements in the property path. - * - * @var array - */ - private $singulars = array(); - /** * The number of elements in the property path. * @@ -79,7 +72,6 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface if ($propertyPath instanceof self) { /* @var PropertyPath $propertyPath */ $this->elements = $propertyPath->elements; - $this->singulars = $propertyPath->singulars; $this->length = $propertyPath->length; $this->isIndex = $propertyPath->isIndex; $this->pathAsString = $propertyPath->pathAsString; @@ -110,16 +102,7 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface $this->isIndex[] = true; } - $pos = false; - $singular = null; - - if (false !== $pos) { - $singular = substr($element, $pos + 1); - $element = substr($element, 0, $pos); - } - $this->elements[] = $element; - $this->singulars[] = $singular; $position += strlen($matches[1]); $remaining = $matches[4]; @@ -168,7 +151,6 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface --$parent->length; $parent->pathAsString = substr($parent->pathAsString, 0, max(strrpos($parent->pathAsString, '.'), strrpos($parent->pathAsString, '['))); array_pop($parent->elements); - array_pop($parent->singulars); array_pop($parent->isIndex); return $parent; diff --git a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorCollectionTest.php b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorCollectionTest.php index 08e6e5e6d0..9f10b95e43 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorCollectionTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorCollectionTest.php @@ -46,21 +46,6 @@ class PropertyAccessorCollectionTest_Car } } -class PropertyAccessorCollectionTest_CarCustomSingular -{ - public function addFoo($axis) - { - } - - public function removeFoo($axis) - { - } - - public function getAxes() - { - } -} - class PropertyAccessorCollectionTest_Engine { } @@ -237,30 +222,6 @@ abstract class PropertyAccessorCollectionTest extends \PHPUnit_Framework_TestCas $this->propertyAccessor->setValue($car, 'structure.axes', $axesAfter); } - public function testSetValueCallsCustomAdderAndRemover() - { - $this->markTestSkipped('This feature is temporarily disabled as of 2.1'); - - $car = $this->getMock(__CLASS__.'_CarCustomSingular'); - $axesBefore = $this->getCollection(array(1 => 'second', 3 => 'fourth')); - $axesAfter = $this->getCollection(array(0 => 'first', 1 => 'second', 2 => 'third')); - - $car->expects($this->at(0)) - ->method('getAxes') - ->will($this->returnValue($axesBefore)); - $car->expects($this->at(1)) - ->method('removeFoo') - ->with('fourth'); - $car->expects($this->at(2)) - ->method('addFoo') - ->with('first'); - $car->expects($this->at(3)) - ->method('addFoo') - ->with('third'); - - $this->propertyAccessor->setValue($car, 'axes|foo', $axesAfter); - } - /** * @expectedException \Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException */ diff --git a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php index 87287048a7..5b127e1bc4 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php @@ -112,15 +112,6 @@ class PropertyAccessorTest extends \PHPUnit_Framework_TestCase $this->assertSame(array('Bernhard'), $object->firstName); } - public function testGetValueIgnoresSingular() - { - $this->markTestSkipped('This feature is temporarily disabled as of 2.1'); - - $object = (object) array('children' => 'Many'); - - $this->assertEquals('Many', $this->propertyAccessor->getValue($object, 'children|child')); - } - public function testGetValueReadsPropertyWithSpecialCharsExceptDot() { $array = (object) array('%!@$ยง' => 'Bernhard'); From 0249f2f295ae89a5f599c0d32518b2ae2b0306fb Mon Sep 17 00:00:00 2001 From: hadriengem Date: Thu, 22 Oct 2015 17:08:54 +0200 Subject: [PATCH 6/7] [DI] don't use array_map to resolve services --- .../Component/DependencyInjection/ContainerBuilder.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 8b677ddf75..2c4460f394 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -925,7 +925,9 @@ class ContainerBuilder extends Container implements TaggedContainerInterface public function resolveServices($value) { if (is_array($value)) { - $value = array_map(array($this, 'resolveServices'), $value); + foreach ($value as $k => $v) { + $value[$k] = $this->resolveServices($v); + } } elseif ($value instanceof Reference) { $value = $this->get((string) $value, $value->getInvalidBehavior()); } elseif ($value instanceof Definition) { From b21d498fd39c5995668b98adf95d4795be44e9e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1chym=20Tou=C5=A1ek?= Date: Tue, 20 Oct 2015 23:50:39 +0200 Subject: [PATCH 7/7] [DoctrineBridge] Fix required guess of boolean fields --- .../Doctrine/Form/DoctrineOrmTypeGuesser.php | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php index ccd8a25f16..e66862e72e 100644 --- a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php +++ b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php @@ -12,8 +12,9 @@ namespace Symfony\Bridge\Doctrine\Form; use Doctrine\Common\Persistence\ManagerRegistry; -use Doctrine\ORM\Mapping\ClassMetadataInfo; use Doctrine\Common\Persistence\Mapping\MappingException; +use Doctrine\DBAL\Types\Type; +use Doctrine\ORM\Mapping\ClassMetadataInfo; use Doctrine\ORM\Mapping\MappingException as LegacyMappingException; use Symfony\Component\Form\FormTypeGuesserInterface; use Symfony\Component\Form\Guess\Guess; @@ -52,28 +53,28 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface } switch ($metadata->getTypeOfField($property)) { - case 'array': + case Type::TARRAY: return new TypeGuess('collection', array(), Guess::MEDIUM_CONFIDENCE); - case 'boolean': + case Type::BOOLEAN: return new TypeGuess('checkbox', array(), Guess::HIGH_CONFIDENCE); - case 'datetime': + case Type::DATETIME: + case Type::DATETIMETZ: case 'vardatetime': - case 'datetimetz': return new TypeGuess('datetime', array(), Guess::HIGH_CONFIDENCE); - case 'date': + case Type::DATE: return new TypeGuess('date', array(), Guess::HIGH_CONFIDENCE); - case 'time': + case Type::TIME: return new TypeGuess('time', array(), Guess::HIGH_CONFIDENCE); - case 'decimal': - case 'float': + case Type::DECIMAL: + case Type::FLOAT: return new TypeGuess('number', array(), Guess::MEDIUM_CONFIDENCE); - case 'integer': - case 'bigint': - case 'smallint': + case Type::INTEGER: + case Type::BIGINT: + case Type::SMALLINT: return new TypeGuess('integer', array(), Guess::MEDIUM_CONFIDENCE); - case 'string': + case Type::STRING: return new TypeGuess('text', array(), Guess::MEDIUM_CONFIDENCE); - case 'text': + case Type::TEXT: return new TypeGuess('textarea', array(), Guess::MEDIUM_CONFIDENCE); default: return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE); @@ -96,7 +97,7 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface // Check whether the field exists and is nullable or not if ($classMetadata->hasField($property)) { - if (!$classMetadata->isNullable($property)) { + if (!$classMetadata->isNullable($property) && Type::BOOLEAN !== $classMetadata->getTypeOfField($property)) { return new ValueGuess(true, Guess::HIGH_CONFIDENCE); } @@ -131,7 +132,7 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface return new ValueGuess($mapping['length'], Guess::HIGH_CONFIDENCE); } - if (in_array($ret[0]->getTypeOfField($property), array('decimal', 'float'))) { + if (in_array($ret[0]->getTypeOfField($property), array(Type::DECIMAL, Type::FLOAT))) { return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE); } } @@ -144,7 +145,7 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface { $ret = $this->getMetadata($class); if ($ret && $ret[0]->hasField($property) && !$ret[0]->hasAssociation($property)) { - if (in_array($ret[0]->getTypeOfField($property), array('decimal', 'float'))) { + if (in_array($ret[0]->getTypeOfField($property), array(Type::DECIMAL, Type::FLOAT))) { return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE); } }