Merge branch '2.7' into 2.8

* 2.7:
  [Process] Fix stream_select priority when writing to stdin
  [Form] NumberToLocalizedStringTransformer should return floats when possible
  [Form] remove useless code in ChoiceType
  [DependencyInjection] Enabled alias for service_container

Conflicts:
	src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php
This commit is contained in:
Nicolas Grekas 2016-03-31 10:07:27 +02:00
commit f7010ce180
9 changed files with 49 additions and 35 deletions

View File

@ -42,6 +42,10 @@ class ReplaceAliasByActualDefinitionPass implements CompilerPassInterface
foreach ($container->getAliases() as $id => $alias) { foreach ($container->getAliases() as $id => $alias) {
$aliasId = (string) $alias; $aliasId = (string) $alias;
if ('service_container' === $aliasId) {
continue;
}
try { try {
$definition = $container->getDefinition($aliasId); $definition = $container->getDefinition($aliasId);
} catch (InvalidArgumentException $e) { } catch (InvalidArgumentException $e) {

View File

@ -36,6 +36,8 @@ class ReplaceAliasByActualDefinitionPassTest extends \PHPUnit_Framework_TestCase
$container->setAlias('a_alias', 'a'); $container->setAlias('a_alias', 'a');
$container->setAlias('b_alias', 'b'); $container->setAlias('b_alias', 'b');
$container->setAlias('container', 'service_container');
$this->process($container); $this->process($container);
$this->assertTrue($container->has('a'), '->process() does nothing to public definitions.'); $this->assertTrue($container->has('a'), '->process() does nothing to public definitions.');
@ -47,6 +49,7 @@ class ReplaceAliasByActualDefinitionPassTest extends \PHPUnit_Framework_TestCase
); );
$this->assertSame('b_alias', $aDefinition->getFactoryService(false)); $this->assertSame('b_alias', $aDefinition->getFactoryService(false));
$this->assertTrue($container->has('container'));
$resolvedFactory = $aDefinition->getFactory(false); $resolvedFactory = $aDefinition->getFactory(false);
$this->assertSame('b_alias', (string) $resolvedFactory[0]); $this->assertSame('b_alias', (string) $resolvedFactory[0]);

View File

@ -205,6 +205,10 @@ class NumberToLocalizedStringTransformer implements DataTransformerInterface
throw new TransformationFailedException('I don\'t have a clear idea what infinity looks like'); throw new TransformationFailedException('I don\'t have a clear idea what infinity looks like');
} }
if (is_int($result) && $result === (int) $float = (float) $result) {
$result = $float;
}
if (false !== $encoding = mb_detect_encoding($value, null, true)) { if (false !== $encoding = mb_detect_encoding($value, null, true)) {
$length = mb_strlen($value, $encoding); $length = mb_strlen($value, $encoding);
$remainder = mb_substr($value, $position, $length, $encoding); $remainder = mb_substr($value, $position, $length, $encoding);

View File

@ -429,7 +429,7 @@ class ChoiceType extends AbstractType
$resolver->setAllowedTypes('choice_value', array('null', 'callable', 'string', 'Symfony\Component\PropertyAccess\PropertyPath')); $resolver->setAllowedTypes('choice_value', array('null', 'callable', 'string', 'Symfony\Component\PropertyAccess\PropertyPath'));
$resolver->setAllowedTypes('choice_attr', array('null', 'array', 'callable', 'string', 'Symfony\Component\PropertyAccess\PropertyPath')); $resolver->setAllowedTypes('choice_attr', array('null', 'array', 'callable', 'string', 'Symfony\Component\PropertyAccess\PropertyPath'));
$resolver->setAllowedTypes('preferred_choices', array('array', '\Traversable', 'callable', 'string', 'Symfony\Component\PropertyAccess\PropertyPath')); $resolver->setAllowedTypes('preferred_choices', array('array', '\Traversable', 'callable', 'string', 'Symfony\Component\PropertyAccess\PropertyPath'));
$resolver->setAllowedTypes('group_by', array('null', 'array', '\Traversable', 'callable', 'string', 'Symfony\Component\PropertyAccess\PropertyPath')); $resolver->setAllowedTypes('group_by', array('null', 'callable', 'string', 'Symfony\Component\PropertyAccess\PropertyPath'));
} }
/** /**
@ -448,21 +448,6 @@ class ChoiceType extends AbstractType
return 'choice'; return 'choice';
} }
private static function flipRecursive($choices, &$output = array())
{
foreach ($choices as $key => $value) {
if (is_array($value)) {
$output[$key] = array();
self::flipRecursive($value, $output[$key]);
continue;
}
$output[$value] = $key;
}
return $output;
}
/** /**
* Adds the sub fields for an expanded choice field. * Adds the sub fields for an expanded choice field.
* *
@ -520,14 +505,6 @@ class ChoiceType extends AbstractType
private function createChoiceListView(ChoiceListInterface $choiceList, array $options) private function createChoiceListView(ChoiceListInterface $choiceList, array $options)
{ {
// If no explicit grouping information is given, use the structural
// information from the "choices" option for creating groups
if (!$options['group_by'] && $options['choices']) {
$options['group_by'] = !$options['choices_as_values']
? self::flipRecursive($options['choices'])
: $options['choices'];
}
return $this->choiceListFactory->createView( return $this->choiceListFactory->createView(
$choiceList, $choiceList,
$options['preferred_choices'], $options['preferred_choices'],

View File

@ -637,10 +637,17 @@ class NumberToLocalizedStringTransformerTest extends \PHPUnit_Framework_TestCase
$transformer->reverseTransform("12\xc2\xa0345,678foo"); $transformer->reverseTransform("12\xc2\xa0345,678foo");
} }
public function testReverseTransformBigint() public function testReverseTransformBigInt()
{ {
$transformer = new NumberToLocalizedStringTransformer(null, true); $transformer = new NumberToLocalizedStringTransformer(null, true);
$this->assertEquals(PHP_INT_MAX - 1, (int) $transformer->reverseTransform((string) (PHP_INT_MAX - 1))); $this->assertEquals(PHP_INT_MAX - 1, (int) $transformer->reverseTransform((string) (PHP_INT_MAX - 1)));
} }
public function testReverseTransformSmallInt()
{
$transformer = new NumberToLocalizedStringTransformer(null, true);
$this->assertSame(1.0, $transformer->reverseTransform('1'));
}
} }

View File

@ -22,10 +22,9 @@ abstract class AbstractPipes implements PipesInterface
public $pipes = array(); public $pipes = array();
/** @var string */ /** @var string */
protected $inputBuffer = ''; private $inputBuffer = '';
/** @var resource|null */ /** @var resource|null */
protected $input; private $input;
/** @var bool */ /** @var bool */
private $blocked = true; private $blocked = true;
@ -91,9 +90,8 @@ abstract class AbstractPipes implements PipesInterface
if (!isset($this->pipes[0])) { if (!isset($this->pipes[0])) {
return; return;
} }
$input = $this->input;
$e = array(); $r = $e = array();
$r = null !== $this->input ? array($this->input) : $e;
$w = array($this->pipes[0]); $w = array($this->pipes[0]);
// let's have a look if something changed in streams // let's have a look if something changed in streams
@ -110,7 +108,7 @@ abstract class AbstractPipes implements PipesInterface
} }
} }
foreach ($r as $input) { if ($input) {
for (;;) { for (;;) {
$data = fread($input, self::CHUNK_SIZE); $data = fread($input, self::CHUNK_SIZE);
if (!isset($data[0])) { if (!isset($data[0])) {
@ -124,7 +122,7 @@ abstract class AbstractPipes implements PipesInterface
return array($this->pipes[0]); return array($this->pipes[0]);
} }
} }
if (!isset($data[0]) && feof($input)) { if (feof($input)) {
// no more data to read on input resource // no more data to read on input resource
// use an empty buffer in the next reads // use an empty buffer in the next reads
$this->input = null; $this->input = null;

View File

@ -158,7 +158,7 @@ class Process
$this->setEnv($env); $this->setEnv($env);
} }
$this->input = $input; $this->setInput($input);
$this->setTimeout($timeout); $this->setTimeout($timeout);
$this->useFileHandles = '\\' === DIRECTORY_SEPARATOR; $this->useFileHandles = '\\' === DIRECTORY_SEPARATOR;
$this->pty = false; $this->pty = false;

View File

@ -80,7 +80,7 @@ class ProcessUtils
* @param string $caller The name of method call that validates the input * @param string $caller The name of method call that validates the input
* @param mixed $input The input to validate * @param mixed $input The input to validate
* *
* @return string The validated input * @return mixed The validated input
* *
* @throws InvalidArgumentException In case the input is not valid * @throws InvalidArgumentException In case the input is not valid
* *
@ -92,6 +92,9 @@ class ProcessUtils
if (is_resource($input)) { if (is_resource($input)) {
return $input; return $input;
} }
if (is_string($input)) {
return $input;
}
if (is_scalar($input)) { if (is_scalar($input)) {
return (string) $input; return (string) $input;
} }

View File

@ -209,6 +209,24 @@ class ProcessTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($expectedLength, strlen($p->getErrorOutput())); $this->assertEquals($expectedLength, strlen($p->getErrorOutput()));
} }
public function testLiveStreamAsInput()
{
$stream = fopen('php://memory', 'r+');
fwrite($stream, 'hello');
rewind($stream);
$p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('stream_copy_to_stream(STDIN, STDOUT);')));
$p->setInput($stream);
$p->start(function ($type, $data) use ($stream) {
if ('hello' === $data) {
fclose($stream);
}
});
$p->wait();
$this->assertSame('hello', $p->getOutput());
}
/** /**
* @expectedException \Symfony\Component\Process\Exception\LogicException * @expectedException \Symfony\Component\Process\Exception\LogicException
* @expectedExceptionMessage Input can not be set while the process is running. * @expectedExceptionMessage Input can not be set while the process is running.