Merge branch '2.1' into 2.2

* 2.1:
  Options small typo
  [Console] fixed unparsed StringInput tokens
  [TwigBridge] fixed trans twig extractor
  [DomCrawler] fix handling of schemes by Link::getUri()
  [Console] Fixed comment
  [TwigBridge] fixed the translator extractor that were not trimming the text in trans tags (closes #7056)
  Fixed handling absent href attribute in base tag
  added a DebuClassLoader::findFile() method to make the wrapping less invasive
  fixed CHANGELOG
  bumped Symfony version to 2.1.9-DEV
  updated VERSION for 2.1.8
  updated CHANGELOG for 2.1.8
  StringInput resets the given options.

Conflicts:
	src/Symfony/Component/HttpKernel/Kernel.php
This commit is contained in:
Fabien Potencier 2013-03-01 07:43:14 +01:00
commit 556ca0cfbd
18 changed files with 305 additions and 17 deletions

View File

@ -7,6 +7,37 @@ in 2.1 minor versions.
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v2.1.0...v2.1.1
* 2.1.8 (2013-02-23)
* b2080c4: [HttpFoundation] Remove Cache-Control when using https download via IE<9 (fixes #6750)
* b7bd630: [Form] Fixed TimeType not to render a "size" attribute in select tags
* 368f62f: Expanded fault-tolerance for unusual cookie dates
* cb03074: [DomCrawler] lowered parsed protocol string (fixes #6986)
* 3e40c17: [HttpKernel] fixed locale management when exiting sub-requests
* 179cd58: [Process] Fix regression introduced in #6620 / 880da01c49a9255f5022ab7e18bca38c18f56370, fixes #7082
* 18b139d: [FrameworkBundle] tweaked reference dumper command (see #7093)
* 0eff68f: Fix REMOTE_ADDR for cached subrequests
* 5e8d844: [Process] Warn user with a useful message when tmpfile() failed
* 42d3c4c: added support for the X-Forwarded-For header (closes #6982, closes #7000)
* 6a9c510: fixed the IP address in HttpCache when calling the backend
* 87f3db7: [EventDispathcer] Fix removeListener
* e0637fa: [DependencyInjection] Add clone for resources which were introduced in 2.1
* bd0ad92: [DependencyInjection] Allow frozen containers to be dumped to graphviz
* 83e9558: Fix 'undefined index' error, when entering scope recursively
* 3615e19: [Security] fixed session creation on login (closes #7011)
* a12744e: Add dot character `.` to legal mime subtype regular expression
* e50d333: [HttpKernel] fixed the creation of the Profiler directory
* ddf4678: [HttpFoundation] fixed the creation of sub-requests under some circumstancies (closes #6923, closes #6936)
* 8ca00c5: [Security] fixed session creation when none is needed (closes #6917)
* 74f2fcf: fixed a circular call (closes #6864)
* 6f71948: [Yaml] fixed wrong merge (indentation default is 4 as of 2.1)
* 4119caf: [DependencyInjection] fixed the creation of synthetic services in ContainerBuilder
* 11aaa2e: Added an error message in the DebugClassLoader when using / instead of \.
* ce38069: [FrameworkBundle] fixed Client::doRequest that must call its parent method (closes #6737)
* 53ccc2c: [Yaml] fixed ignored text when parsing an inlined mapping or sequence (closes #6786)
* ab0385c: [Yaml] fixed #6773
* fea20b7: [Yaml] fixed #6770
* 2.1.7 (2013-01-17)
* e17e232: [Yaml] fixed default value

View File

@ -33,11 +33,17 @@ class TranslationDefaultDomainNodeVisitor implements \Twig_NodeVisitorInterface
}
if ($node instanceof TransDefaultDomainNode) {
$var = $env->getParser()->getVarName();
$name = new \Twig_Node_Expression_AssignName($var, $node->getLine());
$this->domain = new \Twig_Node_Expression_Name($var, $node->getLine());
if ($node->getNode('expr') instanceof \Twig_Node_Expression_Constant) {
$this->domain = $node->getNode('expr');
return new \Twig_Node_Set(false, new \Twig_Node(array($name)), new \Twig_Node(array($node->getNode('expr'))), $node->getLine());
return $node;
} else {
$var = $env->getParser()->getVarName();
$name = new \Twig_Node_Expression_AssignName($var, $node->getLine());
$this->domain = new \Twig_Node_Expression_Name($var, $node->getLine());
return new \Twig_Node_Set(false, new \Twig_Node(array($name)), new \Twig_Node(array($node->getNode('expr'))), $node->getLine());
}
}
if (null === $this->domain) {
@ -68,6 +74,10 @@ class TranslationDefaultDomainNodeVisitor implements \Twig_NodeVisitorInterface
*/
public function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env)
{
if ($node instanceof TransDefaultDomainNode) {
return false;
}
return $node;
}
@ -76,6 +86,6 @@ class TranslationDefaultDomainNodeVisitor implements \Twig_NodeVisitorInterface
*/
public function getPriority()
{
return 0;
return -10;
}
}

View File

@ -20,6 +20,8 @@ use Symfony\Bridge\Twig\Node\TransNode;
*/
class TranslationNodeVisitor implements \Twig_NodeVisitorInterface
{
const UNDEFINED_DOMAIN = '_undefined';
private $enabled = false;
private $messages = array();
@ -57,7 +59,7 @@ class TranslationNodeVisitor implements \Twig_NodeVisitorInterface
// extract constant nodes with a trans filter
$this->messages[] = array(
$node->getNode('node')->getAttribute('value'),
$node->getNode('arguments')->hasNode(1) ? $node->getNode('arguments')->getNode(1)->getAttribute('value') : null,
$this->getReadDomainFromArguments($node->getNode('arguments'), 1),
);
} elseif (
$node instanceof \Twig_Node_Expression_Filter &&
@ -67,13 +69,13 @@ class TranslationNodeVisitor implements \Twig_NodeVisitorInterface
// extract constant nodes with a trans filter
$this->messages[] = array(
$node->getNode('node')->getAttribute('value'),
$node->getNode('arguments')->hasNode(2) ? $node->getNode('arguments')->getNode(2)->getAttribute('value') : null,
$this->getReadDomainFromArguments($node->getNode('arguments'), 2),
);
} elseif ($node instanceof TransNode) {
// extract trans nodes
$this->messages[] = array(
$node->getNode('body')->getAttribute('data'),
null === $node->getNode('domain') ? 'messages' : $node->getNode('domain')->getAttribute('value'),
$this->getReadDomainFromNode($node->getNode('domain')),
);
}
@ -93,6 +95,43 @@ class TranslationNodeVisitor implements \Twig_NodeVisitorInterface
*/
public function getPriority()
{
return -10;
return 0;
}
/**
* @param \Twig_Node $arguments
* @param int $index
*
* @return string|null
*/
private function getReadDomainFromArguments(\Twig_Node $arguments, $index)
{
if ($arguments->hasNode('domain')) {
$argument = $arguments->getNode('domain');
} elseif ($arguments->hasNode($index)) {
$argument = $arguments->getNode($index);
} else {
return null;
}
return $this->getReadDomainFromNode($argument);
}
/**
* @param \Twig_Node $node
*
* @return string|null
*/
private function getReadDomainFromNode(\Twig_Node $node = null)
{
if (null === $node) {
return null;
}
if ($node instanceof \Twig_Node_Expression_Constant) {
return $node->getAttribute('value');
}
return self::UNDEFINED_DOMAIN;
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace Symfony\Bridge\Twig\Tests\NodeVisitor;
use Symfony\Bridge\Twig\NodeVisitor\TranslationDefaultDomainNodeVisitor;
use Symfony\Bridge\Twig\NodeVisitor\TranslationNodeVisitor;
use Symfony\Bridge\Twig\Tests\TestCase;
class TranslationDefaultDomainNodeVisitorTest extends TestCase
{
private static $message = 'message';
private static $domain = 'domain';
/** @dataProvider getDefaultDomainAssignmentTestData */
public function testDefaultDomainAssignment(\Twig_Node $node)
{
$env = new \Twig_Environment(new \Twig_Loader_String(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
$visitor = new TranslationDefaultDomainNodeVisitor();
// visit trans_default_domain tag
$defaultDomain = TwigNodeProvider::getTransDefaultDomainTag('domain');
$visitor->enterNode($defaultDomain, $env);
$visitor->leaveNode($defaultDomain, $env);
// visit tested node
$enteredNode = $visitor->enterNode($node, $env);
$leavedNode = $visitor->leaveNode($node, $env);
$this->assertSame($node, $enteredNode);
$this->assertSame($node, $leavedNode);
// extracting tested node messages
$visitor = new TranslationNodeVisitor();
$visitor->enable();
$visitor->enterNode($node, $env);
$visitor->leaveNode($node, $env);
$this->assertEquals(array(array(self::$message, self::$domain)), $visitor->getMessages());
}
public function getDefaultDomainAssignmentTestData()
{
return array(
array(TwigNodeProvider::getTransFilter(self::$message, self::$domain)),
array(TwigNodeProvider::getTransChoiceFilter(self::$message, self::$domain)),
array(TwigNodeProvider::getTransTag(self::$message, self::$domain)),
);
}
}

View File

@ -0,0 +1,52 @@
<?php
namespace Symfony\Bridge\Twig\Tests\NodeVisitor;
use Symfony\Bridge\Twig\NodeVisitor\TranslationNodeVisitor;
use Symfony\Bridge\Twig\Tests\TestCase;
class TranslationNodeVisitorTest extends TestCase
{
/** @dataProvider getMessagesExtractionTestData */
public function testMessagesExtraction(\Twig_Node $node, array $expectedMessages)
{
$env = new \Twig_Environment(new \Twig_Loader_String(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
$visitor = new TranslationNodeVisitor();
$visitor->enable();
$visitor->enterNode($node, $env);
$visitor->leaveNode($node, $env);
$this->assertEquals($expectedMessages, $visitor->getMessages());
}
public function testMessageExtractionWithInvalidDomainNode()
{
$message = 'new key';
$node = new \Twig_Node_Expression_Filter(
new \Twig_Node_Expression_Constant($message, 0),
new \Twig_Node_Expression_Constant('trans', 0),
new \Twig_Node(array(
new \Twig_Node_Expression_Array(array(), 0),
new \Twig_Node_Expression_Name('variable', 0),
)),
0
);
$this->testMessagesExtraction($node, array(array($message, TranslationNodeVisitor::UNDEFINED_DOMAIN)));
}
public function getMessagesExtractionTestData()
{
$message = 'new key';
$domain = 'domain';
return array(
array(TwigNodeProvider::getTransFilter($message), array(array($message, null))),
array(TwigNodeProvider::getTransChoiceFilter($message), array(array($message, null))),
array(TwigNodeProvider::getTransTag($message), array(array($message, null))),
array(TwigNodeProvider::getTransFilter($message, $domain), array(array($message, $domain))),
array(TwigNodeProvider::getTransChoiceFilter($message, $domain), array(array($message, $domain))),
array(TwigNodeProvider::getTransTag($message, $domain), array(array($message, $domain))),
);
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace Symfony\Bridge\Twig\Tests\NodeVisitor;
use Symfony\Bridge\Twig\Node\TransDefaultDomainNode;
use Symfony\Bridge\Twig\Node\TransNode;
class TwigNodeProvider
{
public static function getTransFilter($message, $domain = null)
{
$arguments = $domain ? array(
new \Twig_Node_Expression_Array(array(), 0),
new \Twig_Node_Expression_Constant($domain, 0),
) : array();
return new \Twig_Node_Expression_Filter(
new \Twig_Node_Expression_Constant($message, 0),
new \Twig_Node_Expression_Constant('trans', 0),
new \Twig_Node($arguments),
0
);
}
public static function getTransChoiceFilter($message, $domain = null)
{
$arguments = $domain ? array(
new \Twig_Node_Expression_Constant(0, 0),
new \Twig_Node_Expression_Array(array(), 0),
new \Twig_Node_Expression_Constant($domain, 0),
) : array();
return new \Twig_Node_Expression_Filter(
new \Twig_Node_Expression_Constant($message, 0),
new \Twig_Node_Expression_Constant('transchoice', 0),
new \Twig_Node($arguments),
0
);
}
public static function getTransTag($message, $domain = null)
{
return new TransNode(
new \Twig_Node_Body(array(), array('data' => $message)),
$domain ? new \Twig_Node_Expression_Constant($domain, 0) : null
);
}
public static function getTransDefaultDomainTag($domain)
{
return new TransDefaultDomainNode(
new \Twig_Node_Expression_Constant($domain, 0)
);
}
}

View File

@ -63,9 +63,19 @@ class TwigExtractorTest extends TestCase
array('{{ "new key" | transchoice(1) | upper }}', array('new key' => 'messages')),
array('{{ "new key" | transchoice(1, {}, "domain") }}', array('new key' => 'domain')),
array('{% trans %}new key{% endtrans %}', array('new key' => 'messages')),
array('{% trans %} new key {% endtrans %}', array('new key' => 'messages')),
array('{% trans from "domain" %}new key{% endtrans %}', array('new key' => 'domain')),
array('{% set foo = "new key" | trans %}', array('new key' => 'messages')),
array('{{ 1 ? "new key" | trans : "another key" | trans }}', array('new key' => 'messages', 'another key' => 'messages')),
// make sure 'trans_default_domain' tag is supported
array('{% trans_default_domain "domain" %}{{ "new key"|trans }}', array('new key' => 'domain')),
array('{% trans_default_domain "domain" %}{{ "new key"|transchoice }}', array('new key' => 'domain')),
array('{% trans_default_domain "domain" %}{% trans %}new key{% endtrans %}', array('new key' => 'domain')),
// make sure this works with twig's named arguments
array('{{ "new key" | trans(domain="domain") }}', array('new key' => 'domain')),
array('{{ "new key" | transchoice(domain="domain", count=1) }}', array('new key' => 'domain')),
);
}
}

View File

@ -78,7 +78,7 @@ class TwigExtractor implements ExtractorInterface
$this->twig->parse($this->twig->tokenize($template));
foreach ($visitor->getMessages() as $message) {
$catalogue->set($message[0], $this->prefix.$message[0], $message[1] ? $message[1] : $this->defaultDomain);
$catalogue->set(trim($message[0]), $this->prefix.trim($message[0]), $message[1] ? $message[1] : $this->defaultDomain);
}
$visitor->disable();

View File

@ -40,7 +40,7 @@ class Application extends BaseApplication
parent::__construct('Symfony', Kernel::VERSION.' - '.$kernel->getName().'/'.$kernel->getEnvironment().($kernel->isDebug() ? '/debug' : ''));
$this->getDefinition()->addOption(new InputOption('--shell', '-s', InputOption::VALUE_NONE, 'Launch the shell.'));
$this->getDefinition()->addOption(new InputOption('--process-isolation', null, InputOption::VALUE_NONE, 'Launch commands from shell as a separate processes.'));
$this->getDefinition()->addOption(new InputOption('--process-isolation', null, InputOption::VALUE_NONE, 'Launch commands from shell as a separate process.'));
$this->getDefinition()->addOption(new InputOption('--env', '-e', InputOption::VALUE_REQUIRED, 'The Environment name.', $kernel->getEnvironment()));
$this->getDefinition()->addOption(new InputOption('--no-debug', null, InputOption::VALUE_NONE, 'Switches off debug mode.'));
}

View File

@ -69,6 +69,18 @@ class DebugClassLoader
spl_autoload_unregister(array($this, 'loadClass'));
}
/**
* Finds a file by class name
*
* @param string $class A class name to resolve to file
*
* @return string|null
*/
public function findFile($class)
{
return $this->classFinder->findFile($class);
}
/**
* Loads the given class or interface.
*

View File

@ -68,6 +68,7 @@ class ArgvInput extends Input
protected function setTokens(array $tokens)
{
$this->tokens = $tokens;
$this->parse();
}
/**

View File

@ -123,7 +123,7 @@ abstract class Output implements OutputInterface
/**
* Writes a message to the output and adds a newline at the end.
*
* @param string|array $messages The message as an array of lines of a single string
* @param string|array $messages The message as an array of lines or a single string
* @param integer $type The type of output
*
* @api
@ -136,7 +136,7 @@ abstract class Output implements OutputInterface
/**
* Writes a message to the output.
*
* @param string|array $messages The message as an array of lines of a single string
* @param string|array $messages The message as an array of lines or a single string
* @param Boolean $newline Whether to add a newline or not
* @param integer $type The type of output
*

View File

@ -33,7 +33,7 @@ interface OutputInterface
/**
* Writes a message to the output.
*
* @param string|array $messages The message as an array of lines of a single string
* @param string|array $messages The message as an array of lines or a single string
* @param Boolean $newline Whether to add a newline or not
* @param integer $type The type of output (0: normal, 1: raw, 2: plain)
*

View File

@ -12,6 +12,8 @@
namespace Symfony\Component\Console\Tests\Input;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
class StringInputTest extends \PHPUnit_Framework_TestCase
{
@ -27,6 +29,18 @@ class StringInputTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($tokens, $p->getValue($input), $message);
}
public function testInputOptionWithGivenString()
{
$definition = new InputDefinition(
array(new InputOption('foo', null, InputOption::VALUE_REQUIRED))
);
$input = new StringInput('--foo=bar', $definition);
$actual = $input->getOption('foo');
$this->assertEquals('bar', $actual);
}
public function getTokenizeData()
{
return array(

View File

@ -145,8 +145,9 @@ class Crawler extends \SplObjectStorage
$base = $this->filterXPath('descendant-or-self::base')->extract(array('href'));
if (count($base)) {
$this->uri = current($base);
$baseHref = current($base);
if (count($base) && !empty($baseHref)) {
$this->uri = $baseHref;
}
}

View File

@ -89,7 +89,7 @@ class Link
$uri = trim($this->getRawUri());
// absolute URL?
if (0 === strpos($uri, 'http')) {
if (null !== parse_url($uri, PHP_URL_SCHEME)) {
return $uri;
}

View File

@ -80,6 +80,18 @@ class CrawlerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('Tiếng Việt', $crawler->filterXPath('//div')->text());
}
/**
* @covers Symfony\Component\DomCrawler\Crawler::addHtmlContent
*/
public function testAddHtmlContentInvalidBaseTag()
{
$crawler = new Crawler(null, 'http://symfony.com');
$crawler->addHtmlContent('<html><head><base target="_top"></head><a href="/contact"></a></html>', 'UTF-8');
$this->assertEquals('http://symfony.com/contact', current($crawler->filterXPath('//a')->links())->getUri(), '->addHtmlContent() correctly handles a non-existent base tag href attribute');
}
/**
* @covers Symfony\Component\DomCrawler\Crawler::addHtmlContent
*/

View File

@ -93,6 +93,8 @@ class LinkTest extends \PHPUnit_Framework_TestCase
array('?a=b', 'http://localhost/bar/', 'http://localhost/bar/?a=b'),
array('http://login.foo.com/foo', 'http://localhost/bar/', 'http://login.foo.com/foo'),
array('https://login.foo.com/foo', 'https://localhost/bar/', 'https://login.foo.com/foo'),
array('mailto:foo@bar.com', 'http://localhost/foo', 'mailto:foo@bar.com'),
array('?foo=2', 'http://localhost?foo=1', 'http://localhost?foo=2'),
array('?foo=2', 'http://localhost/?foo=1', 'http://localhost/?foo=2'),