Merge branch '2.5' into 2.6
* 2.5: [HttpFoundation] [Request] fix baseUrl parsing to fix wrong path_info [Twig][Bridge][TranslationDefaultDomain] add support of named arguments. [Form] Improved exception message if the data class is not found Fixes ArgvInput's argument getter with empty tokens execute cheaper checks before more expensive ones [FrameworkBundle] FormDataCollector should be loaded only if form config is enabled Conflicts: src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml
This commit is contained in:
commit
7a3332b798
@ -62,14 +62,20 @@ class TranslationDefaultDomainNodeVisitor implements \Twig_NodeVisitorInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($node instanceof \Twig_Node_Expression_Filter && in_array($node->getNode('filter')->getAttribute('value'), array('trans', 'transchoice'))) {
|
if ($node instanceof \Twig_Node_Expression_Filter && in_array($node->getNode('filter')->getAttribute('value'), array('trans', 'transchoice'))) {
|
||||||
$ind = 'trans' === $node->getNode('filter')->getAttribute('value') ? 1 : 2;
|
|
||||||
$arguments = $node->getNode('arguments');
|
$arguments = $node->getNode('arguments');
|
||||||
if (!$arguments->hasNode($ind)) {
|
$ind = 'trans' === $node->getNode('filter')->getAttribute('value') ? 1 : 2;
|
||||||
if (!$arguments->hasNode($ind - 1)) {
|
if ($this->isNamedArguments($arguments)) {
|
||||||
$arguments->setNode($ind - 1, new \Twig_Node_Expression_Array(array(), $node->getLine()));
|
if (!$arguments->hasNode('domain') && !$arguments->hasNode($ind)) {
|
||||||
|
$arguments->setNode('domain', $this->scope->get('domain'));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (!$arguments->hasNode($ind)) {
|
||||||
|
if (!$arguments->hasNode($ind - 1)) {
|
||||||
|
$arguments->setNode($ind - 1, new \Twig_Node_Expression_Array(array(), $node->getLine()));
|
||||||
|
}
|
||||||
|
|
||||||
$arguments->setNode($ind, $this->scope->get('domain'));
|
$arguments->setNode($ind, $this->scope->get('domain'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} elseif ($node instanceof TransNode) {
|
} elseif ($node instanceof TransNode) {
|
||||||
if (null === $node->getNode('domain')) {
|
if (null === $node->getNode('domain')) {
|
||||||
@ -103,4 +109,18 @@ class TranslationDefaultDomainNodeVisitor implements \Twig_NodeVisitorInterface
|
|||||||
{
|
{
|
||||||
return -10;
|
return -10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function isNamedArguments($arguments)
|
||||||
|
{
|
||||||
|
foreach ($arguments as $name => $node) {
|
||||||
|
if (!is_int($name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,6 +147,40 @@ class TranslationExtensionTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals('foo (foo)foo (custom)foo (foo)foo (custom)foo (foo)foo (custom)', trim($template->render(array())));
|
$this->assertEquals('foo (foo)foo (custom)foo (foo)foo (custom)foo (foo)foo (custom)', trim($template->render(array())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDefaultTranslationDomainWithNamedArguments()
|
||||||
|
{
|
||||||
|
$templates = array(
|
||||||
|
'index' => '
|
||||||
|
{%- trans_default_domain "foo" %}
|
||||||
|
|
||||||
|
{%- block content %}
|
||||||
|
{{- "foo"|trans(arguments = {}, domain = "custom") }}
|
||||||
|
{{- "foo"|transchoice(count = 1) }}
|
||||||
|
{{- "foo"|transchoice(count = 1, arguments = {}, domain = "custom") }}
|
||||||
|
{{- "foo"|trans({}, domain = "custom") }}
|
||||||
|
{{- "foo"|trans({}, "custom", locale = "fr") }}
|
||||||
|
{{- "foo"|transchoice(1, arguments = {}, domain = "custom") }}
|
||||||
|
{{- "foo"|transchoice(1, {}, "custom", locale = "fr") }}
|
||||||
|
{% endblock %}
|
||||||
|
',
|
||||||
|
|
||||||
|
'base' => '
|
||||||
|
{%- block content "" %}
|
||||||
|
',
|
||||||
|
);
|
||||||
|
|
||||||
|
$translator = new Translator('en', new MessageSelector());
|
||||||
|
$translator->addLoader('array', new ArrayLoader());
|
||||||
|
$translator->addResource('array', array('foo' => 'foo (messages)'), 'en');
|
||||||
|
$translator->addResource('array', array('foo' => 'foo (custom)'), 'en', 'custom');
|
||||||
|
$translator->addResource('array', array('foo' => 'foo (foo)'), 'en', 'foo');
|
||||||
|
$translator->addResource('array', array('foo' => 'foo (fr)'), 'fr', 'custom');
|
||||||
|
|
||||||
|
$template = $this->getTemplate($templates, $translator);
|
||||||
|
|
||||||
|
$this->assertEquals('foo (custom)foo (foo)foo (custom)foo (custom)foo (fr)foo (custom)foo (fr)', trim($template->render(array())));
|
||||||
|
}
|
||||||
|
|
||||||
protected function getTemplate($template, $translator = null)
|
protected function getTemplate($template, $translator = null)
|
||||||
{
|
{
|
||||||
if (null === $translator) {
|
if (null === $translator) {
|
||||||
|
@ -77,6 +77,13 @@ class TranslationDefaultDomainNodeVisitorTest extends \PHPUnit_Framework_TestCas
|
|||||||
array(TwigNodeProvider::getTransFilter(self::$message)),
|
array(TwigNodeProvider::getTransFilter(self::$message)),
|
||||||
array(TwigNodeProvider::getTransChoiceFilter(self::$message)),
|
array(TwigNodeProvider::getTransChoiceFilter(self::$message)),
|
||||||
array(TwigNodeProvider::getTransTag(self::$message)),
|
array(TwigNodeProvider::getTransTag(self::$message)),
|
||||||
|
// with named arguments
|
||||||
|
array(TwigNodeProvider::getTransFilter(self::$message, null, array(
|
||||||
|
'arguments' => new \Twig_Node_Expression_Array(array(), 0),
|
||||||
|
))),
|
||||||
|
array(TwigNodeProvider::getTransChoiceFilter(self::$message), null, array(
|
||||||
|
'arguments' => new \Twig_Node_Expression_Array(array(), 0),
|
||||||
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,12 +29,14 @@ class TwigNodeProvider
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getTransFilter($message, $domain = null)
|
public static function getTransFilter($message, $domain = null, $arguments = null)
|
||||||
{
|
{
|
||||||
$arguments = $domain ? array(
|
if (!$arguments) {
|
||||||
new \Twig_Node_Expression_Array(array(), 0),
|
$arguments = $domain ? array(
|
||||||
new \Twig_Node_Expression_Constant($domain, 0),
|
new \Twig_Node_Expression_Array(array(), 0),
|
||||||
) : array();
|
new \Twig_Node_Expression_Constant($domain, 0),
|
||||||
|
) : array();
|
||||||
|
}
|
||||||
|
|
||||||
return new \Twig_Node_Expression_Filter(
|
return new \Twig_Node_Expression_Filter(
|
||||||
new \Twig_Node_Expression_Constant($message, 0),
|
new \Twig_Node_Expression_Constant($message, 0),
|
||||||
@ -44,13 +46,15 @@ class TwigNodeProvider
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getTransChoiceFilter($message, $domain = null)
|
public static function getTransChoiceFilter($message, $domain = null, $arguments = null)
|
||||||
{
|
{
|
||||||
$arguments = $domain ? array(
|
if (!$arguments) {
|
||||||
new \Twig_Node_Expression_Constant(0, 0),
|
$arguments = $domain ? array(
|
||||||
new \Twig_Node_Expression_Array(array(), 0),
|
new \Twig_Node_Expression_Constant(0, 0),
|
||||||
new \Twig_Node_Expression_Constant($domain, 0),
|
new \Twig_Node_Expression_Array(array(), 0),
|
||||||
) : array();
|
new \Twig_Node_Expression_Constant($domain, 0),
|
||||||
|
) : array();
|
||||||
|
}
|
||||||
|
|
||||||
return new \Twig_Node_Expression_Filter(
|
return new \Twig_Node_Expression_Filter(
|
||||||
new \Twig_Node_Expression_Constant($message, 0),
|
new \Twig_Node_Expression_Constant($message, 0),
|
||||||
|
@ -13,8 +13,6 @@
|
|||||||
<parameter key="data_collector.time.class">Symfony\Component\HttpKernel\DataCollector\TimeDataCollector</parameter>
|
<parameter key="data_collector.time.class">Symfony\Component\HttpKernel\DataCollector\TimeDataCollector</parameter>
|
||||||
<parameter key="data_collector.memory.class">Symfony\Component\HttpKernel\DataCollector\MemoryDataCollector</parameter>
|
<parameter key="data_collector.memory.class">Symfony\Component\HttpKernel\DataCollector\MemoryDataCollector</parameter>
|
||||||
<parameter key="data_collector.router.class">Symfony\Bundle\FrameworkBundle\DataCollector\RouterDataCollector</parameter>
|
<parameter key="data_collector.router.class">Symfony\Bundle\FrameworkBundle\DataCollector\RouterDataCollector</parameter>
|
||||||
<parameter key="data_collector.form.class">Symfony\Component\Form\Extension\DataCollector\FormDataCollector</parameter>
|
|
||||||
<parameter key="data_collector.form.extractor.class">Symfony\Component\Form\Extension\DataCollector\FormDataExtractor</parameter>
|
|
||||||
</parameters>
|
</parameters>
|
||||||
|
|
||||||
<services>
|
<services>
|
||||||
@ -61,12 +59,5 @@
|
|||||||
<tag name="kernel.event_listener" event="kernel.controller" method="onKernelController"/>
|
<tag name="kernel.event_listener" event="kernel.controller" method="onKernelController"/>
|
||||||
<tag name="data_collector" template="@WebProfiler/Collector/router.html.twig" id="router" priority="255" />
|
<tag name="data_collector" template="@WebProfiler/Collector/router.html.twig" id="router" priority="255" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="data_collector.form.extractor" class="%data_collector.form.extractor.class%" />
|
|
||||||
|
|
||||||
<service id="data_collector.form" class="%data_collector.form.class%">
|
|
||||||
<tag name="data_collector" template="@WebProfiler/Collector/form.html.twig" id="form" priority="255" />
|
|
||||||
<argument type="service" id="data_collector.form.extractor" />
|
|
||||||
</service>
|
|
||||||
</services>
|
</services>
|
||||||
</container>
|
</container>
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
<parameters>
|
<parameters>
|
||||||
<parameter key="form.resolved_type_factory.data_collector_proxy.class">Symfony\Component\Form\Extension\DataCollector\Proxy\ResolvedTypeFactoryDataCollectorProxy</parameter>
|
<parameter key="form.resolved_type_factory.data_collector_proxy.class">Symfony\Component\Form\Extension\DataCollector\Proxy\ResolvedTypeFactoryDataCollectorProxy</parameter>
|
||||||
<parameter key="form.type_extension.form.data_collector.class">Symfony\Component\Form\Extension\DataCollector\Type\DataCollectorTypeExtension</parameter>
|
<parameter key="form.type_extension.form.data_collector.class">Symfony\Component\Form\Extension\DataCollector\Type\DataCollectorTypeExtension</parameter>
|
||||||
|
<parameter key="data_collector.form.class">Symfony\Component\Form\Extension\DataCollector\FormDataCollector</parameter>
|
||||||
|
<parameter key="data_collector.form.extractor.class">Symfony\Component\Form\Extension\DataCollector\FormDataExtractor</parameter>
|
||||||
</parameters>
|
</parameters>
|
||||||
|
|
||||||
<services>
|
<services>
|
||||||
@ -22,5 +24,13 @@
|
|||||||
<tag name="form.type_extension" alias="form" />
|
<tag name="form.type_extension" alias="form" />
|
||||||
<argument type="service" id="data_collector.form" />
|
<argument type="service" id="data_collector.form" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
<!-- DataCollector -->
|
||||||
|
<service id="data_collector.form.extractor" class="%data_collector.form.extractor.class%" />
|
||||||
|
|
||||||
|
<service id="data_collector.form" class="%data_collector.form.class%">
|
||||||
|
<tag name="data_collector" template="@WebProfiler/Collector/form.html.twig" id="form" priority="255" />
|
||||||
|
<argument type="service" id="data_collector.form.extractor" />
|
||||||
|
</service>
|
||||||
</services>
|
</services>
|
||||||
</container>
|
</container>
|
||||||
|
@ -309,9 +309,11 @@ class ArgvInput extends Input
|
|||||||
public function getParameterOption($values, $default = false)
|
public function getParameterOption($values, $default = false)
|
||||||
{
|
{
|
||||||
$values = (array) $values;
|
$values = (array) $values;
|
||||||
|
|
||||||
$tokens = $this->tokens;
|
$tokens = $this->tokens;
|
||||||
while ($token = array_shift($tokens)) {
|
|
||||||
|
while (0 < count($tokens)) {
|
||||||
|
$token = array_shift($tokens);
|
||||||
|
|
||||||
foreach ($values as $value) {
|
foreach ($values as $value) {
|
||||||
if ($token === $value || 0 === strpos($token, $value.'=')) {
|
if ($token === $value || 0 === strpos($token, $value.'=')) {
|
||||||
if (false !== $pos = strpos($token, '=')) {
|
if (false !== $pos = strpos($token, '=')) {
|
||||||
|
@ -304,6 +304,7 @@ class ArgvInputTest extends \PHPUnit_Framework_TestCase
|
|||||||
array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), 'dev'),
|
array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), 'dev'),
|
||||||
array(array('app/console', 'foo:bar', '--env=dev'), array('-e', '--env'), 'dev'),
|
array(array('app/console', 'foo:bar', '--env=dev'), array('-e', '--env'), 'dev'),
|
||||||
array(array('app/console', 'foo:bar', '--env=dev', '--en=1'), array('--en'), '1'),
|
array(array('app/console', 'foo:bar', '--env=dev', '--en=1'), array('--en'), '1'),
|
||||||
|
array(array('app/console', 'foo:bar', '--env=dev', '', '--en=1'), array('--en'), '1'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
|
|||||||
self::validateName($name);
|
self::validateName($name);
|
||||||
|
|
||||||
if (null !== $dataClass && !class_exists($dataClass) && !interface_exists($dataClass)) {
|
if (null !== $dataClass && !class_exists($dataClass) && !interface_exists($dataClass)) {
|
||||||
throw new InvalidArgumentException(sprintf('The data class "%s" is not a valid class.', $dataClass));
|
throw new InvalidArgumentException(sprintf('Class "%s" not found. Is the "data_class" form option set correctly?', $dataClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->name = (string) $name;
|
$this->name = (string) $name;
|
||||||
|
@ -1760,7 +1760,7 @@ class Request
|
|||||||
return $prefix;
|
return $prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, dirname($baseUrl))) {
|
if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, dirname($baseUrl).'/')) {
|
||||||
// directory portion of $baseUrl matches
|
// directory portion of $baseUrl matches
|
||||||
return rtrim($prefix, '/');
|
return rtrim($prefix, '/');
|
||||||
}
|
}
|
||||||
|
@ -223,6 +223,21 @@ class RequestTest extends \PHPUnit_Framework_TestCase
|
|||||||
$request = Request::create('http://test.com/?foo');
|
$request = Request::create('http://test.com/?foo');
|
||||||
$this->assertEquals('/?foo', $request->getRequestUri());
|
$this->assertEquals('/?foo', $request->getRequestUri());
|
||||||
$this->assertEquals(array('foo' => ''), $request->query->all());
|
$this->assertEquals(array('foo' => ''), $request->query->all());
|
||||||
|
|
||||||
|
## assume rewrite rule: (.*) --> app/app.php ; app/ is a symlink to a symfony web/ directory
|
||||||
|
$request = Request::create('http://test.com/apparthotel-1234', 'GET', array(), array(), array(),
|
||||||
|
array(
|
||||||
|
'DOCUMENT_ROOT' => '/var/www/www.test.com',
|
||||||
|
'SCRIPT_FILENAME' => '/var/www/www.test.com/app/app.php',
|
||||||
|
'SCRIPT_NAME' => '/app/app.php',
|
||||||
|
'PHP_SELF' => '/app/app.php/apparthotel-1234',
|
||||||
|
));
|
||||||
|
$this->assertEquals('http://test.com/apparthotel-1234', $request->getUri());
|
||||||
|
$this->assertEquals('/apparthotel-1234', $request->getPathInfo());
|
||||||
|
$this->assertEquals('', $request->getQueryString());
|
||||||
|
$this->assertEquals(80, $request->getPort());
|
||||||
|
$this->assertEquals('test.com', $request->getHttpHost());
|
||||||
|
$this->assertFalse($request->isSecure());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1327,7 +1342,7 @@ class RequestTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
array(
|
array(
|
||||||
'/foo%20bar',
|
'/foo%20bar/',
|
||||||
array(
|
array(
|
||||||
'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
|
'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
|
||||||
'SCRIPT_NAME' => '/foo bar/app.php',
|
'SCRIPT_NAME' => '/foo bar/app.php',
|
||||||
|
@ -72,15 +72,15 @@ class Escaper
|
|||||||
*/
|
*/
|
||||||
public static function requiresSingleQuoting($value)
|
public static function requiresSingleQuoting($value)
|
||||||
{
|
{
|
||||||
// Determines if the PHP value contains any single characters that would
|
// Determines if a PHP value is entirely composed of a value that would
|
||||||
// cause it to require single quoting in YAML.
|
// require single quoting in YAML.
|
||||||
if (preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value)) {
|
if (in_array(strtolower($value), array('null', '~', 'true', 'false', 'y', 'n', 'yes', 'no', 'on', 'off'))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines if a PHP value is entirely composed of a value that would
|
// Determines if the PHP value contains any single characters that would
|
||||||
// require single quoting in YAML.
|
// cause it to require single quoting in YAML.
|
||||||
return in_array(strtolower($value), array('null', '~', 'true', 'false', 'y', 'n', 'yes', 'no', 'on', 'off'));
|
return preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,13 +144,13 @@ class Inline
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $repr;
|
return $repr;
|
||||||
|
case '' == $value:
|
||||||
|
return "''";
|
||||||
case Escaper::requiresDoubleQuoting($value):
|
case Escaper::requiresDoubleQuoting($value):
|
||||||
return Escaper::escapeWithDoubleQuotes($value);
|
return Escaper::escapeWithDoubleQuotes($value);
|
||||||
case Escaper::requiresSingleQuoting($value):
|
case Escaper::requiresSingleQuoting($value):
|
||||||
case preg_match(self::getTimestampRegex(), $value):
|
case preg_match(self::getTimestampRegex(), $value):
|
||||||
return Escaper::escapeWithSingleQuotes($value);
|
return Escaper::escapeWithSingleQuotes($value);
|
||||||
case '' == $value:
|
|
||||||
return "''";
|
|
||||||
default:
|
default:
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user