diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php
index c2fa9daebf..9cf636df95 100644
--- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php
+++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php
@@ -329,7 +329,7 @@ class EntityChoiceList extends ObjectChoiceList
protected function createIndex($entity)
{
if ($this->idAsIndex) {
- return current($this->getIdentifierValues($entity));
+ return $this->fixIndex(current($this->getIdentifierValues($entity)));
}
return parent::createIndex($entity);
@@ -355,6 +355,23 @@ class EntityChoiceList extends ObjectChoiceList
return parent::createValue($entity);
}
+ /**
+ * {@inheritdoc}
+ */
+ protected function fixIndex($index)
+ {
+ $index = parent::fixIndex($index);
+
+ // If the ID is a single-field integer identifier, it is used as
+ // index. Replace any leading minus by underscore to make it a valid
+ // form name.
+ if ($this->idAsIndex && $index < 0) {
+ $index = strtr($index, '-', '_');
+ }
+
+ return $index;
+ }
+
/**
* Loads the list with entities.
*/
diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/EntityChoiceListTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/EntityChoiceListTest.php
index f928f1f385..a3ce750343 100644
--- a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/EntityChoiceListTest.php
+++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/EntityChoiceListTest.php
@@ -312,4 +312,47 @@ class EntityChoiceListTest extends DoctrineOrmTestCase
$this->assertSame(array(0 => $entity1, 1 => $entity2), $choiceList->getChoices());
}
+
+ public function testMinusReplacedByUnderscoreInNegativeIntIds()
+ {
+ $entity1 = new SingleIdentEntity(-1, 'Foo');
+ $entity2 = new SingleIdentEntity(1, 'Bar');
+
+ // Persist for managed state
+ $this->em->persist($entity1);
+ $this->em->persist($entity2);
+ $this->em->flush();
+
+ $choiceList = new EntityChoiceList(
+ $this->em,
+ self::SINGLE_IDENT_CLASS,
+ 'name'
+ );
+
+ $this->assertSame(array('_1' => $entity1, 1 => $entity2), $choiceList->getChoices());
+ $this->assertSame(array('_1', 1), $choiceList->getIndicesForChoices(array($entity1, $entity2)));
+ $this->assertSame(array('_1', 1), $choiceList->getIndicesForValues(array('-1', '1')));
+ }
+
+ public function testMinusReplacedByUnderscoreIfNotLoaded()
+ {
+ $entity1 = new SingleIdentEntity(-1, 'Foo');
+ $entity2 = new SingleIdentEntity(1, 'Bar');
+
+ // Persist for managed state
+ $this->em->persist($entity1);
+ $this->em->persist($entity2);
+ $this->em->flush();
+
+ $choiceList = new EntityChoiceList(
+ $this->em,
+ self::SINGLE_IDENT_CLASS,
+ 'name'
+ );
+
+ // no getChoices()!
+
+ $this->assertSame(array('_1', 1), $choiceList->getIndicesForChoices(array($entity1, $entity2)));
+ $this->assertSame(array('_1', 1), $choiceList->getIndicesForValues(array('-1', '1')));
+ }
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/esi.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/esi.xml
index 9e1d57f921..3038f40e97 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/esi.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/esi.xml
@@ -13,8 +13,8 @@
-
-
+
+
diff --git a/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/trace.html.twig b/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/trace.html.twig
index 37b2ecc2b4..d4a11e1e50 100644
--- a/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/trace.html.twig
+++ b/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/trace.html.twig
@@ -12,8 +12,8 @@
in {{ trace.file|format_file(trace.line) }}
{% spaceless %}
-
-
+
+
{% endspaceless %}
diff --git a/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.html.twig b/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.html.twig
index e9359959d2..e0f1a0db13 100644
--- a/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.html.twig
+++ b/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/traces.html.twig
@@ -5,8 +5,8 @@
{{ exception.class|abbr_class }}: {{ exception.message|nl2br|format_file_from_text }}
{% spaceless %}
-
-
+
+
{% endspaceless %}
diff --git a/src/Symfony/Component/Console/Formatter/OutputFormatter.php b/src/Symfony/Component/Console/Formatter/OutputFormatter.php
index a7ac648af1..642590dcbc 100644
--- a/src/Symfony/Component/Console/Formatter/OutputFormatter.php
+++ b/src/Symfony/Component/Console/Formatter/OutputFormatter.php
@@ -23,7 +23,7 @@ class OutputFormatter implements OutputFormatterInterface
/**
* The pattern to phrase the format.
*/
- const FORMAT_PATTERN = '#(\\\\?)<(/?)([a-z][a-z0-9_=;-]+)?>((?:(?!\\\\?<).)*)#is';
+ const FORMAT_PATTERN = '#(\\\\?)<(/?)([a-z][a-z0-9_=;-]+)?>((?: [^<\\\\]+ | (?!<(?:/?[a-z]|/>)). | .(?<=\\\\<) )*)#isx';
private $decorated;
private $styles = array();
diff --git a/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php b/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php
index 33187a7d26..497630e87c 100644
--- a/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php
+++ b/src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php
@@ -73,6 +73,26 @@ class FormatterStyleTest extends \PHPUnit_Framework_TestCase
);
}
+ public function testStyleMatchingNotGreedy()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals(
+ "(\033[32m>=2.0,<2.3\033[0m)",
+ $formatter->format('(
>=2.0,<2.3)')
+ );
+ }
+
+ public function testStyleEscaping()
+ {
+ $formatter = new OutputFormatter(true);
+
+ $this->assertEquals(
+ "(\033[32mz>=2.0,
format('('.$formatter->escape('z>=2.0,)')
+ );
+ }
+
public function testDeepNestedStyles()
{
$formatter = new OutputFormatter(true);
diff --git a/src/Symfony/Component/CssSelector/Tests/TokenizerTest.php b/src/Symfony/Component/CssSelector/Tests/TokenizerTest.php
index b15de9dca1..e0e00d8ed3 100644
--- a/src/Symfony/Component/CssSelector/Tests/TokenizerTest.php
+++ b/src/Symfony/Component/CssSelector/Tests/TokenizerTest.php
@@ -34,6 +34,7 @@ class TokenizerTest extends \PHPUnit_Framework_TestCase
{
$this->assertEquals('foo[class=foo bar ]', $this->tokensToString($this->tokenizer->tokenize('foo[class="foo bar"]')), '->tokenize() lexes an input string and returns an array of tokens');
$this->assertEquals("foo[class=foo Abar ]", $this->tokensToString($this->tokenizer->tokenize('foo[class="foo \\65 bar"]')), '->tokenize() lexes an input string and returns an array of tokens');
+ $this->assertEquals("img[alt= ]", $this->tokensToString($this->tokenizer->tokenize('img[alt=""]')), '->tokenize() lexes an input string and returns an array of tokens');
}
/**
diff --git a/src/Symfony/Component/CssSelector/Tokenizer.php b/src/Symfony/Component/CssSelector/Tokenizer.php
index 67d5b67470..34e8ac580a 100644
--- a/src/Symfony/Component/CssSelector/Tokenizer.php
+++ b/src/Symfony/Component/CssSelector/Tokenizer.php
@@ -129,7 +129,7 @@ class Tokenizer
}
$result = substr($s, $start, $next - $start);
- if ('\\' === $result[strlen($result) - 1]) {
+ if (strlen($result) > 0 && '\\' === $result[strlen($result) - 1]) {
// next quote character is escaped
$pos = $next + 1;
continue;
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php
index c69d078e8b..6fad9a2841 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php
@@ -89,7 +89,7 @@ class ResolveInvalidReferencesPass implements CompilerPassInterface
// resolve invalid behavior
if ($exists && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) {
- $arguments[$k] = new Reference($id);
+ $arguments[$k] = new Reference($id, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $argument->isStrict());
} elseif (!$exists && ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) {
$arguments[$k] = null;
} elseif (!$exists && ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) {
diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
index a0740a964c..22aabf2745 100644
--- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
+++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
@@ -229,24 +229,7 @@ class PhpDumper extends Dumper
throw new ServiceCircularReferenceException($id, array($id));
}
- $arguments = array();
- foreach ($sDefinition->getArguments() as $argument) {
- $arguments[] = $this->dumpValue($argument);
- }
-
- if (null !== $sDefinition->getFactoryMethod()) {
- if (null !== $sDefinition->getFactoryClass()) {
- $code .= sprintf(" \$%s = call_user_func(array(%s, '%s')%s);\n", $name, $this->dumpValue($sDefinition->getFactoryClass()), $sDefinition->getFactoryMethod(), count($arguments) > 0 ? ', '.implode(', ', $arguments) : '');
- } elseif (null !== $sDefinition->getFactoryService()) {
- $code .= sprintf(" \$%s = %s->%s(%s);\n", $name, $this->getServiceCall($sDefinition->getFactoryService()), $sDefinition->getFactoryMethod(), implode(', ', $arguments));
- } else {
- throw new RuntimeException('Factory service or factory class must be defined in service definition for '.$id);
- }
- } elseif (false !== strpos($class, '$')) {
- $code .= sprintf(" \$class = %s;\n \$%s = new \$class(%s);\n", $class, $name, implode(', ', $arguments));
- } else {
- $code .= sprintf(" \$%s = new \\%s(%s);\n", $name, substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments));
- }
+ $code .= $this->addNewInstance($id, $sDefinition, '$'.$name, ' = ');
if (!$this->hasReference($id, $sDefinition->getMethodCalls(), true) && !$this->hasReference($id, $sDefinition->getProperties(), true)) {
$code .= $this->addServiceMethodCalls(null, $sDefinition, $name);
@@ -297,11 +280,6 @@ class PhpDumper extends Dumper
throw new InvalidArgumentException(sprintf('"%s" is not a valid class name for the "%s" service.', $class, $id));
}
- $arguments = array();
- foreach ($definition->getArguments() as $value) {
- $arguments[] = $this->dumpValue($value);
- }
-
$simple = $this->isSimpleInstance($id, $definition);
$instantiation = '';
@@ -320,19 +298,7 @@ class PhpDumper extends Dumper
$instantiation .= ' = ';
}
- if (null !== $definition->getFactoryMethod()) {
- if (null !== $definition->getFactoryClass()) {
- $code = sprintf(" $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($definition->getFactoryClass()), $definition->getFactoryMethod(), $arguments ? ', '.implode(', ', $arguments) : '');
- } elseif (null !== $definition->getFactoryService()) {
- $code = sprintf(" $return{$instantiation}%s->%s(%s);\n", $this->getServiceCall($definition->getFactoryService()), $definition->getFactoryMethod(), implode(', ', $arguments));
- } else {
- throw new RuntimeException('Factory method requires a factory service or factory class in service definition for '.$id);
- }
- } elseif (false !== strpos($class, '$')) {
- $code = sprintf(" \$class = %s;\n\n $return{$instantiation}new \$class(%s);\n", $class, implode(', ', $arguments));
- } else {
- $code = sprintf(" $return{$instantiation}new \\%s(%s);\n", substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments));
- }
+ $code = $this->addNewInstance($id, $definition, $return, $instantiation);
if (!$simple) {
$code .= "\n";
@@ -611,6 +577,34 @@ EOF;
return $publicServices.$aliasServices.$privateServices;
}
+ private function addNewInstance($id, Definition $definition, $return, $instantiation)
+ {
+ $class = $this->dumpValue($definition->getClass());
+
+ $arguments = array();
+ foreach ($definition->getArguments() as $value) {
+ $arguments[] = $this->dumpValue($value);
+ }
+
+ if (null !== $definition->getFactoryMethod()) {
+ if (null !== $definition->getFactoryClass()) {
+ return sprintf(" $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($definition->getFactoryClass()), $definition->getFactoryMethod(), $arguments ? ', '.implode(', ', $arguments) : '');
+ }
+
+ if (null !== $definition->getFactoryService()) {
+ return sprintf(" $return{$instantiation}%s->%s(%s);\n", $this->getServiceCall($definition->getFactoryService()), $definition->getFactoryMethod(), implode(', ', $arguments));
+ }
+
+ throw new RuntimeException('Factory method requires a factory service or factory class in service definition for '.$id);
+ }
+
+ if (false !== strpos($class, '$')) {
+ return sprintf(" \$class = %s;\n\n $return{$instantiation}new \$class(%s);\n", $class, implode(', ', $arguments));
+ }
+
+ return sprintf(" $return{$instantiation}new \\%s(%s);\n", substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments));
+ }
+
/**
* Adds the class headers.
*
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInvalidReferencesPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInvalidReferencesPassTest.php
index a18ba73862..72058868d4 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInvalidReferencesPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInvalidReferencesPassTest.php
@@ -61,6 +61,20 @@ class ResolveInvalidReferencesPassTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array(), $def->getProperties());
}
+ public function testStrictFlagIsPreserved()
+ {
+ $container = new ContainerBuilder();
+ $container->register('bar');
+ $def = $container
+ ->register('foo')
+ ->addArgument(new Reference('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE, false))
+ ;
+
+ $this->process($container);
+
+ $this->assertFalse($def->getArgument(0)->isStrict());
+ }
+
protected function process(ContainerBuilder $container)
{
$pass = new ResolveInvalidReferencesPass();
diff --git a/src/Symfony/Component/Form/FormBuilder.php b/src/Symfony/Component/Form/FormBuilder.php
index 0cec9b9426..9d11b5f750 100644
--- a/src/Symfony/Component/Form/FormBuilder.php
+++ b/src/Symfony/Component/Form/FormBuilder.php
@@ -204,6 +204,21 @@ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormB
return count($this->children);
}
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormConfig()
+ {
+ $config = parent::getFormConfig();
+
+ $config->factory = null;
+ $config->parent = null;
+ $config->children = array();
+ $config->unresolvedChildren = array();
+
+ return $config;
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/src/Symfony/Component/Form/Resources/translations/validators.da.xlf b/src/Symfony/Component/Form/Resources/translations/validators.da.xlf
index 9663cb6f17..c2dd4601f9 100644
--- a/src/Symfony/Component/Form/Resources/translations/validators.da.xlf
+++ b/src/Symfony/Component/Form/Resources/translations/validators.da.xlf
@@ -11,7 +11,7 @@
Den oploadede fil var for stor. Opload venligst en mindre fil.
- The CSRF token is invalid.
+ The CSRF token is invalid. Please try to resubmit the form.
CSRF nøglen er ugyldig.