Merge branch '2.1' into 2.2
* 2.1: sub-requests are now created with the same class as their parent [FrameworkBundle] removed BC break [FrameworkBundle] changed temp kernel name in cache:clear [DoctrineBridge] Avoids blob values to be logged by doctrine [Security] use current request attributes to generate redirect url? [Validator] fix showing wrong max file size for upload errors [TwigBridge] removed double var initialization (refs #7344) [2.1][TwigBridge] Fixes Issue #7342 in TwigBridge [FrameworkBundle] fixed cahe:clear command's warmup [TwigBridge] now enter/leave scope on Twig_Node_Module [TwigBridge] fixed fixed scope & trans_default_domain node visitor [TwigBridge] fixed non probant tests & added new one [BrowserKit] added ability to ignored malformed set-cookie header [Translation] removed wriong 'use' [Translation] added xliff loader/dumper with resname support [TwigBridge] fixes Conflicts: src/Symfony/Bundle/FrameworkBundle/HttpKernel.php src/Symfony/Component/Security/Http/HttpUtils.php src/Symfony/Component/Translation/Loader/XliffFileLoader.php src/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php
This commit is contained in:
commit
0d7593c636
@ -22,6 +22,9 @@ use Doctrine\DBAL\Logging\SQLLogger;
|
||||
*/
|
||||
class DbalLogger implements SQLLogger
|
||||
{
|
||||
const MAX_STRING_LENGTH = 32;
|
||||
const BINARY_DATA_VALUE = '(binary value)';
|
||||
|
||||
protected $logger;
|
||||
protected $stopwatch;
|
||||
|
||||
@ -46,6 +49,26 @@ class DbalLogger implements SQLLogger
|
||||
$this->stopwatch->start('doctrine', 'doctrine');
|
||||
}
|
||||
|
||||
if (is_array($params)) {
|
||||
foreach ($params as $index => $param) {
|
||||
if (!is_string($params[$index])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// non utf-8 strings break json encoding
|
||||
if (null === preg_match('#[^\p{L}\p{N} ]#u', $params[$index])) {
|
||||
$params[$index] = self::BINARY_DATA_VALUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
// too long string must be shorten
|
||||
if (self::MAX_STRING_LENGTH < strlen($params[$index])) {
|
||||
$params[$index] = substr($params[$index], self::MAX_STRING_LENGTH - 6).' [...]';
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $this->logger) {
|
||||
$this->log($sql, null === $params ? array() : $params);
|
||||
}
|
||||
|
@ -33,10 +33,15 @@ class EntityTypePerformanceTest extends FormPerformanceTestCase
|
||||
protected function getExtensions()
|
||||
{
|
||||
$manager = $this->getMock('Doctrine\Common\Persistence\ManagerRegistry');
|
||||
|
||||
$manager->expects($this->any())
|
||||
->method('getManager')
|
||||
->will($this->returnValue($this->em));
|
||||
|
||||
$manager->expects($this->any())
|
||||
->method('getManagerForClass')
|
||||
->will($this->returnValue($this->em));
|
||||
|
||||
return array(
|
||||
new CoreExtension(),
|
||||
new DoctrineOrmExtension($manager)
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
namespace Symfony\Bridge\Doctrine\Tests\Logger;
|
||||
|
||||
use Symfony\Bridge\Doctrine\Logger\DbalLogger;
|
||||
|
||||
class DbalLoggerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
@ -59,12 +61,38 @@ class DbalLoggerTest extends \PHPUnit_Framework_TestCase
|
||||
$dbalLogger
|
||||
->expects($this->once())
|
||||
->method('log')
|
||||
->with('SQL', array('utf8' => 'foo', 'nonutf8' => "\x7F\xFF"))
|
||||
->with('SQL', array('utf8' => 'foo', 'nonutf8' => DbalLogger::BINARY_DATA_VALUE))
|
||||
;
|
||||
|
||||
$dbalLogger->startQuery('SQL', array(
|
||||
'utf8' => 'foo',
|
||||
'nonutf8' => "\x7F\xFF"
|
||||
'nonutf8' => "\x7F\xFF",
|
||||
));
|
||||
}
|
||||
|
||||
public function testLogLongString()
|
||||
{
|
||||
$logger = $this->getMock('Symfony\\Component\\HttpKernel\\Log\\LoggerInterface');
|
||||
|
||||
$dbalLogger = $this
|
||||
->getMockBuilder('Symfony\\Bridge\\Doctrine\\Logger\\DbalLogger')
|
||||
->setConstructorArgs(array($logger, null))
|
||||
->setMethods(array('log'))
|
||||
->getMock()
|
||||
;
|
||||
|
||||
$shortString = str_repeat('a', DbalLogger::MAX_STRING_LENGTH);
|
||||
$longString = str_repeat('a', DbalLogger::MAX_STRING_LENGTH + 1);
|
||||
|
||||
$dbalLogger
|
||||
->expects($this->once())
|
||||
->method('log')
|
||||
->with('SQL', array('short' => $shortString, 'long' => substr($longString, DbalLogger::MAX_STRING_LENGTH - 6).' [...]'))
|
||||
;
|
||||
|
||||
$dbalLogger->startQuery('SQL', array(
|
||||
'short' => $shortString,
|
||||
'long' => $longString,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
126
src/Symfony/Bridge/Twig/NodeVisitor/Scope.php
Normal file
126
src/Symfony/Bridge/Twig/NodeVisitor/Scope.php
Normal file
@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Bridge\Twig\NodeVisitor;
|
||||
|
||||
/**
|
||||
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
|
||||
*/
|
||||
class Scope
|
||||
{
|
||||
/**
|
||||
* @var Scope|null
|
||||
*/
|
||||
private $parent;
|
||||
|
||||
/**
|
||||
* @var Scope[]
|
||||
*/
|
||||
private $children;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
private $left;
|
||||
|
||||
/**
|
||||
* @param Scope $parent
|
||||
*/
|
||||
public function __construct(Scope $parent = null)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
$this->left = false;
|
||||
$this->data = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a new child scope.
|
||||
*
|
||||
* @return Scope
|
||||
*/
|
||||
public function enter()
|
||||
{
|
||||
$child = new self($this);
|
||||
$this->children[] = $child;
|
||||
|
||||
return $child;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes current scope and returns parent one.
|
||||
*
|
||||
* @return Scope|null
|
||||
*/
|
||||
public function leave()
|
||||
{
|
||||
$this->left = true;
|
||||
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores data into current scope.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*
|
||||
* @throws \LogicException
|
||||
*
|
||||
* @return Scope Current scope
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
if ($this->left) {
|
||||
throw new \LogicException('Left scope is not mutable.');
|
||||
}
|
||||
|
||||
$this->data[$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if a data is visible from current scope.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
if (array_key_exists($key, $this->data)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (null === $this->parent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->parent->has($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns data visible from current scope.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
if (array_key_exists($key, $this->data)) {
|
||||
return $this->data[$key];
|
||||
}
|
||||
|
||||
if (null === $this->parent) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $this->parent->get($key, $default);
|
||||
}
|
||||
}
|
@ -21,32 +21,43 @@ use Symfony\Bridge\Twig\Node\TransDefaultDomainNode;
|
||||
*/
|
||||
class TranslationDefaultDomainNodeVisitor implements \Twig_NodeVisitorInterface
|
||||
{
|
||||
private $domain;
|
||||
/**
|
||||
* @var Scope
|
||||
*/
|
||||
private $scope;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->scope = new Scope();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env)
|
||||
{
|
||||
if ($node instanceof \Twig_Node_Module) {
|
||||
$this->domain = null;
|
||||
if ($node instanceof \Twig_Node_Block || $node instanceof \Twig_Node_Module) {
|
||||
$this->scope = $this->scope->enter();
|
||||
}
|
||||
|
||||
if ($node instanceof TransDefaultDomainNode) {
|
||||
if ($node->getNode('expr') instanceof \Twig_Node_Expression_Constant) {
|
||||
$this->domain = $node->getNode('expr');
|
||||
$this->scope->set('domain', $node->getNode('expr'));
|
||||
|
||||
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());
|
||||
$this->scope->set('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) {
|
||||
if (!$this->scope->has('domain')) {
|
||||
return $node;
|
||||
}
|
||||
|
||||
@ -58,11 +69,11 @@ class TranslationDefaultDomainNodeVisitor implements \Twig_NodeVisitorInterface
|
||||
$arguments->setNode($ind - 1, new \Twig_Node_Expression_Array(array(), $node->getLine()));
|
||||
}
|
||||
|
||||
$arguments->setNode($ind, $this->domain);
|
||||
$arguments->setNode($ind, $this->scope->get('domain'));
|
||||
}
|
||||
} elseif ($node instanceof TransNode) {
|
||||
if (null === $node->getNode('domain')) {
|
||||
$node->setNode('domain', $this->domain);
|
||||
$node->setNode('domain', $this->scope->get('domain'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,6 +89,10 @@ class TranslationDefaultDomainNodeVisitor implements \Twig_NodeVisitorInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($node instanceof \Twig_Node_Block || $node instanceof \Twig_Node_Module) {
|
||||
$this->scope = $this->scope->leave();
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
|
16
src/Symfony/Bridge/Twig/Tests/NodeVisitor/ScopeTest.php
Normal file
16
src/Symfony/Bridge/Twig/Tests/NodeVisitor/ScopeTest.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Bridge\Twig\Tests\NodeVisitor;
|
||||
|
||||
use Symfony\Bridge\Twig\NodeVisitor\Scope;
|
||||
use Symfony\Bridge\Twig\Tests\TestCase;
|
||||
|
||||
class ScopeTest extends TestCase
|
||||
{
|
||||
public function testScopeInitiation()
|
||||
{
|
||||
$scope = new Scope();
|
||||
$scope->enter();
|
||||
$this->assertNull($scope->get('test'));
|
||||
}
|
||||
}
|
@ -15,11 +15,10 @@ class TranslationDefaultDomainNodeVisitorTest extends TestCase
|
||||
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');
|
||||
$defaultDomain = TwigNodeProvider::getTransDefaultDomainTag(self::$domain);
|
||||
$visitor->enterNode($defaultDomain, $env);
|
||||
$visitor->leaveNode($defaultDomain, $env);
|
||||
|
||||
@ -38,12 +37,38 @@ class TranslationDefaultDomainNodeVisitorTest extends TestCase
|
||||
$this->assertEquals(array(array(self::$message, self::$domain)), $visitor->getMessages());
|
||||
}
|
||||
|
||||
/** @dataProvider getDefaultDomainAssignmentTestData */
|
||||
public function testNewModuleWithoutDefaultDomainTag(\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
|
||||
$newModule = TwigNodeProvider::getModule('test');
|
||||
$visitor->enterNode($newModule, $env);
|
||||
$visitor->leaveNode($newModule, $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, null)), $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)),
|
||||
array(TwigNodeProvider::getTransFilter(self::$message)),
|
||||
array(TwigNodeProvider::getTransChoiceFilter(self::$message)),
|
||||
array(TwigNodeProvider::getTransTag(self::$message)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,19 @@ use Symfony\Bridge\Twig\Node\TransNode;
|
||||
|
||||
class TwigNodeProvider
|
||||
{
|
||||
public static function getModule($content)
|
||||
{
|
||||
return new \Twig_Node_Module(
|
||||
new \Twig_Node_Expression_Constant($content, 0),
|
||||
null,
|
||||
new \Twig_Node_Expression_Array(array(), 0),
|
||||
new \Twig_Node_Expression_Array(array(), 0),
|
||||
new \Twig_Node_Expression_Array(array(), 0),
|
||||
null,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
public static function getTransFilter($message, $domain = null)
|
||||
{
|
||||
$arguments = $domain ? array(
|
||||
|
@ -25,8 +25,6 @@ use Symfony\Component\Finder\Finder;
|
||||
*/
|
||||
class CacheClearCommand extends ContainerAwareCommand
|
||||
{
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -57,31 +55,32 @@ EOF
|
||||
{
|
||||
$realCacheDir = $this->getContainer()->getParameter('kernel.cache_dir');
|
||||
$oldCacheDir = $realCacheDir.'_old';
|
||||
$filesystem = $this->getContainer()->get('filesystem');
|
||||
|
||||
if (!is_writable($realCacheDir)) {
|
||||
throw new \RuntimeException(sprintf('Unable to write in the "%s" directory', $realCacheDir));
|
||||
}
|
||||
|
||||
$filesystem = $this->getContainer()->get('filesystem');
|
||||
$kernel = $this->getContainer()->get('kernel');
|
||||
$output->writeln(sprintf('Clearing the cache for the <info>%s</info> environment with debug <info>%s</info>', $kernel->getEnvironment(), var_export($kernel->isDebug(), true)));
|
||||
|
||||
$this->getContainer()->get('cache_clearer')->clear($realCacheDir);
|
||||
|
||||
if ($filesystem->exists($oldCacheDir)) {
|
||||
$filesystem->remove($oldCacheDir);
|
||||
}
|
||||
|
||||
$kernel = $this->getContainer()->get('kernel');
|
||||
$output->writeln(sprintf('Clearing the cache for the <info>%s</info> environment with debug <info>%s</info>', $kernel->getEnvironment(), var_export($kernel->isDebug(), true)));
|
||||
$this->getContainer()->get('cache_clearer')->clear($realCacheDir);
|
||||
|
||||
if ($input->getOption('no-warmup')) {
|
||||
$filesystem->rename($realCacheDir, $oldCacheDir);
|
||||
} else {
|
||||
$warmupDir = $realCacheDir.'_new';
|
||||
// the warmup cache dir name must have the same length than the real one
|
||||
// to avoid the many problems in serialized resources files
|
||||
$warmupDir = substr($realCacheDir, 0, -1).'_';
|
||||
|
||||
if ($filesystem->exists($warmupDir)) {
|
||||
$filesystem->remove($warmupDir);
|
||||
}
|
||||
|
||||
$this->warmup($warmupDir, !$input->getOption('no-optional-warmers'));
|
||||
$this->warmup($warmupDir, $realCacheDir, !$input->getOption('no-optional-warmers'));
|
||||
|
||||
$filesystem->rename($realCacheDir, $oldCacheDir);
|
||||
$filesystem->rename($warmupDir, $realCacheDir);
|
||||
@ -90,99 +89,103 @@ EOF
|
||||
$filesystem->remove($oldCacheDir);
|
||||
}
|
||||
|
||||
protected function warmup($warmupDir, $enableOptionalWarmers = true)
|
||||
/**
|
||||
* @param string $warmupDir
|
||||
* @param string $realCacheDir
|
||||
* @param bool $enableOptionalWarmers
|
||||
*/
|
||||
protected function warmup($warmupDir, $realCacheDir, $enableOptionalWarmers = true)
|
||||
{
|
||||
$this->getContainer()->get('filesystem')->remove($warmupDir);
|
||||
|
||||
$parent = $this->getContainer()->get('kernel');
|
||||
$class = get_class($parent);
|
||||
// create a temporary kernel
|
||||
$realKernel = $this->getContainer()->get('kernel');
|
||||
$realKernelClass = get_class($realKernel);
|
||||
$namespace = '';
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
$namespace = substr($class, 0, $pos);
|
||||
$class = substr($class, $pos + 1);
|
||||
if (false !== $pos = strrpos($realKernelClass, '\\')) {
|
||||
$namespace = substr($realKernelClass, 0, $pos);
|
||||
$realKernelClass = substr($realKernelClass, $pos + 1);
|
||||
}
|
||||
$tempKernel = $this->getTempKernel($realKernel, $namespace, $realKernelClass, $warmupDir);
|
||||
$tempKernel->boot();
|
||||
|
||||
$kernel = $this->getTempKernel($parent, $namespace, $class, $warmupDir);
|
||||
$kernel->boot();
|
||||
|
||||
$warmer = $kernel->getContainer()->get('cache_warmer');
|
||||
|
||||
// warmup temporary dir
|
||||
$warmer = $tempKernel->getContainer()->get('cache_warmer');
|
||||
if ($enableOptionalWarmers) {
|
||||
$warmer->enableOptionalWarmers();
|
||||
}
|
||||
|
||||
$warmer->warmUp($warmupDir);
|
||||
|
||||
// fix references to the Kernel in .meta files
|
||||
foreach (Finder::create()->files()->name('*.meta')->in($warmupDir) as $file) {
|
||||
// fix meta references to the Kernel
|
||||
$content = preg_replace(
|
||||
'/C\:\d+\:"'.preg_quote($class.$this->getTempKernelSuffix(), '"/').'"/',
|
||||
sprintf('C:%s:"%s"', strlen($class), $class),
|
||||
file_put_contents($file, preg_replace(
|
||||
'/(C\:\d+\:)"'.get_class($tempKernel).'"/',
|
||||
sprintf('$1"%s"', $realKernelClass),
|
||||
file_get_contents($file)
|
||||
);
|
||||
|
||||
// fix meta references to cache files
|
||||
$realWarmupDir = substr($warmupDir, 0, -4);
|
||||
$content = preg_replace_callback(
|
||||
'/s\:\d+\:"'.preg_quote($warmupDir, '/').'([^"]+)"/',
|
||||
function (array $matches) use ($realWarmupDir) {
|
||||
$path = $realWarmupDir.$matches[1];
|
||||
return sprintf('s:%s:"%s"', strlen($path), $path);
|
||||
},
|
||||
$content
|
||||
);
|
||||
));
|
||||
}
|
||||
|
||||
// fix references to cached files with the real cache directory name
|
||||
foreach (Finder::create()->files()->in($warmupDir) as $file) {
|
||||
$content = str_replace($warmupDir, $realCacheDir, file_get_contents($file));
|
||||
file_put_contents($file, $content);
|
||||
}
|
||||
|
||||
// fix container files and classes
|
||||
$regex = '/'.preg_quote($this->getTempKernelSuffix(), '/').'/';
|
||||
foreach (Finder::create()->files()->name(get_class($kernel->getContainer()).'*')->in($warmupDir) as $file) {
|
||||
$content = file_get_contents($file);
|
||||
$content = preg_replace($regex, '', $content);
|
||||
|
||||
// fix absolute paths to the cache directory
|
||||
$content = preg_replace('/'.preg_quote($warmupDir, '/').'/', preg_replace('/_new$/', '', $warmupDir), $content);
|
||||
|
||||
file_put_contents(preg_replace($regex, '', $file), $content);
|
||||
// fix references to kernel/container related classes
|
||||
$search = $tempKernel->getName().ucfirst($tempKernel->getEnvironment());
|
||||
$replace = $realKernel->getName().ucfirst($realKernel->getEnvironment());
|
||||
foreach (Finder::create()->files()->name($search.'*')->in($warmupDir) as $file) {
|
||||
$content = str_replace($search, $replace, file_get_contents($file));
|
||||
file_put_contents(str_replace($search, $replace, $file), $content);
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getTempKernelSuffix()
|
||||
/**
|
||||
* @deprecated to be removed in 2.3
|
||||
*/
|
||||
protected function getTempSuffix()
|
||||
{
|
||||
if (null === $this->name) {
|
||||
$this->name = '__'.uniqid().'__';
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
protected function getTempKernel(KernelInterface $parent, $namespace, $class, $warmupDir)
|
||||
/**
|
||||
* @param KernelInterface $parent
|
||||
* @param string $namespace
|
||||
* @param string $parentClass
|
||||
* @param string $warmupDir
|
||||
*
|
||||
* @return KernelInterface
|
||||
*/
|
||||
protected function getTempKernel(KernelInterface $parent, $namespace, $parentClass, $warmupDir)
|
||||
{
|
||||
$suffix = $this->getTempKernelSuffix();
|
||||
$rootDir = $parent->getRootDir();
|
||||
// the temp kernel class name must have the same length than the real one
|
||||
// to avoid the many problems in serialized resources files
|
||||
$class = substr($parentClass, 0, -1).'_';
|
||||
// the temp kernel name must be changed too
|
||||
$name = substr($parent->getName(), 0, -1).'_';
|
||||
$code = <<<EOF
|
||||
<?php
|
||||
|
||||
namespace $namespace
|
||||
{
|
||||
class $class$suffix extends $class
|
||||
class $class extends $parentClass
|
||||
{
|
||||
public function getCacheDir()
|
||||
{
|
||||
return '$warmupDir';
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return '$name';
|
||||
}
|
||||
|
||||
public function getRootDir()
|
||||
{
|
||||
return '$rootDir';
|
||||
}
|
||||
|
||||
protected function getContainerClass()
|
||||
{
|
||||
return parent::getContainerClass().'$suffix';
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF;
|
||||
@ -190,7 +193,7 @@ EOF;
|
||||
file_put_contents($file = $warmupDir.'/kernel.tmp', $code);
|
||||
require_once $file;
|
||||
@unlink($file);
|
||||
$class = "$namespace\\$class$suffix";
|
||||
$class = "$namespace\\$class";
|
||||
|
||||
return new $class($parent->getEnvironment(), $parent->isDebug());
|
||||
}
|
||||
|
@ -109,7 +109,11 @@ class CookieJar
|
||||
}
|
||||
|
||||
foreach ($cookies as $cookie) {
|
||||
try {
|
||||
$this->set(Cookie::fromString($cookie, $uri));
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
// invalid cookies are just ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,6 +82,13 @@ class CookieJarTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('bar', $cookieJar->get('bar')->getValue(), '->updateFromSetCookie() keeps existing cookies');
|
||||
}
|
||||
|
||||
public function testUpdateFromEmptySetCookie()
|
||||
{
|
||||
$cookieJar = new CookieJar();
|
||||
$cookieJar->updateFromSetCookie(array(''));
|
||||
$this->assertEquals(array(), $cookieJar->all());
|
||||
}
|
||||
|
||||
public function testUpdateFromSetCookieWithMultipleCookies()
|
||||
{
|
||||
$timestamp = time() + 3600;
|
||||
|
@ -250,7 +250,7 @@ class Store implements StoreInterface
|
||||
// As per the RFC, invalidate Location and Content-Location URLs if present
|
||||
foreach (array('Location', 'Content-Location') as $header) {
|
||||
if ($uri = $request->headers->get($header)) {
|
||||
$subRequest = Request::create($uri, 'get', array(), array(), array(), $request->server->all());
|
||||
$subRequest = call_user_func(array(get_class($request), 'create'), 'get', array(), array(), array(), $request->server->all());
|
||||
|
||||
$this->invalidate($subRequest);
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ class HttpUtils
|
||||
*/
|
||||
public function createRequest(Request $request, $path)
|
||||
{
|
||||
$newRequest = Request::create($this->generateUri($request, $path), 'get', array(), $request->cookies->all(), array(), $request->server->all());
|
||||
$newRequest = call_user_func(array(get_class($request), 'create'), $this->generateUri($request, $path), 'get', array(), $request->cookies->all(), array(), $request->server->all());
|
||||
if ($request->hasSession()) {
|
||||
$newRequest->setSession($request->getSession());
|
||||
}
|
||||
@ -140,6 +140,16 @@ class HttpUtils
|
||||
throw new \LogicException('You must provide a UrlGeneratorInterface instance to be able to use routes.');
|
||||
}
|
||||
|
||||
return $this->urlGenerator->generate($path, array(), UrlGeneratorInterface::ABSOLUTE_URL);
|
||||
$url = $this->urlGenerator->generate($path, $attributes, UrlGeneratorInterface::ABSOLUTE_URL);
|
||||
|
||||
// unnecessary query string parameters must be removed from url
|
||||
// (ie. query parameters that are presents in $attributes)
|
||||
// fortunately, they all are, so we have to remove entire query string
|
||||
$position = strpos($url, '?');
|
||||
if (false !== $position) {
|
||||
$url = substr($url, 0, $position);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
@ -137,13 +137,25 @@ class HttpUtilsTest extends \PHPUnit_Framework_TestCase
|
||||
$utils->checkRequestPath($this->getRequest(), 'foobar');
|
||||
}
|
||||
|
||||
private function getUrlGenerator()
|
||||
public function testGenerateUrlRemovesQueryString()
|
||||
{
|
||||
$method = new \ReflectionMethod('Symfony\Component\Security\Http\HttpUtils', 'generateUrl');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$utils = new HttpUtils($this->getUrlGenerator());
|
||||
$this->assertEquals('/foo/bar', $method->invoke($utils, 'route_name'));
|
||||
|
||||
$utils = new HttpUtils($this->getUrlGenerator('/foo/bar?param=value'));
|
||||
$this->assertEquals('/foo/bar', $method->invoke($utils, 'route_name'));
|
||||
}
|
||||
|
||||
private function getUrlGenerator($generatedUrl = '/foo/bar')
|
||||
{
|
||||
$urlGenerator = $this->getMock('Symfony\Component\Routing\Generator\UrlGeneratorInterface');
|
||||
$urlGenerator
|
||||
->expects($this->any())
|
||||
->method('generate')
|
||||
->will($this->returnValue('/foo/bar'))
|
||||
->will($this->returnValue($generatedUrl))
|
||||
;
|
||||
|
||||
return $urlGenerator;
|
||||
|
@ -27,24 +27,30 @@ class XliffFileDumper extends FileDumper
|
||||
{
|
||||
$dom = new \DOMDocument('1.0', 'utf-8');
|
||||
$dom->formatOutput = true;
|
||||
|
||||
$xliff = $dom->appendChild($dom->createElement('xliff'));
|
||||
$xliff->setAttribute('version', '1.2');
|
||||
$xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:1.2');
|
||||
|
||||
$xliffFile = $xliff->appendChild($dom->createElement('file'));
|
||||
$xliffFile->setAttribute('source-language', $messages->getLocale());
|
||||
$xliffFile->setAttribute('datatype', 'plaintext');
|
||||
$xliffFile->setAttribute('original', 'file.ext');
|
||||
|
||||
$xliffBody = $xliffFile->appendChild($dom->createElement('body'));
|
||||
$id = 1;
|
||||
foreach ($messages->all($domain) as $source => $target) {
|
||||
$trans = $dom->createElement('trans-unit');
|
||||
$trans->setAttribute('id', $id);
|
||||
$s = $trans->appendChild($dom->createElement('source'));
|
||||
$translation = $dom->createElement('trans-unit');
|
||||
|
||||
$translation->setAttribute('id', md5($source));
|
||||
$translation->setAttribute('resname', $source);
|
||||
|
||||
$s = $translation->appendChild($dom->createElement('source'));
|
||||
$s->appendChild($dom->createTextNode($source));
|
||||
$t = $trans->appendChild($dom->createElement('target'));
|
||||
|
||||
$t = $translation->appendChild($dom->createElement('target'));
|
||||
$t->appendChild($dom->createTextNode($target));
|
||||
$xliffBody->appendChild($trans);
|
||||
$id++;
|
||||
|
||||
$xliffBody->appendChild($translation);
|
||||
}
|
||||
|
||||
return $dom->saveXML();
|
||||
|
@ -45,10 +45,14 @@ class XliffFileLoader implements LoaderInterface
|
||||
|
||||
$catalogue = new MessageCatalogue($locale);
|
||||
foreach ($xml->xpath('//xliff:trans-unit') as $translation) {
|
||||
if (!isset($translation->source) || !isset($translation->target)) {
|
||||
$attributes = $translation->attributes();
|
||||
|
||||
if (!(isset($attributes['resname']) || isset($translation->source)) || !isset($translation->target)) {
|
||||
continue;
|
||||
}
|
||||
$catalogue->set((string) $translation->source, (string) $translation->target, $domain);
|
||||
|
||||
$source = isset($attributes['resname']) && $attributes['resname'] ? $attributes['resname'] : $translation->source;
|
||||
$catalogue->set((string) $source, (string) $translation->target, $domain);
|
||||
}
|
||||
$catalogue->addResource(new FileResource($resource));
|
||||
|
||||
@ -60,6 +64,8 @@ class XliffFileLoader implements LoaderInterface
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*
|
||||
* @return \SimpleXMLElement
|
||||
*
|
||||
* @throws InvalidResourceException
|
||||
|
@ -33,6 +33,14 @@ class XliffFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
|
||||
}
|
||||
|
||||
public function testLoadWithResname()
|
||||
{
|
||||
$loader = new XliffFileLoader();
|
||||
$catalogue = $loader->load(__DIR__.'/../fixtures/resname.xlf', 'en', 'domain1');
|
||||
|
||||
$this->assertEquals(array('foo' => 'bar', 'bar' => 'baz', 'baz' => 'foo'), $catalogue->all('domain1'));
|
||||
}
|
||||
|
||||
public function testIncompleteResource()
|
||||
{
|
||||
$loader = new XliffFileLoader();
|
||||
|
19
src/Symfony/Component/Translation/Tests/fixtures/resname.xlf
vendored
Normal file
19
src/Symfony/Component/Translation/Tests/fixtures/resname.xlf
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
|
||||
<file source-language="en" datatype="plaintext" original="file.ext">
|
||||
<body>
|
||||
<trans-unit id="1" resname="foo">
|
||||
<source></source>
|
||||
<target>bar</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="2" resname="bar">
|
||||
<source>bar source</source>
|
||||
<target>baz</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="3">
|
||||
<source>baz</source>
|
||||
<target>foo</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
@ -2,11 +2,11 @@
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
|
||||
<file source-language="en" datatype="plaintext" original="file.ext">
|
||||
<body>
|
||||
<trans-unit id="1">
|
||||
<trans-unit id="acbd18db4cc2f85cedef654fccc4a4d8" resname="foo">
|
||||
<source>foo</source>
|
||||
<target>bar</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="2">
|
||||
<trans-unit id="3c6e0b8a9c15224a8228b9a98ca1531d" resname="key">
|
||||
<source>key</source>
|
||||
<target></target>
|
||||
</trans-unit>
|
||||
|
@ -37,8 +37,21 @@ class FileValidator extends ConstraintValidator
|
||||
if ($value instanceof UploadedFile && !$value->isValid()) {
|
||||
switch ($value->getError()) {
|
||||
case UPLOAD_ERR_INI_SIZE:
|
||||
if ($constraint->maxSize) {
|
||||
if (ctype_digit((string) $constraint->maxSize)) {
|
||||
$maxSize = (int) $constraint->maxSize;
|
||||
} elseif (preg_match('/^\d++k$/', $constraint->maxSize)) {
|
||||
$maxSize = $constraint->maxSize * 1024;
|
||||
} elseif (preg_match('/^\d++M$/', $constraint->maxSize)) {
|
||||
$maxSize = $constraint->maxSize * 1048576;
|
||||
} else {
|
||||
throw new ConstraintDefinitionException(sprintf('"%s" is not a valid maximum size', $constraint->maxSize));
|
||||
}
|
||||
$maxSize = min(UploadedFile::getMaxFilesize(), $maxSize);
|
||||
} else {
|
||||
$maxSize = UploadedFile::getMaxFilesize();
|
||||
$maxSize = $constraint->maxSize ? min($maxSize, $constraint->maxSize) : $maxSize;
|
||||
}
|
||||
|
||||
$this->context->addViolation($constraint->uploadIniSizeErrorMessage, array(
|
||||
'{{ limit }}' => $maxSize,
|
||||
'{{ suffix }}' => 'bytes',
|
||||
@ -97,15 +110,15 @@ class FileValidator extends ConstraintValidator
|
||||
if ($constraint->maxSize) {
|
||||
if (ctype_digit((string) $constraint->maxSize)) {
|
||||
$size = filesize($path);
|
||||
$limit = $constraint->maxSize;
|
||||
$limit = (int) $constraint->maxSize;
|
||||
$suffix = 'bytes';
|
||||
} elseif (preg_match('/^(\d+)k$/', $constraint->maxSize, $matches)) {
|
||||
} elseif (preg_match('/^\d++k$/', $constraint->maxSize)) {
|
||||
$size = round(filesize($path) / 1000, 2);
|
||||
$limit = $matches[1];
|
||||
$limit = (int) $constraint->maxSize;
|
||||
$suffix = 'kB';
|
||||
} elseif (preg_match('/^(\d+)M$/', $constraint->maxSize, $matches)) {
|
||||
} elseif (preg_match('/^\d++M$/', $constraint->maxSize)) {
|
||||
$size = round(filesize($path) / 1000000, 2);
|
||||
$limit = $matches[1];
|
||||
$limit = (int) $constraint->maxSize;
|
||||
$suffix = 'MB';
|
||||
} else {
|
||||
throw new ConstraintDefinitionException(sprintf('"%s" is not a valid maximum size', $constraint->maxSize));
|
||||
|
@ -288,12 +288,13 @@ abstract class FileValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
/**
|
||||
* @dataProvider uploadedFileErrorProvider
|
||||
*/
|
||||
public function testUploadedFileError($error, $message, array $params = array())
|
||||
public function testUploadedFileError($error, $message, array $params = array(), $maxSize = null)
|
||||
{
|
||||
$file = new UploadedFile('/path/to/file', 'originalName', 'mime', 0, $error);
|
||||
|
||||
$constraint = new File(array(
|
||||
$message => 'myMessage',
|
||||
'maxSize' => $maxSize
|
||||
));
|
||||
|
||||
$this->context->expects($this->once())
|
||||
@ -316,10 +317,24 @@ abstract class FileValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
);
|
||||
|
||||
if (class_exists('Symfony\Component\HttpFoundation\File\UploadedFile')) {
|
||||
// when no maxSize is specified on constraint, it should use the ini value
|
||||
$tests[] = array(UPLOAD_ERR_INI_SIZE, 'uploadIniSizeErrorMessage', array(
|
||||
'{{ limit }}' => UploadedFile::getMaxFilesize(),
|
||||
'{{ suffix }}' => 'bytes',
|
||||
));
|
||||
|
||||
// it should use the smaller limitation (maxSize option in this case)
|
||||
$tests[] = array(UPLOAD_ERR_INI_SIZE, 'uploadIniSizeErrorMessage', array(
|
||||
'{{ limit }}' => 1,
|
||||
'{{ suffix }}' => 'bytes',
|
||||
), '1');
|
||||
|
||||
// it correctly parses the maxSize option and not only uses simple string comparison
|
||||
// 1000M should be bigger than the ini value
|
||||
$tests[] = array(UPLOAD_ERR_INI_SIZE, 'uploadIniSizeErrorMessage', array(
|
||||
'{{ limit }}' => UploadedFile::getMaxFilesize(),
|
||||
'{{ suffix }}' => 'bytes',
|
||||
), '1000M');
|
||||
}
|
||||
|
||||
return $tests;
|
||||
|
Reference in New Issue
Block a user