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:
commit
86b99ab64a
@ -12,8 +12,9 @@
|
|||||||
namespace Symfony\Bridge\Doctrine\Form;
|
namespace Symfony\Bridge\Doctrine\Form;
|
||||||
|
|
||||||
use Doctrine\Common\Persistence\ManagerRegistry;
|
use Doctrine\Common\Persistence\ManagerRegistry;
|
||||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
|
||||||
use Doctrine\Common\Persistence\Mapping\MappingException;
|
use Doctrine\Common\Persistence\Mapping\MappingException;
|
||||||
|
use Doctrine\DBAL\Types\Type;
|
||||||
|
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||||
use Doctrine\ORM\Mapping\MappingException as LegacyMappingException;
|
use Doctrine\ORM\Mapping\MappingException as LegacyMappingException;
|
||||||
use Symfony\Component\Form\FormTypeGuesserInterface;
|
use Symfony\Component\Form\FormTypeGuesserInterface;
|
||||||
use Symfony\Component\Form\Guess\Guess;
|
use Symfony\Component\Form\Guess\Guess;
|
||||||
@ -51,28 +52,28 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch ($metadata->getTypeOfField($property)) {
|
switch ($metadata->getTypeOfField($property)) {
|
||||||
case 'array':
|
case Type::TARRAY:
|
||||||
return new TypeGuess('collection', array(), Guess::MEDIUM_CONFIDENCE);
|
return new TypeGuess('collection', array(), Guess::MEDIUM_CONFIDENCE);
|
||||||
case 'boolean':
|
case Type::BOOLEAN:
|
||||||
return new TypeGuess('checkbox', array(), Guess::HIGH_CONFIDENCE);
|
return new TypeGuess('checkbox', array(), Guess::HIGH_CONFIDENCE);
|
||||||
case 'datetime':
|
case Type::DATETIME:
|
||||||
|
case Type::DATETIMETZ:
|
||||||
case 'vardatetime':
|
case 'vardatetime':
|
||||||
case 'datetimetz':
|
|
||||||
return new TypeGuess('datetime', array(), Guess::HIGH_CONFIDENCE);
|
return new TypeGuess('datetime', array(), Guess::HIGH_CONFIDENCE);
|
||||||
case 'date':
|
case Type::DATE:
|
||||||
return new TypeGuess('date', array(), Guess::HIGH_CONFIDENCE);
|
return new TypeGuess('date', array(), Guess::HIGH_CONFIDENCE);
|
||||||
case 'time':
|
case Type::TIME:
|
||||||
return new TypeGuess('time', array(), Guess::HIGH_CONFIDENCE);
|
return new TypeGuess('time', array(), Guess::HIGH_CONFIDENCE);
|
||||||
case 'decimal':
|
case Type::DECIMAL:
|
||||||
case 'float':
|
case Type::FLOAT:
|
||||||
return new TypeGuess('number', array(), Guess::MEDIUM_CONFIDENCE);
|
return new TypeGuess('number', array(), Guess::MEDIUM_CONFIDENCE);
|
||||||
case 'integer':
|
case Type::INTEGER:
|
||||||
case 'bigint':
|
case Type::BIGINT:
|
||||||
case 'smallint':
|
case Type::SMALLINT:
|
||||||
return new TypeGuess('integer', array(), Guess::MEDIUM_CONFIDENCE);
|
return new TypeGuess('integer', array(), Guess::MEDIUM_CONFIDENCE);
|
||||||
case 'string':
|
case Type::STRING:
|
||||||
return new TypeGuess('text', array(), Guess::MEDIUM_CONFIDENCE);
|
return new TypeGuess('text', array(), Guess::MEDIUM_CONFIDENCE);
|
||||||
case 'text':
|
case Type::TEXT:
|
||||||
return new TypeGuess('textarea', array(), Guess::MEDIUM_CONFIDENCE);
|
return new TypeGuess('textarea', array(), Guess::MEDIUM_CONFIDENCE);
|
||||||
default:
|
default:
|
||||||
return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE);
|
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
|
// Check whether the field exists and is nullable or not
|
||||||
if ($classMetadata->hasField($property)) {
|
if ($classMetadata->hasField($property)) {
|
||||||
if (!$classMetadata->isNullable($property)) {
|
if (!$classMetadata->isNullable($property) && Type::BOOLEAN !== $classMetadata->getTypeOfField($property)) {
|
||||||
return new ValueGuess(true, Guess::HIGH_CONFIDENCE);
|
return new ValueGuess(true, Guess::HIGH_CONFIDENCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +131,7 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface
|
|||||||
return new ValueGuess($mapping['length'], Guess::HIGH_CONFIDENCE);
|
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);
|
return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,7 +144,7 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface
|
|||||||
{
|
{
|
||||||
$ret = $this->getMetadata($class);
|
$ret = $this->getMetadata($class);
|
||||||
if ($ret && $ret[0]->hasField($property) && !$ret[0]->hasAssociation($property)) {
|
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);
|
return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -327,8 +327,7 @@ abstract class Client
|
|||||||
*/
|
*/
|
||||||
protected function doRequestInProcess($request)
|
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, null);
|
||||||
$process = new PhpProcess($this->getScript($request), null, array('TMPDIR' => sys_get_temp_dir(), 'TEMP' => sys_get_temp_dir()));
|
|
||||||
$process->run();
|
$process->run();
|
||||||
|
|
||||||
if (!$process->isSuccessful() || !preg_match('/^O\:\d+\:/', $process->getOutput())) {
|
if (!$process->isSuccessful() || !preg_match('/^O\:\d+\:/', $process->getOutput())) {
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
"symfony/dom-crawler": "~2.0,>=2.0.5"
|
"symfony/dom-crawler": "~2.0,>=2.0.5"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"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"
|
"symfony/css-selector": "~2.0,>=2.0.5"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
|
@ -283,7 +283,7 @@ class ClassCollectionLoader
|
|||||||
|
|
||||||
$traits = array();
|
$traits = array();
|
||||||
|
|
||||||
if (function_exists('get_declared_traits')) {
|
if (method_exists('ReflectionClass', 'getTraits')) {
|
||||||
foreach ($classes as $c) {
|
foreach ($classes as $c) {
|
||||||
foreach (self::resolveDependencies(self::computeTraitDeps($c), $c) as $trait) {
|
foreach (self::resolveDependencies(self::computeTraitDeps($c), $c) as $trait) {
|
||||||
if ($trait !== $c) {
|
if ($trait !== $c) {
|
||||||
|
@ -938,7 +938,9 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
public function resolveServices($value)
|
public function resolveServices($value)
|
||||||
{
|
{
|
||||||
if (is_array($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) {
|
} elseif ($value instanceof Reference) {
|
||||||
$value = $this->get((string) $value, $value->getInvalidBehavior());
|
$value = $this->get((string) $value, $value->getInvalidBehavior());
|
||||||
} elseif ($value instanceof Definition) {
|
} elseif ($value instanceof Definition) {
|
||||||
|
@ -86,7 +86,7 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer
|
|||||||
* Transforms a DateTime object into a date string with the configured format
|
* Transforms a DateTime object into a date string with the configured format
|
||||||
* and timezone.
|
* 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
|
* @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.');
|
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 {
|
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
|
// On PHP versions < 5.3.7 we need to emulate the pipe operator
|
||||||
// and reset parts not given in the format to their equivalent
|
// and reset parts not given in the format to their equivalent
|
||||||
// of the UNIX base timestamp.
|
// of the UNIX base timestamp.
|
||||||
@ -220,8 +220,6 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer
|
|||||||
if ($this->inputTimezone !== $this->outputTimezone) {
|
if ($this->inputTimezone !== $this->outputTimezone) {
|
||||||
$dateTime->setTimezone(new \DateTimeZone($this->inputTimezone));
|
$dateTime->setTimezone(new \DateTimeZone($this->inputTimezone));
|
||||||
}
|
}
|
||||||
} catch (TransformationFailedException $e) {
|
|
||||||
throw $e;
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
|
throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
|
||||||
}
|
}
|
||||||
|
@ -57,18 +57,19 @@ class IpUtils
|
|||||||
* @param string $requestIp IPv4 address to check
|
* @param string $requestIp IPv4 address to check
|
||||||
* @param string $ip IPv4 address or subnet in CIDR notation
|
* @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)
|
public static function checkIp4($requestIp, $ip)
|
||||||
{
|
{
|
||||||
if (false !== strpos($ip, '/')) {
|
if (false !== strpos($ip, '/')) {
|
||||||
if ('0.0.0.0/0' === $ip) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
list($address, $netmask) = explode('/', $ip, 2);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -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.1/1'),
|
||||||
array(true, '192.168.1.1', '192.168.1.0/24'),
|
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', '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('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(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(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(true, '1.2.3.4', '0.0.0.0/0'),
|
||||||
array(false, '1.2.3.4', '256.256.256/0'),
|
array(true, '1.2.3.4', '192.168.1.0/0'),
|
||||||
array(false, '1.2.3.4', '192.168.1.0/0'),
|
array(false, '1.2.3.4', '256.256.256/0'), // invalid CIDR notation
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,12 +19,6 @@ use Symfony\Component\HttpKernel\UriSigner;
|
|||||||
|
|
||||||
class EsiFragmentRendererTest extends \PHPUnit_Framework_TestCase
|
class EsiFragmentRendererTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
public function testRenderFallbackToInlineStrategyIfNoRequest()
|
|
||||||
{
|
|
||||||
$strategy = new EsiFragmentRenderer(new Esi(), $this->getInlineStrategy(true));
|
|
||||||
$strategy->render('/', Request::create('/'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testRenderFallbackToInlineStrategyIfEsiNotSupported()
|
public function testRenderFallbackToInlineStrategyIfEsiNotSupported()
|
||||||
{
|
{
|
||||||
$strategy = new EsiFragmentRenderer(new Esi(), $this->getInlineStrategy(true));
|
$strategy = new EsiFragmentRenderer(new Esi(), $this->getInlineStrategy(true));
|
||||||
|
@ -27,13 +27,13 @@ class PhpProcess extends Process
|
|||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param string $script The PHP script to run (as a string)
|
* @param string $script The PHP script to run (as a string)
|
||||||
* @param string $cwd The working directory
|
* @param string|null $cwd The working directory or null to use the working dir of the current PHP process
|
||||||
* @param array $env The environment variables
|
* @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 int $timeout The timeout in seconds
|
||||||
* @param array $options An array of options for proc_open
|
* @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();
|
$executableFinder = new PhpExecutableFinder();
|
||||||
if (false === $php = $executableFinder->find()) {
|
if (false === $php = $executableFinder->find()) {
|
||||||
|
@ -131,7 +131,7 @@ class Process
|
|||||||
*
|
*
|
||||||
* @param string $commandline The command line to run
|
* @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 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 string|null $input The input
|
||||||
* @param int|float|null $timeout The timeout in seconds or null to disable
|
* @param int|float|null $timeout The timeout in seconds or null to disable
|
||||||
* @param array $options An array of options for proc_open
|
* @param array $options An array of options for proc_open
|
||||||
@ -1030,7 +1030,7 @@ class Process
|
|||||||
|
|
||||||
$this->env = array();
|
$this->env = array();
|
||||||
foreach ($env as $key => $value) {
|
foreach ($env as $key => $value) {
|
||||||
$this->env[(binary) $key] = (binary) $value;
|
$this->env[$key] = (string) $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -36,13 +36,6 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface
|
|||||||
*/
|
*/
|
||||||
private $elements = array();
|
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.
|
* The number of elements in the property path.
|
||||||
*
|
*
|
||||||
@ -79,7 +72,6 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface
|
|||||||
if ($propertyPath instanceof self) {
|
if ($propertyPath instanceof self) {
|
||||||
/* @var PropertyPath $propertyPath */
|
/* @var PropertyPath $propertyPath */
|
||||||
$this->elements = $propertyPath->elements;
|
$this->elements = $propertyPath->elements;
|
||||||
$this->singulars = $propertyPath->singulars;
|
|
||||||
$this->length = $propertyPath->length;
|
$this->length = $propertyPath->length;
|
||||||
$this->isIndex = $propertyPath->isIndex;
|
$this->isIndex = $propertyPath->isIndex;
|
||||||
$this->pathAsString = $propertyPath->pathAsString;
|
$this->pathAsString = $propertyPath->pathAsString;
|
||||||
@ -115,16 +107,7 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface
|
|||||||
$this->isIndex[] = true;
|
$this->isIndex[] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$pos = false;
|
|
||||||
$singular = null;
|
|
||||||
|
|
||||||
if (false !== $pos) {
|
|
||||||
$singular = substr($element, $pos + 1);
|
|
||||||
$element = substr($element, 0, $pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->elements[] = $element;
|
$this->elements[] = $element;
|
||||||
$this->singulars[] = $singular;
|
|
||||||
|
|
||||||
$position += strlen($matches[1]);
|
$position += strlen($matches[1]);
|
||||||
$remaining = $matches[4];
|
$remaining = $matches[4];
|
||||||
@ -173,7 +156,6 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface
|
|||||||
--$parent->length;
|
--$parent->length;
|
||||||
$parent->pathAsString = substr($parent->pathAsString, 0, max(strrpos($parent->pathAsString, '.'), strrpos($parent->pathAsString, '[')));
|
$parent->pathAsString = substr($parent->pathAsString, 0, max(strrpos($parent->pathAsString, '.'), strrpos($parent->pathAsString, '[')));
|
||||||
array_pop($parent->elements);
|
array_pop($parent->elements);
|
||||||
array_pop($parent->singulars);
|
|
||||||
array_pop($parent->isIndex);
|
array_pop($parent->isIndex);
|
||||||
|
|
||||||
return $parent;
|
return $parent;
|
||||||
|
Reference in New Issue
Block a user