merged 2.0

This commit is contained in:
Fabien Potencier 2011-09-28 16:08:31 +02:00
commit 885bb33791
28 changed files with 288 additions and 35 deletions

View File

@ -344,6 +344,19 @@ class FrameworkExtension extends Extension
$namedPackages,
));
// Apply request scope to assets helper if one or more packages are request-scoped
$requireRequestScope = array_reduce(
$namedPackages,
function($v, Reference $ref) use ($container) {
return $v || 'request' === $container->getDefinition($ref)->getScope();
},
'request' === $defaultPackage->getScope()
);
if ($requireRequestScope) {
$container->getDefinition('templating.helper.assets')->setScope('request');
}
if (!empty($config['loaders'])) {
$loaders = array_map(function($loader) { return new Reference($loader); }, $config['loaders']);

View File

@ -34,7 +34,7 @@
<tag name="templating.helper" alias="slots" />
</service>
<service id="templating.helper.assets" class="%templating.helper.assets.class%" scope="request">
<service id="templating.helper.assets" class="%templating.helper.assets.class%">
<tag name="templating.helper" alias="assets" />
<argument /> <!-- default package -->
<argument type="collection" /> <!-- named packages -->

View File

@ -45,7 +45,7 @@ class Router extends BaseRouter
}
/**
* @{inheritdoc}
* {@inheritdoc}
*/
public function getRouteCollection()
{

View File

@ -0,0 +1,14 @@
<?php
$container->loadFromExtension('framework', array(
'secret' => 's3cr3t',
'templating' => array(
'assets_base_urls' => 'https://cdn.example.com',
'engines' => array('php', 'twig'),
'packages' => array(
'images' => array(
'base_urls' => 'https://images.example.com',
),
),
),
));

View File

@ -0,0 +1,19 @@
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:framework="http://symfony.com/schema/dic/symfony"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
<framework:config secret="s3cr3t">
<framework:templating>
<framework:engine>php</framework:engine>
<framework:engine>twig</framework:engine>
<framework:assets-base-url>https://cdn.example.com</framework:assets-base-url>
<framework:package name="images">
<framework:base-url>https://images.example.com</framework:base-url>
</framework:package>
</framework:templating>
</framework:config>
</container>

View File

@ -0,0 +1,8 @@
framework:
secret: s3cr3t
templating:
assets_base_urls: https://cdn.example.com
engines: [php, twig]
packages:
images:
base_urls: https://images.example.com

View File

@ -96,6 +96,8 @@ abstract class FrameworkExtensionTest extends TestCase
$this->assertTrue($container->hasDefinition('templating.name_parser'), '->registerTemplatingConfiguration() loads templating.xml');
$this->assertEquals('request', $container->getDefinition('templating.helper.assets')->getScope(), '->registerTemplatingConfiguration() sets request scope on assets helper if one or more packages are request-scopes');
// default package should have one http base url and path package ssl url
$this->assertTrue($container->hasDefinition('templating.asset.default_package.http'));
$package = $container->getDefinition('templating.asset.default_package.http');
@ -125,6 +127,13 @@ abstract class FrameworkExtensionTest extends TestCase
$this->assertEquals(array('FrameworkBundle:Form', 'theme1', 'theme2'), $container->getParameter('templating.helper.form.resources'), '->registerTemplatingConfiguration() registers the theme and adds the base theme');
}
public function testTemplatingAssetsHelperScopeDependsOnPackageArgumentScopes()
{
$container = $this->createContainerFromFile('templating_url_package');
$this->assertNotEquals('request', $container->getDefinition('templating.helper.assets')->getScope(), '->registerTemplatingConfiguration() does not set request scope on assets helper if no packages are request-scopes');
}
public function testTranslator()
{
$container = $this->createContainerFromFile('full');

View File

@ -0,0 +1,126 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Tests\Translation;
use Symfony\Bundle\FrameworkBundle\Translation\Translator;
use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\HttpKernel\Util\Filesystem;
class TranslatorTest extends \PHPUnit_Framework_TestCase
{
protected $tmpDir;
public function setUp()
{
$this->tmpDir = sys_get_temp_dir().'/sf2_translation';
$this->deleteTmpDir();
}
public function tearDown()
{
$this->deleteTmpDir();
}
protected function deleteTmpDir()
{
if (!file_exists($dir = $this->tmpDir)) {
return;
}
$fs = new Filesystem();
$fs->remove($dir);
}
public function testTransWithoutCaching()
{
$translator = $this->getTranslator($this->getLoader());
$translator->setLocale('fr');
$translator->setFallbackLocale('en');
$this->assertEquals('foo (FR)', $translator->trans('foo'));
$this->assertEquals('bar (EN)', $translator->trans('bar'));
}
public function testTransWithCaching()
{
// prime the cache
$translator = $this->getTranslator($this->getLoader(), array('cache_dir' => $this->tmpDir));
$translator->setLocale('fr');
$translator->setFallbackLocale('en');
$this->assertEquals('foo (FR)', $translator->trans('foo'));
$this->assertEquals('bar (EN)', $translator->trans('bar'));
// do it another time as the cache is primed now
$loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
$translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir));
$translator->setLocale('fr');
$translator->setFallbackLocale('en');
$this->assertEquals('foo (FR)', $translator->trans('foo'));
$this->assertEquals('bar (EN)', $translator->trans('bar'));
}
protected function getCatalogue($locale, $messages)
{
$catalogue = new MessageCatalogue($locale);
foreach ($messages as $key => $translation) {
$catalogue->set($key, $translation);
}
return $catalogue;
}
protected function getLoader()
{
$loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
$loader
->expects($this->at(0))
->method('load')
->will($this->returnValue($this->getCatalogue('fr', array('foo' => 'foo (FR)'))))
;
$loader
->expects($this->at(1))
->method('load')
->will($this->returnValue($this->getCatalogue('en', array('foo' => 'foo (EN)', 'bar' => 'bar (EN)'))))
;
return $loader;
}
protected function getContainer($loader)
{
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
$container
->expects($this->any())
->method('get')
->will($this->returnValue($loader))
;
return $container;
}
public function getTranslator($loader, $options = array())
{
$translator = new Translator(
$this->getContainer($loader),
$this->getMock('Symfony\Component\Translation\MessageSelector'),
array('loader' => 'loader'),
$options
);
$translator->addResource('loader', 'foo', 'fr');
$translator->addResource('loader', 'foo', 'en');
return $translator;
}
}

View File

@ -98,10 +98,34 @@ class Translator extends BaseTranslator
parent::doLoadCatalogue($locale);
$content = sprintf(
"<?php use Symfony\Component\Translation\MessageCatalogue; return new MessageCatalogue('%s', %s);",
$fallbackContent = '';
$fallback = $this->computeFallbackLocale($locale);
if ($fallback && $fallback != $locale) {
$fallbackContent = sprintf(<<<EOF
\$catalogue->addFallbackCatalogue(new MessageCatalogue('%s', %s));
EOF
,
$fallback,
var_export($this->catalogues[$fallback]->all(), true)
);
}
$content = sprintf(<<<EOF
<?php
use Symfony\Component\Translation\MessageCatalogue;
\$catalogue = new MessageCatalogue('%s', %s);
%s
return \$catalogue;
EOF
,
$locale,
var_export($this->catalogues[$locale]->all(), true)
var_export($this->catalogues[$locale]->all(), true),
$fallbackContent
);
$cache->write($content, $this->catalogues[$locale]->getResources());

View File

@ -67,7 +67,7 @@ class Cookie
}
$this->name = $name;
$this->expires = null === $expires ? null : (integer) $expires;
$this->path = empty($path) ? null : $path;
$this->path = empty($path) ? '/' : $path;
$this->domain = $domain;
$this->secure = (Boolean) $secure;
$this->httponly = (Boolean) $httponly;
@ -92,7 +92,7 @@ class Cookie
$cookie .= '; domain='.$this->domain;
}
if (null !== $this->path) {
if ('/' !== $this->path) {
$cookie .= '; path='.$this->path;
}
@ -130,8 +130,8 @@ class Cookie
$values = array(
'name' => trim($name),
'value' => trim($value),
'expires' => null,
'path' => null,
'expires' => null,
'path' => '/',
'domain' => '',
'secure' => false,
'httponly' => false,
@ -262,7 +262,7 @@ class Cookie
*/
public function getPath()
{
return null !== $this->path ? $this->path : '/';
return $this->path;
}
/**

View File

@ -84,7 +84,7 @@ class ClassCollectionLoader
$files = array();
$content = '';
foreach ($classes as $class) {
if (!class_exists($class) && !interface_exists($class) && function_exists('trait_exists') && !trait_exists($class)) {
if (!class_exists($class) && !interface_exists($class) && (!function_exists('trait_exists') || !trait_exists($class))) {
throw new \InvalidArgumentException(sprintf('Unable to load class "%s"', $class));
}

View File

@ -55,7 +55,7 @@ class DebugUniversalClassLoader extends UniversalClassLoader
if ($file = $this->findFile($class)) {
require $file;
if (!class_exists($class, false) && !interface_exists($class, false) && function_exists('trait_exists') && !trait_exists($class)) {
if (!class_exists($class, false) && !interface_exists($class, false) && (!function_exists('trait_exists') || !trait_exists($class))) {
throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file));
}
}

View File

@ -586,7 +586,7 @@ class Application
$commands = array();
foreach ($this->commands as $name => $command) {
if ($namespace === $this->extractNamespace($name)) {
if ($namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1)) {
$commands[$name] = $command;
}
}

View File

@ -71,7 +71,7 @@ class Cookie
$this->value = $value;
$this->domain = $domain;
$this->expire = $expire;
$this->path = $path;
$this->path = empty($path) ? '/' : $path;
$this->secure = (Boolean) $secure;
$this->httpOnly = (Boolean) $httpOnly;
}
@ -90,8 +90,8 @@ class Cookie
}
}
if (null !== $this->getPath()) {
$str .= '; path='.$this->getPath();
if ('/' !== $this->path) {
$str .= '; path='.$this->path;
}
if (null !== $this->getDomain()) {

View File

@ -44,14 +44,14 @@ class Request
public $query;
/**
* @var \Symfony\Component\HttpFoundation\ParameterBag
* @var \Symfony\Component\HttpFoundation\ServerBag
*
* @api
*/
public $server;
/**
* @var \Symfony\Component\HttpFoundation\ParameterBag
* @var \Symfony\Component\HttpFoundation\FileBag
*
* @api
*/
@ -1235,7 +1235,7 @@ class Request
$requestUri = substr($requestUri, 0, $pos);
}
if ((null !== $baseUrl) && (false === ($pathInfo = substr($requestUri, strlen($baseUrl))))) {
if ((null !== $baseUrl) && (false === ($pathInfo = substr(urldecode($requestUri), strlen(urldecode($baseUrl)))))) {
// If substr() returns false then PATH_INFO is set to an empty string
return '/';
} elseif (null === $baseUrl) {

View File

@ -142,8 +142,12 @@ class ResponseHeaderBag extends HeaderBag
*
* @api
*/
public function removeCookie($name, $path = null, $domain = null)
public function removeCookie($name, $path = '/', $domain = null)
{
if (null === $path) {
$path = '/';
}
unset($this->cookies[$domain][$path][$name]);
if (empty($this->cookies[$domain][$path])) {
@ -198,7 +202,7 @@ class ResponseHeaderBag extends HeaderBag
*
* @api
*/
public function clearCookie($name, $path = null, $domain = null)
public function clearCookie($name, $path = '/', $domain = null)
{
$this->setCookie(new Cookie($name, null, 1, $path, $domain));
}

View File

@ -15,11 +15,11 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpFoundation\Request;
/**
* Allows to filter a controller callable
* Allows filtering of a controller callable
*
* You can call getController() to retrieve the current controller. With
* setController() you can set a new controller that is used in for processing
* a request.
* setController() you can set a new controller that is used in the processing
* of the request.
*
* Controllers should be callables.
*

View File

@ -198,7 +198,7 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec
$data[] = $tmp;
$data[] = $value;
}
} elseif (key_exists($key, $data)) {
} elseif (array_key_exists($key, $data)) {
if ((false === is_array($data[$key])) || (false === isset($data[$key][0]))) {
$data[$key] = array($data[$key]);
}

View File

@ -181,6 +181,7 @@ class Translator implements TranslatorInterface
private function loadFallbackCatalogues($locale)
{
$current = $this->catalogues[$locale];
foreach ($this->computeFallbackLocales($locale) as $fallback) {
if (!isset($this->catalogues[$fallback])) {
$this->doLoadCatalogue($fallback);

View File

@ -65,7 +65,7 @@ class CookieTest extends \PHPUnit_Framework_TestCase
{
$this->assertEquals('foo=bar; domain=www.example.com', (string) Cookie::FromString('foo=bar', 'http://www.example.com/'));
$this->assertEquals('foo=bar; domain=www.example.com; path=/foo', (string) Cookie::FromString('foo=bar', 'http://www.example.com/foo/bar'));
$this->assertEquals('foo=bar; domain=www.example.com; path=/', (string) Cookie::FromString('foo=bar; path=/', 'http://www.example.com/foo/bar'));
$this->assertEquals('foo=bar; domain=www.example.com', (string) Cookie::FromString('foo=bar; path=/', 'http://www.example.com/foo/bar'));
$this->assertEquals('foo=bar; domain=www.myotherexample.com', (string) Cookie::FromString('foo=bar; domain=www.myotherexample.com', 'http://www.example.com/'));
}

View File

@ -63,4 +63,12 @@ EOF;
$this->assertEquals($expected, ClassCollectionLoader::fixNamespaceDeclarations($source));
}
/**
* @expectedException InvalidArgumentException
*/
public function testUnableToLoadClassException()
{
ClassCollectionLoader::load(array('SomeNotExistingClass'), '', 'foo', false);
}
}

View File

@ -142,10 +142,10 @@ class CookieTest extends \PHPUnit_Framework_TestCase
{
$cookie = new Cookie('foo', 'bar', strtotime('Fri, 20-May-2011 15:25:52 GMT'), '/', '.myfoodomain.com', true);
$this->assertEquals('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; path=/; domain=.myfoodomain.com; secure; httponly', $cookie->__toString(), '->__toString() returns string representation of the cookie');
$this->assertEquals('foo=bar; expires=Fri, 20-May-2011 15:25:52 GMT; domain=.myfoodomain.com; secure; httponly', $cookie->__toString(), '->__toString() returns string representation of the cookie');
$cookie = new Cookie('foo', null, 1, '/', '.myfoodomain.com');
$cookie = new Cookie('foo', null, 1, '/admin/', '.myfoodomain.com');
$this->assertEquals('foo=deleted; expires=' . gmdate("D, d-M-Y H:i:s T", time()-31536001) . '; path=/; domain=.myfoodomain.com; httponly', $cookie->__toString(), '->__toString() returns string representation of a cleared cookie if value is NULL');
$this->assertEquals('foo=deleted; expires=' . gmdate("D, d-M-Y H:i:s T", time()-31536001) . '; path=/admin/; domain=.myfoodomain.com; httponly', $cookie->__toString(), '->__toString() returns string representation of a cleared cookie if value is NULL');
}
}

View File

@ -708,6 +708,31 @@ class RequestTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('', $request->getBasePath());
}
public function testGetPathInfo()
{
$request = new Request();
$this->assertEquals('/', $request->getPathInfo());
$server = array();
$server['REQUEST_URI'] = '/path/info';
$request->initialize(array(), array(), array(), array(), array(), $server);
$this->assertEquals('/path/info', $request->getPathInfo());
$server = array();
$server['REQUEST_URI'] = '/path test/info';
$request->initialize(array(), array(), array(), array(), array(), $server);
$this->assertEquals('/path test/info', $request->getPathInfo());
$server = array();
$server['REQUEST_URI'] = '/path%20test/info';
$request->initialize(array(), array(), array(), array(), array(), $server);
$this->assertEquals('/path test/info', $request->getPathInfo());
}
public function testGetPreferredLanguage()
{
$request = new Request();

View File

@ -69,7 +69,7 @@ class ResponseHeaderBagTest extends \PHPUnit_Framework_TestCase
$bag = new ResponseHeaderBag(array());
$bag->setCookie(new Cookie('foo', 'bar'));
$this->assertContains("Set-Cookie: foo=bar; path=/; httponly", explode("\r\n", $bag->__toString()));
$this->assertContains("Set-Cookie: foo=bar; httponly", explode("\r\n", $bag->__toString()));
$bag->clearCookie('foo');
@ -90,7 +90,7 @@ class ResponseHeaderBagTest extends \PHPUnit_Framework_TestCase
$this->assertContains("Set-Cookie: foo=bar; path=/path/foo; domain=foo.bar; httponly", $headers);
$this->assertContains("Set-Cookie: foo=bar; path=/path/foo; domain=foo.bar; httponly", $headers);
$this->assertContains("Set-Cookie: foo=bar; path=/path/bar; domain=bar.foo; httponly", $headers);
$this->assertContains("Set-Cookie: foo=bar; path=/; httponly", $headers);
$this->assertContains("Set-Cookie: foo=bar; httponly", $headers);
$cookies = $bag->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
$this->assertTrue(isset($cookies['foo.bar']['/path/foo']['foo']));

View File

@ -40,9 +40,9 @@ class CookieClearingLogoutHandlerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('foo.foo', $cookie->getDomain());
$this->assertTrue($cookie->isCleared());
$cookie = $cookies['']['']['foo2'];
$cookie = $cookies['']['/']['foo2'];
$this->assertStringStartsWith('foo2', $cookie->getName());
$this->assertNull($cookie->getPath());
$this->assertEquals('/', $cookie->getPath());
$this->assertNull($cookie->getDomain());
$this->assertTrue($cookie->isCleared());
}

View File

@ -222,7 +222,7 @@ class PersistentTokenBasedRememberMeServicesTest extends \PHPUnit_Framework_Test
$cookie = $request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME);
$this->assertTrue($cookie->isCleared());
$this->assertNull($cookie->getPath());
$this->assertEquals('/', $cookie->getPath());
$this->assertNull($cookie->getDomain());
}

View File

@ -155,7 +155,7 @@ class TokenBasedRememberMeServicesTest extends \PHPUnit_Framework_TestCase
$cookie = $request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME);
$this->assertTrue($cookie->isCleared());
$this->assertNull($cookie->getPath());
$this->assertEquals('/', $cookie->getPath());
$this->assertNull($cookie->getDomain());
}

View File

@ -19,6 +19,8 @@ http://symfony.com/download
*/
set_time_limit(0);
if (!is_dir($vendorDir = dirname(__FILE__).'/vendor')) {
mkdir($vendorDir, 0777, true);
}