Merge branch '2.3' into 2.7

* 2.3:
  [DoctrineBridge] Fix required guess of boolean fields
  [DI] don't use array_map to resolve services
  Remove dead code in the PropertyPath constructor
  [Process] Inherit env vars by default in PhpProcess
  [HttpFoundation] Fixes /0 subnet handling in IpUtils
  [Form] Simplify DateTimeToStringTransformer Avoid unneeded catch and re-throw of the same exception.
  [HttpKernel] Remove a duplicate test for the EsiFragmentRenderer

Conflicts:
	src/Symfony/Component/Process/Process.php
	src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorCollectionTest.php
	src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php
This commit is contained in:
Nicolas Grekas 2015-10-23 16:47:27 +02:00
commit 86b99ab64a
12 changed files with 57 additions and 80 deletions

View File

@ -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;
@ -51,28 +52,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);
@ -95,7 +96,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);
}
@ -130,7 +131,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);
}
}
@ -143,7 +144,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);
}
}

View File

@ -327,8 +327,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())) {

View File

@ -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": {

View File

@ -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) {

View File

@ -938,7 +938,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) {

View File

@ -86,7 +86,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
*
@ -138,21 +138,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.
@ -220,8 +220,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);
}

View File

@ -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 {

View File

@ -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
);
}

View File

@ -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));

View File

@ -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()) {

View File

@ -131,7 +131,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 $input The input
* @param int|float|null $timeout The timeout in seconds or null to disable
* @param array $options An array of options for proc_open
@ -1030,7 +1030,7 @@ class Process
$this->env = array();
foreach ($env as $key => $value) {
$this->env[(binary) $key] = (binary) $value;
$this->env[$key] = (string) $value;
}
return $this;

View File

@ -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;
@ -115,16 +107,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];
@ -173,7 +156,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;