Merge branch '2.2'
* 2.2: Fixed XmlFileLoaderTest::testLoadThrowsExceptionWithInvalidFileEvenWithoutSchemaValidation moved file hash calculation to own method [Validator] Add check for existing metadata on property added support for the X-Forwarded-For header (closes #6982, closes #7000) fixed the IP address in HttpCache when calling the backend [EventDispatcher] Added assertion. [EventDispathcer] Fix removeListener [DependencyInjection] Add clone for resources which were introduced in 2.1 [DependencyInjection] Allow frozen containers to be dumped to graphviz Fix 'undefined index' error, when entering scope recursively [Security] fixed session creation on login (closes #7011) replaced usage of the deprecated pattern routing key (replaced with path) Add dot character `.` to legal mime subtype regular expression [HttpFoundation] fixed the creation of sub-requests under some circumstancies (closes #6923, closes #6936)
This commit is contained in:
commit
f66e109d14
@ -1,23 +1,23 @@
|
|||||||
session_welcome:
|
session_welcome:
|
||||||
pattern: /session
|
path: /session
|
||||||
defaults: { _controller: TestBundle:Session:welcome }
|
defaults: { _controller: TestBundle:Session:welcome }
|
||||||
|
|
||||||
session_welcome_name:
|
session_welcome_name:
|
||||||
pattern: /session/{name}
|
path: /session/{name}
|
||||||
defaults: { _controller: TestBundle:Session:welcome }
|
defaults: { _controller: TestBundle:Session:welcome }
|
||||||
|
|
||||||
session_logout:
|
session_logout:
|
||||||
pattern: /session_logout
|
path: /session_logout
|
||||||
defaults: { _controller: TestBundle:Session:logout}
|
defaults: { _controller: TestBundle:Session:logout}
|
||||||
|
|
||||||
session_setflash:
|
session_setflash:
|
||||||
pattern: /session_setflash/{message}
|
path: /session_setflash/{message}
|
||||||
defaults: { _controller: TestBundle:Session:setFlash}
|
defaults: { _controller: TestBundle:Session:setFlash}
|
||||||
|
|
||||||
session_showflash:
|
session_showflash:
|
||||||
pattern: /session_showflash
|
path: /session_showflash
|
||||||
defaults: { _controller: TestBundle:Session:showFlash}
|
defaults: { _controller: TestBundle:Session:showFlash}
|
||||||
|
|
||||||
profiler:
|
profiler:
|
||||||
pattern: /profiler
|
path: /profiler
|
||||||
defaults: { _controller: TestBundle:Profiler:index }
|
defaults: { _controller: TestBundle:Profiler:index }
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
form_login:
|
form_login:
|
||||||
pattern: /login
|
path: /login
|
||||||
defaults: { _controller: CsrfFormLoginBundle:Login:login }
|
defaults: { _controller: CsrfFormLoginBundle:Login:login }
|
||||||
|
|
||||||
form_login_check:
|
form_login_check:
|
||||||
pattern: /login_check
|
path: /login_check
|
||||||
defaults: { _controller: CsrfFormLoginBundle:Login:loginCheck }
|
defaults: { _controller: CsrfFormLoginBundle:Login:loginCheck }
|
||||||
|
|
||||||
form_login_homepage:
|
form_login_homepage:
|
||||||
pattern: /
|
path: /
|
||||||
defaults: { _controller: CsrfFormLoginBundle:Login:afterLogin }
|
defaults: { _controller: CsrfFormLoginBundle:Login:afterLogin }
|
||||||
|
|
||||||
form_login_custom_target_path:
|
form_login_custom_target_path:
|
||||||
pattern: /foo
|
path: /foo
|
||||||
defaults: { _controller: CsrfFormLoginBundle:Login:afterLogin }
|
defaults: { _controller: CsrfFormLoginBundle:Login:afterLogin }
|
||||||
|
|
||||||
form_login_default_target_path:
|
form_login_default_target_path:
|
||||||
pattern: /profile
|
path: /profile
|
||||||
defaults: { _controller: CsrfFormLoginBundle:Login:afterLogin }
|
defaults: { _controller: CsrfFormLoginBundle:Login:afterLogin }
|
||||||
|
|
||||||
form_login_redirect_to_protected_resource_after_login:
|
form_login_redirect_to_protected_resource_after_login:
|
||||||
pattern: /protected-resource
|
path: /protected-resource
|
||||||
defaults: { _controller: CsrfFormLoginBundle:Login:afterLogin }
|
defaults: { _controller: CsrfFormLoginBundle:Login:afterLogin }
|
||||||
|
|
||||||
form_logout:
|
form_logout:
|
||||||
pattern: /logout_path
|
path: /logout_path
|
||||||
|
|
||||||
form_secure_action:
|
form_secure_action:
|
||||||
pattern: /secure-but-not-covered-by-access-control
|
path: /secure-but-not-covered-by-access-control
|
||||||
defaults: { _controller: CsrfFormLoginBundle:Login:secure }
|
defaults: { _controller: CsrfFormLoginBundle:Login:secure }
|
||||||
|
@ -1,29 +1,29 @@
|
|||||||
localized_login_path:
|
localized_login_path:
|
||||||
pattern: /{_locale}/login
|
path: /{_locale}/login
|
||||||
defaults: { _controller: FormLoginBundle:Localized:login }
|
defaults: { _controller: FormLoginBundle:Localized:login }
|
||||||
requirements: { _locale: "^[a-z]{2}$" }
|
requirements: { _locale: "^[a-z]{2}$" }
|
||||||
|
|
||||||
localized_check_path:
|
localized_check_path:
|
||||||
pattern: /{_locale}/login_check
|
path: /{_locale}/login_check
|
||||||
defaults: { _controller: FormLoginBundle:Localized:loginCheck }
|
defaults: { _controller: FormLoginBundle:Localized:loginCheck }
|
||||||
requirements: { _locale: "^[a-z]{2}$" }
|
requirements: { _locale: "^[a-z]{2}$" }
|
||||||
|
|
||||||
localized_default_target_path:
|
localized_default_target_path:
|
||||||
pattern: /{_locale}/profile
|
path: /{_locale}/profile
|
||||||
defaults: { _controller: FormLoginBundle:Localized:profile }
|
defaults: { _controller: FormLoginBundle:Localized:profile }
|
||||||
requirements: { _locale: "^[a-z]{2}$" }
|
requirements: { _locale: "^[a-z]{2}$" }
|
||||||
|
|
||||||
localized_logout_path:
|
localized_logout_path:
|
||||||
pattern: /{_locale}/logout
|
path: /{_locale}/logout
|
||||||
defaults: { _controller: FormLoginBundle:Localized:logout }
|
defaults: { _controller: FormLoginBundle:Localized:logout }
|
||||||
requirements: { _locale: "^[a-z]{2}$" }
|
requirements: { _locale: "^[a-z]{2}$" }
|
||||||
|
|
||||||
localized_logout_target_path:
|
localized_logout_target_path:
|
||||||
pattern: /{_locale}/
|
path: /{_locale}/
|
||||||
defaults: { _controller: FormLoginBundle:Localized:homepage }
|
defaults: { _controller: FormLoginBundle:Localized:homepage }
|
||||||
requirements: { _locale: "^[a-z]{2}$" }
|
requirements: { _locale: "^[a-z]{2}$" }
|
||||||
|
|
||||||
localized_secure_path:
|
localized_secure_path:
|
||||||
pattern: /{_locale}/secure/
|
path: /{_locale}/secure/
|
||||||
defaults: { _controller: FormLoginBundle:Localized:secure }
|
defaults: { _controller: FormLoginBundle:Localized:secure }
|
||||||
requirements: { _locale: "^[a-z]{2}$" }
|
requirements: { _locale: "^[a-z]{2}$" }
|
||||||
|
@ -1,33 +1,33 @@
|
|||||||
form_login:
|
form_login:
|
||||||
pattern: /login
|
path: /login
|
||||||
defaults: { _controller: FormLoginBundle:Login:login }
|
defaults: { _controller: FormLoginBundle:Login:login }
|
||||||
|
|
||||||
form_login_check:
|
form_login_check:
|
||||||
pattern: /login_check
|
path: /login_check
|
||||||
defaults: { _controller: FormLoginBundle:Login:loginCheck }
|
defaults: { _controller: FormLoginBundle:Login:loginCheck }
|
||||||
|
|
||||||
form_login_homepage:
|
form_login_homepage:
|
||||||
pattern: /
|
path: /
|
||||||
defaults: { _controller: FormLoginBundle:Login:afterLogin }
|
defaults: { _controller: FormLoginBundle:Login:afterLogin }
|
||||||
|
|
||||||
form_login_custom_target_path:
|
form_login_custom_target_path:
|
||||||
pattern: /foo
|
path: /foo
|
||||||
defaults: { _controller: FormLoginBundle:Login:afterLogin }
|
defaults: { _controller: FormLoginBundle:Login:afterLogin }
|
||||||
|
|
||||||
form_login_default_target_path:
|
form_login_default_target_path:
|
||||||
pattern: /profile
|
path: /profile
|
||||||
defaults: { _controller: FormLoginBundle:Login:afterLogin }
|
defaults: { _controller: FormLoginBundle:Login:afterLogin }
|
||||||
|
|
||||||
form_login_redirect_to_protected_resource_after_login:
|
form_login_redirect_to_protected_resource_after_login:
|
||||||
pattern: /protected_resource
|
path: /protected_resource
|
||||||
defaults: { _controller: FormLoginBundle:Login:afterLogin }
|
defaults: { _controller: FormLoginBundle:Login:afterLogin }
|
||||||
|
|
||||||
highly_protected_resource:
|
highly_protected_resource:
|
||||||
pattern: /highly_protected_resource
|
path: /highly_protected_resource
|
||||||
|
|
||||||
form_logout:
|
form_logout:
|
||||||
pattern: /logout_path
|
path: /logout_path
|
||||||
|
|
||||||
form_secure_action:
|
form_secure_action:
|
||||||
pattern: /secure-but-not-covered-by-access-control
|
path: /secure-but-not-covered-by-access-control
|
||||||
defaults: { _controller: FormLoginBundle:Login:secure }
|
defaults: { _controller: FormLoginBundle:Login:secure }
|
||||||
|
@ -338,8 +338,10 @@ class Container implements IntrospectableContainerInterface
|
|||||||
unset($this->scopedServices[$name]);
|
unset($this->scopedServices[$name]);
|
||||||
|
|
||||||
foreach ($this->scopeChildren[$name] as $child) {
|
foreach ($this->scopeChildren[$name] as $child) {
|
||||||
$services[$child] = $this->scopedServices[$child];
|
if (isset($this->scopedServices[$child])) {
|
||||||
unset($this->scopedServices[$child]);
|
$services[$child] = $this->scopedServices[$child];
|
||||||
|
unset($this->scopedServices[$child]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update global map
|
// update global map
|
||||||
|
@ -15,6 +15,8 @@ use Symfony\Component\DependencyInjection\Definition;
|
|||||||
use Symfony\Component\DependencyInjection\Reference;
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
use Symfony\Component\DependencyInjection\Parameter;
|
use Symfony\Component\DependencyInjection\Parameter;
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GraphvizDumper dumps a service container as a graphviz file.
|
* GraphvizDumper dumps a service container as a graphviz file.
|
||||||
@ -159,7 +161,7 @@ class GraphvizDumper extends Dumper
|
|||||||
{
|
{
|
||||||
$nodes = array();
|
$nodes = array();
|
||||||
|
|
||||||
$container = clone $this->container;
|
$container = $this->cloneContainer();
|
||||||
|
|
||||||
foreach ($container->getDefinitions() as $id => $definition) {
|
foreach ($container->getDefinitions() as $id => $definition) {
|
||||||
$nodes[$id] = array('class' => str_replace('\\', '\\\\', $this->container->getParameterBag()->resolveValue($definition->getClass())), 'attributes' => array_merge($this->options['node.definition'], array('style' => ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope() ? 'filled' : 'dotted')));
|
$nodes[$id] = array('class' => str_replace('\\', '\\\\', $this->container->getParameterBag()->resolveValue($definition->getClass())), 'attributes' => array_merge($this->options['node.definition'], array('style' => ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope() ? 'filled' : 'dotted')));
|
||||||
@ -175,13 +177,32 @@ class GraphvizDumper extends Dumper
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$container->hasDefinition($id)) {
|
if (!$container->hasDefinition($id)) {
|
||||||
$nodes[$id] = array('class' => str_replace('\\', '\\\\', get_class($service)), 'attributes' => $this->options['node.instance']);
|
$class = ('service_container' === $id) ? get_class($this->container) : get_class($service);
|
||||||
|
$nodes[$id] = array('class' => str_replace('\\', '\\\\', $class), 'attributes' => $this->options['node.instance']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $nodes;
|
return $nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function cloneContainer()
|
||||||
|
{
|
||||||
|
$parameterBag = new ParameterBag($this->container->getParameterBag()->all());
|
||||||
|
|
||||||
|
$container = new ContainerBuilder($parameterBag);
|
||||||
|
$container->setDefinitions($this->container->getDefinitions());
|
||||||
|
$container->setAliases($this->container->getAliases());
|
||||||
|
$container->setResources($this->container->getResources());
|
||||||
|
foreach ($this->container->getScopes() as $scope) {
|
||||||
|
$container->addScope($scope);
|
||||||
|
}
|
||||||
|
foreach ($this->container->getExtensions() as $extension) {
|
||||||
|
$container->registerExtension($extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $container;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the start dot.
|
* Returns the start dot.
|
||||||
*
|
*
|
||||||
|
@ -261,6 +261,38 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertFalse($container->has('a'));
|
$this->assertFalse($container->has('a'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testEnterScopeRecursivelyWithInactiveChildScopes()
|
||||||
|
{
|
||||||
|
$container = new Container();
|
||||||
|
$container->addScope(new Scope('foo'));
|
||||||
|
$container->addScope(new Scope('bar', 'foo'));
|
||||||
|
|
||||||
|
$this->assertFalse($container->isScopeActive('foo'));
|
||||||
|
|
||||||
|
$container->enterScope('foo');
|
||||||
|
|
||||||
|
$this->assertTrue($container->isScopeActive('foo'));
|
||||||
|
$this->assertFalse($container->isScopeActive('bar'));
|
||||||
|
$this->assertFalse($container->has('a'));
|
||||||
|
|
||||||
|
$a = new \stdClass();
|
||||||
|
$container->set('a', $a, 'foo');
|
||||||
|
|
||||||
|
$services = $this->getField($container, 'scopedServices');
|
||||||
|
$this->assertTrue(isset($services['foo']['a']));
|
||||||
|
$this->assertSame($a, $services['foo']['a']);
|
||||||
|
|
||||||
|
$this->assertTrue($container->has('a'));
|
||||||
|
$container->enterScope('foo');
|
||||||
|
|
||||||
|
$services = $this->getField($container, 'scopedServices');
|
||||||
|
$this->assertFalse(isset($services['a']));
|
||||||
|
|
||||||
|
$this->assertTrue($container->isScopeActive('foo'));
|
||||||
|
$this->assertFalse($container->isScopeActive('bar'));
|
||||||
|
$this->assertFalse($container->has('a'));
|
||||||
|
}
|
||||||
|
|
||||||
public function testLeaveScopeNotActive()
|
public function testLeaveScopeNotActive()
|
||||||
{
|
{
|
||||||
$container = new Container();
|
$container = new Container();
|
||||||
|
@ -48,4 +48,18 @@ class GraphvizDumperTest extends \PHPUnit_Framework_TestCase
|
|||||||
'node.missing' => array('fillcolor' => 'red', 'style' => 'empty'),
|
'node.missing' => array('fillcolor' => 'red', 'style' => 'empty'),
|
||||||
)), str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services10-1.dot')), '->dump() dumps services');
|
)), str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services10-1.dot')), '->dump() dumps services');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDumpWithFrozenContainer()
|
||||||
|
{
|
||||||
|
$container = include self::$fixturesPath.'/containers/container13.php';
|
||||||
|
$dumper = new GraphvizDumper($container);
|
||||||
|
$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services13.dot')), $dumper->dump(), '->dump() dumps services');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDumpWithFrozenCustomClassContainer()
|
||||||
|
{
|
||||||
|
$container = include self::$fixturesPath.'/containers/container14.php';
|
||||||
|
$dumper = new GraphvizDumper($container);
|
||||||
|
$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services14.dot')), $dumper->dump(), '->dump() dumps services');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
use Symfony\Component\DependencyInjection\Definition;
|
||||||
|
|
||||||
|
$container = new ContainerBuilder();
|
||||||
|
$container->
|
||||||
|
register('foo', 'FooClass')->
|
||||||
|
addArgument(new Reference('bar'))
|
||||||
|
;
|
||||||
|
$container->compile();
|
||||||
|
|
||||||
|
return $container;
|
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Container14;
|
||||||
|
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
|
||||||
|
class ProjectServiceContainer extends ContainerBuilder
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ProjectServiceContainer();
|
@ -0,0 +1,8 @@
|
|||||||
|
digraph sc {
|
||||||
|
ratio="compress"
|
||||||
|
node [fontsize="11" fontname="Arial" shape="record"];
|
||||||
|
edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"];
|
||||||
|
|
||||||
|
node_foo [label="foo\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
|
||||||
|
node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"];
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
digraph sc {
|
||||||
|
ratio="compress"
|
||||||
|
node [fontsize="11" fontname="Arial" shape="record"];
|
||||||
|
edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"];
|
||||||
|
|
||||||
|
node_service_container [label="service_container\nContainer14\\ProjectServiceContainer\n", shape=record, fillcolor="#9999ff", style="filled"];
|
||||||
|
}
|
@ -106,7 +106,7 @@ class EventDispatcher implements EventDispatcherInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->listeners[$eventName] as $priority => $listeners) {
|
foreach ($this->listeners[$eventName] as $priority => $listeners) {
|
||||||
if (false !== ($key = array_search($listener, $listeners))) {
|
if (false !== ($key = array_search($listener, $listeners, true))) {
|
||||||
unset($this->listeners[$eventName][$priority][$key], $this->sorted[$eventName]);
|
unset($this->listeners[$eventName][$priority][$key], $this->sorted[$eventName]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,6 +244,29 @@ class EventDispatcherTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->dispatcher->dispatch('test');
|
$this->dispatcher->dispatch('test');
|
||||||
$this->assertSame($this->dispatcher, $dispatcher);
|
$this->assertSame($this->dispatcher, $dispatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see https://bugs.php.net/bug.php?id=62976
|
||||||
|
*
|
||||||
|
* This bug affects:
|
||||||
|
* - The PHP 5.3 branch for versions < 5.3.18
|
||||||
|
* - The PHP 5.4 branch for versions < 5.4.8
|
||||||
|
* - The PHP 5.5 branch is not affected
|
||||||
|
*/
|
||||||
|
public function testWorkaroundForPhpBug62976()
|
||||||
|
{
|
||||||
|
$dispatcher = new EventDispatcher();
|
||||||
|
$dispatcher->addListener('bug.62976', new CallableClass());
|
||||||
|
$dispatcher->removeListener('bug.62976', function() {});
|
||||||
|
$this->assertTrue($dispatcher->hasListeners('bug.62976'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CallableClass
|
||||||
|
{
|
||||||
|
public function __invoke()
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestEventListener
|
class TestEventListener
|
||||||
|
@ -22,6 +22,7 @@ use Symfony\Component\HttpFoundation\File\Exception\FileException;
|
|||||||
* @author Igor Wiedler <igor@wiedler.ch>
|
* @author Igor Wiedler <igor@wiedler.ch>
|
||||||
* @author Jordan Alliot <jordan.alliot@gmail.com>
|
* @author Jordan Alliot <jordan.alliot@gmail.com>
|
||||||
* @author Sergey Linnik <linniksa@gmail.com>
|
* @author Sergey Linnik <linniksa@gmail.com>
|
||||||
|
* @author Povilas Skruibis <puovils@gmail.com>
|
||||||
*/
|
*/
|
||||||
class BinaryFileResponse extends Response
|
class BinaryFileResponse extends Response
|
||||||
{
|
{
|
||||||
@ -123,11 +124,23 @@ class BinaryFileResponse extends Response
|
|||||||
*/
|
*/
|
||||||
public function setAutoEtag()
|
public function setAutoEtag()
|
||||||
{
|
{
|
||||||
$this->setEtag(sha1_file($this->file->getPathname()));
|
$this->setEtag($this->calculateFileHash($this->file->getPathname()));
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate file hash
|
||||||
|
*
|
||||||
|
* @param string $filename The path to the file
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function calculateFileHash($filename)
|
||||||
|
{
|
||||||
|
return sha1_file($filename);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the Content-Disposition header with the given filename.
|
* Sets the Content-Disposition header with the given filename.
|
||||||
*
|
*
|
||||||
|
@ -77,7 +77,7 @@ class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface
|
|||||||
|
|
||||||
$type = trim(ob_get_clean());
|
$type = trim(ob_get_clean());
|
||||||
|
|
||||||
if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-]+)#i', $type, $match)) {
|
if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\.]+)#i', $type, $match)) {
|
||||||
// it's not a type, but an error message
|
// it's not a type, but an error message
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1468,12 +1468,16 @@ class Request
|
|||||||
if ($this->headers->has('X_ORIGINAL_URL') && false !== stripos(PHP_OS, 'WIN')) {
|
if ($this->headers->has('X_ORIGINAL_URL') && false !== stripos(PHP_OS, 'WIN')) {
|
||||||
// IIS with Microsoft Rewrite Module
|
// IIS with Microsoft Rewrite Module
|
||||||
$requestUri = $this->headers->get('X_ORIGINAL_URL');
|
$requestUri = $this->headers->get('X_ORIGINAL_URL');
|
||||||
|
$this->headers->remove('X_ORIGINAL_URL');
|
||||||
} elseif ($this->headers->has('X_REWRITE_URL') && false !== stripos(PHP_OS, 'WIN')) {
|
} elseif ($this->headers->has('X_REWRITE_URL') && false !== stripos(PHP_OS, 'WIN')) {
|
||||||
// IIS with ISAPI_Rewrite
|
// IIS with ISAPI_Rewrite
|
||||||
$requestUri = $this->headers->get('X_REWRITE_URL');
|
$requestUri = $this->headers->get('X_REWRITE_URL');
|
||||||
|
$this->headers->remove('X_REWRITE_URL');
|
||||||
} elseif ($this->server->get('IIS_WasUrlRewritten') == '1' && $this->server->get('UNENCODED_URL') != '') {
|
} elseif ($this->server->get('IIS_WasUrlRewritten') == '1' && $this->server->get('UNENCODED_URL') != '') {
|
||||||
// IIS7 with URL Rewrite: make sure we get the unencoded url (double slash problem)
|
// IIS7 with URL Rewrite: make sure we get the unencoded url (double slash problem)
|
||||||
$requestUri = $this->server->get('UNENCODED_URL');
|
$requestUri = $this->server->get('UNENCODED_URL');
|
||||||
|
$this->server->remove('UNENCODED_URL');
|
||||||
|
$this->server->remove('IIS_WasUrlRewritten');
|
||||||
} elseif ($this->server->has('REQUEST_URI')) {
|
} elseif ($this->server->has('REQUEST_URI')) {
|
||||||
$requestUri = $this->server->get('REQUEST_URI');
|
$requestUri = $this->server->get('REQUEST_URI');
|
||||||
// HTTP proxy reqs setup request uri with scheme and host [and port] + the url path, only use url path
|
// HTTP proxy reqs setup request uri with scheme and host [and port] + the url path, only use url path
|
||||||
@ -1487,8 +1491,12 @@ class Request
|
|||||||
if ('' != $this->server->get('QUERY_STRING')) {
|
if ('' != $this->server->get('QUERY_STRING')) {
|
||||||
$requestUri .= '?'.$this->server->get('QUERY_STRING');
|
$requestUri .= '?'.$this->server->get('QUERY_STRING');
|
||||||
}
|
}
|
||||||
|
$this->server->remove('ORIG_PATH_INFO');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// normalize the request URI to ease creating sub-requests from this request
|
||||||
|
$this->server->set('REQUEST_URI', $requestUri);
|
||||||
|
|
||||||
return $requestUri;
|
return $requestUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,6 +418,18 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
|
|||||||
$subRequest->headers->remove('if_modified_since');
|
$subRequest->headers->remove('if_modified_since');
|
||||||
$subRequest->headers->remove('if_none_match');
|
$subRequest->headers->remove('if_none_match');
|
||||||
|
|
||||||
|
// modify the X-Forwarded-For header if needed
|
||||||
|
$forwardedFor = $subRequest->headers->get('X-Forwarded-For');
|
||||||
|
if ($forwardedFor) {
|
||||||
|
$subRequest->headers->set('X-Forwarded-For', $forwardedFor.', '.$subRequest->server->get('REMOTE_ADDR'));
|
||||||
|
} else {
|
||||||
|
$subRequest->headers->set('X-Forwarded-For', $subRequest->server->get('REMOTE_ADDR'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix the client IP address by setting it to 127.0.0.1 as HttpCache
|
||||||
|
// is always called from the same process as the backend.
|
||||||
|
$subRequest->server->set('REMOTE_ADDR', '127.0.0.1');
|
||||||
|
|
||||||
$response = $this->forward($subRequest, $catch);
|
$response = $this->forward($subRequest, $catch);
|
||||||
|
|
||||||
if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) {
|
if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) {
|
||||||
|
@ -1034,4 +1034,36 @@ class HttpCacheTest extends HttpCacheTestCase
|
|||||||
$this->assertEquals('Hello World!', $this->response->getContent());
|
$this->assertEquals('Hello World!', $this->response->getContent());
|
||||||
$this->assertEquals(12, $this->response->headers->get('Content-Length'));
|
$this->assertEquals(12, $this->response->headers->get('Content-Length'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testClientIpIsAlwaysLocalhostForForwardedRequests()
|
||||||
|
{
|
||||||
|
$this->setNextResponse();
|
||||||
|
$this->request('GET', '/', array('REMOTE_ADDR' => '10.0.0.1'));
|
||||||
|
|
||||||
|
$this->assertEquals('127.0.0.1', $this->kernel->getBackendRequest()->server->get('REMOTE_ADDR'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getXForwardedForData
|
||||||
|
*/
|
||||||
|
public function testXForwarderForHeaderForForwardedRequests($xForwardedFor, $expected)
|
||||||
|
{
|
||||||
|
$this->setNextResponse();
|
||||||
|
$server = array('REMOTE_ADDR' => '10.0.0.1');
|
||||||
|
if (false !== $xForwardedFor) {
|
||||||
|
$server['HTTP_X_FORWARDED_FOR'] = $xForwardedFor;
|
||||||
|
}
|
||||||
|
$this->request('GET', '/', $server);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $this->kernel->getBackendRequest()->headers->get('X-Forwarded-For'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getXForwardedForData()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array(false, '10.0.0.1'),
|
||||||
|
array('10.0.0.2', '10.0.0.2, 10.0.0.1'),
|
||||||
|
array('10.0.0.2, 10.0.0.3', '10.0.0.2, 10.0.0.3, 10.0.0.1'),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ class TestHttpKernel extends HttpKernel implements ControllerResolverInterface
|
|||||||
protected $called;
|
protected $called;
|
||||||
protected $customizer;
|
protected $customizer;
|
||||||
protected $catch;
|
protected $catch;
|
||||||
|
protected $backendRequest;
|
||||||
|
|
||||||
public function __construct($body, $status, $headers, \Closure $customizer = null)
|
public function __construct($body, $status, $headers, \Closure $customizer = null)
|
||||||
{
|
{
|
||||||
@ -39,9 +40,15 @@ class TestHttpKernel extends HttpKernel implements ControllerResolverInterface
|
|||||||
parent::__construct(new EventDispatcher(), $this);
|
parent::__construct(new EventDispatcher(), $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getBackendRequest()
|
||||||
|
{
|
||||||
|
return $this->backendRequest;
|
||||||
|
}
|
||||||
|
|
||||||
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = false)
|
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = false)
|
||||||
{
|
{
|
||||||
$this->catch = $catch;
|
$this->catch = $catch;
|
||||||
|
$this->backendRequest = $request;
|
||||||
|
|
||||||
return parent::handle($request, $type, $catch);
|
return parent::handle($request, $type, $catch);
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ class TestMultipleHttpKernel extends HttpKernel implements ControllerResolverInt
|
|||||||
protected $headers;
|
protected $headers;
|
||||||
protected $catch;
|
protected $catch;
|
||||||
protected $call;
|
protected $call;
|
||||||
|
protected $backendRequest;
|
||||||
|
|
||||||
public function __construct($responses)
|
public function __construct($responses)
|
||||||
{
|
{
|
||||||
@ -42,8 +43,15 @@ class TestMultipleHttpKernel extends HttpKernel implements ControllerResolverInt
|
|||||||
parent::__construct(new EventDispatcher(), $this);
|
parent::__construct(new EventDispatcher(), $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getBackendRequest()
|
||||||
|
{
|
||||||
|
return $this->backendRequest;
|
||||||
|
}
|
||||||
|
|
||||||
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = false)
|
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = false)
|
||||||
{
|
{
|
||||||
|
$this->backendRequest = $request;
|
||||||
|
|
||||||
return parent::handle($request, $type, $catch);
|
return parent::handle($request, $type, $catch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,14 +12,15 @@
|
|||||||
namespace Symfony\Component\Routing\Tests\Fixtures;
|
namespace Symfony\Component\Routing\Tests\Fixtures;
|
||||||
|
|
||||||
use Symfony\Component\Routing\Loader\XmlFileLoader;
|
use Symfony\Component\Routing\Loader\XmlFileLoader;
|
||||||
|
use Symfony\Component\Config\Util\XmlUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* XmlFileLoader with schema validation turned off
|
* XmlFileLoader with schema validation turned off
|
||||||
*/
|
*/
|
||||||
class CustomXmlFileLoader extends XmlFileLoader
|
class CustomXmlFileLoader extends XmlFileLoader
|
||||||
{
|
{
|
||||||
protected function validate(\DOMDocument $dom)
|
protected function loadFile($file)
|
||||||
{
|
{
|
||||||
return true;
|
return XmlUtils::loadFile($file, function() { return true; });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
blog_show:
|
blog_show:
|
||||||
resource: validpattern.yml
|
resource: validpattern.yml
|
||||||
pattern: /test
|
path: /test
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
blog_show:
|
blog_show:
|
||||||
pattern: /blog/{slug}
|
path: /blog/{slug}
|
||||||
type: custom
|
type: custom
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
"#$péß^a|":
|
"#$péß^a|":
|
||||||
pattern: "true"
|
path: "true"
|
||||||
|
@ -6,9 +6,18 @@ $collection = new RouteCollection();
|
|||||||
$collection->add('blog_show', new Route(
|
$collection->add('blog_show', new Route(
|
||||||
'/blog/{slug}',
|
'/blog/{slug}',
|
||||||
array('_controller' => 'MyBlogBundle:Blog:show'),
|
array('_controller' => 'MyBlogBundle:Blog:show'),
|
||||||
array('_method' => 'GET', 'locale' => '\w+'),
|
array('_method' => 'GET', 'locale' => '\w+', '_scheme' => 'https'),
|
||||||
array('compiler_class' => 'RouteCompiler'),
|
array('compiler_class' => 'RouteCompiler'),
|
||||||
'{locale}.example.com'
|
'{locale}.example.com'
|
||||||
));
|
));
|
||||||
|
$collection->add('blog_show_legacy', new Route(
|
||||||
|
'/blog/{slug}',
|
||||||
|
array('_controller' => 'MyBlogBundle:Blog:show'),
|
||||||
|
array('locale' => '\w+'),
|
||||||
|
array('compiler_class' => 'RouteCompiler'),
|
||||||
|
'{locale}.example.com',
|
||||||
|
array('https'),
|
||||||
|
array('GET')
|
||||||
|
));
|
||||||
|
|
||||||
return $collection;
|
return $collection;
|
||||||
|
@ -4,9 +4,16 @@
|
|||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
|
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
|
||||||
|
|
||||||
<route id="blog_show" pattern="/blog/{slug}" host="{locale}.example.com">
|
<route id="blog_show" path="/blog/{slug}" host="{locale}.example.com" methods="GET" schemes="https">
|
||||||
|
<default key="_controller">MyBundle:Blog:show</default>
|
||||||
|
<requirement key="locale">\w+</requirement>
|
||||||
|
<option key="compiler_class">RouteCompiler</option>
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<route id="blog_show_legacy" pattern="/blog/{slug}" host="{locale}.example.com">
|
||||||
<default key="_controller">MyBundle:Blog:show</default>
|
<default key="_controller">MyBundle:Blog:show</default>
|
||||||
<requirement key="_method">GET</requirement>
|
<requirement key="_method">GET</requirement>
|
||||||
|
<requirement key="_scheme">https</requirement>
|
||||||
<requirement key="locale">\w+</requirement>
|
<requirement key="locale">\w+</requirement>
|
||||||
<option key="compiler_class">RouteCompiler</option>
|
<option key="compiler_class">RouteCompiler</option>
|
||||||
</route>
|
</route>
|
||||||
|
@ -1,7 +1,17 @@
|
|||||||
blog_show:
|
blog_show:
|
||||||
pattern: /blog/{slug}
|
path: /blog/{slug}
|
||||||
defaults: { _controller: MyBlogBundle:Blog:show }
|
defaults: { _controller: MyBlogBundle:Blog:show }
|
||||||
host : "{locale}.example.com"
|
host: "{locale}.example.com"
|
||||||
requirements: { '_method': 'GET', 'locale': '\w+' }
|
requirements: { 'locale': '\w+' }
|
||||||
|
methods: ['GET']
|
||||||
|
schemes: ['https']
|
||||||
|
options:
|
||||||
|
compiler_class: RouteCompiler
|
||||||
|
|
||||||
|
blog_show_legacy:
|
||||||
|
pattern: /blog/{slug}
|
||||||
|
defaults: { _controller: MyBlogBundle:Blog:show }
|
||||||
|
host: "{locale}.example.com"
|
||||||
|
requirements: { '_method': 'GET', 'locale': '\w+', _scheme: 'https' }
|
||||||
options:
|
options:
|
||||||
compiler_class: RouteCompiler
|
compiler_class: RouteCompiler
|
||||||
|
@ -40,13 +40,16 @@ class PhpFileLoaderTest extends \PHPUnit_Framework_TestCase
|
|||||||
$routeCollection = $loader->load('validpattern.php');
|
$routeCollection = $loader->load('validpattern.php');
|
||||||
$routes = $routeCollection->all();
|
$routes = $routeCollection->all();
|
||||||
|
|
||||||
$this->assertEquals(1, count($routes), 'One route is loaded');
|
$this->assertCount(2, $routes, 'Two routes are loaded');
|
||||||
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
|
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
|
||||||
$route = $routes['blog_show'];
|
|
||||||
$this->assertEquals('/blog/{slug}', $route->getPath());
|
foreach ($routes as $route) {
|
||||||
$this->assertEquals('MyBlogBundle:Blog:show', $route->getDefault('_controller'));
|
$this->assertEquals('/blog/{slug}', $route->getPath());
|
||||||
$this->assertEquals('GET', $route->getRequirement('_method'));
|
$this->assertEquals('MyBlogBundle:Blog:show', $route->getDefault('_controller'));
|
||||||
$this->assertEquals('{locale}.example.com', $route->getHost());
|
$this->assertEquals('GET', $route->getRequirement('_method'));
|
||||||
$this->assertEquals('RouteCompiler', $route->getOption('compiler_class'));
|
$this->assertEquals('https', $route->getRequirement('_scheme'));
|
||||||
|
$this->assertEquals('{locale}.example.com', $route->getHost());
|
||||||
|
$this->assertEquals('RouteCompiler', $route->getOption('compiler_class'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,12 +41,13 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
|||||||
$routeCollection = $loader->load('validpattern.xml');
|
$routeCollection = $loader->load('validpattern.xml');
|
||||||
$routes = $routeCollection->all();
|
$routes = $routeCollection->all();
|
||||||
|
|
||||||
$this->assertEquals(1, count($routes), 'One route is loaded');
|
$this->assertCount(2, $routes, 'Two routes are loaded');
|
||||||
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
|
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
|
||||||
$route = $routes['blog_show'];
|
$route = $routes['blog_show'];
|
||||||
$this->assertEquals('/blog/{slug}', $route->getPath());
|
$this->assertEquals('/blog/{slug}', $route->getPath());
|
||||||
$this->assertEquals('MyBundle:Blog:show', $route->getDefault('_controller'));
|
$this->assertEquals('MyBundle:Blog:show', $route->getDefault('_controller'));
|
||||||
$this->assertEquals('GET', $route->getRequirement('_method'));
|
$this->assertEquals('GET', $route->getRequirement('_method'));
|
||||||
|
$this->assertEquals('https', $route->getRequirement('_scheme'));
|
||||||
$this->assertEquals('\w+', $route->getRequirement('locale'));
|
$this->assertEquals('\w+', $route->getRequirement('locale'));
|
||||||
$this->assertEquals('{locale}.example.com', $route->getHost());
|
$this->assertEquals('{locale}.example.com', $route->getHost());
|
||||||
$this->assertEquals('RouteCompiler', $route->getOption('compiler_class'));
|
$this->assertEquals('RouteCompiler', $route->getOption('compiler_class'));
|
||||||
@ -57,7 +58,8 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
|||||||
$loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
|
$loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
|
||||||
$routeCollection = $loader->load('namespaceprefix.xml');
|
$routeCollection = $loader->load('namespaceprefix.xml');
|
||||||
|
|
||||||
$this->assertCount(1, $routeCollection, 'One route is loaded');
|
$this->assertCount(1, $routeCollection->all(), 'One route is loaded');
|
||||||
|
|
||||||
$route = $routeCollection->get('blog_show');
|
$route = $routeCollection->get('blog_show');
|
||||||
$this->assertEquals('/blog/{slug}', $route->getPath());
|
$this->assertEquals('/blog/{slug}', $route->getPath());
|
||||||
$this->assertEquals('MyBundle:Blog:show', $route->getDefault('_controller'));
|
$this->assertEquals('MyBundle:Blog:show', $route->getDefault('_controller'));
|
||||||
@ -73,14 +75,17 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
|||||||
$routeCollection = $loader->load('validresource.xml');
|
$routeCollection = $loader->load('validresource.xml');
|
||||||
$routes = $routeCollection->all();
|
$routes = $routeCollection->all();
|
||||||
|
|
||||||
$this->assertEquals(1, count($routes), 'One route is loaded');
|
$this->assertCount(2, $routes, 'Two routes are loaded');
|
||||||
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
|
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
|
||||||
$this->assertEquals('/{foo}/blog/{slug}', $routes['blog_show']->getPath());
|
|
||||||
$this->assertEquals('MyBundle:Blog:show', $routes['blog_show']->getDefault('_controller'));
|
foreach ($routes as $route) {
|
||||||
$this->assertEquals('123', $routes['blog_show']->getDefault('foo'));
|
$this->assertEquals('/{foo}/blog/{slug}', $routes['blog_show']->getPath());
|
||||||
$this->assertEquals('\d+', $routes['blog_show']->getRequirement('foo'));
|
$this->assertEquals('MyBundle:Blog:show', $routes['blog_show']->getDefault('_controller'));
|
||||||
$this->assertEquals('bar', $routes['blog_show']->getOption('foo'));
|
$this->assertEquals('123', $routes['blog_show']->getDefault('foo'));
|
||||||
$this->assertEquals('{locale}.example.com', $routes['blog_show']->getHost());
|
$this->assertEquals('\d+', $routes['blog_show']->getRequirement('foo'));
|
||||||
|
$this->assertEquals('bar', $routes['blog_show']->getOption('foo'));
|
||||||
|
$this->assertEquals('{locale}.example.com', $routes['blog_show']->getHost());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,15 +79,18 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
|||||||
$routeCollection = $loader->load('validpattern.yml');
|
$routeCollection = $loader->load('validpattern.yml');
|
||||||
$routes = $routeCollection->all();
|
$routes = $routeCollection->all();
|
||||||
|
|
||||||
$this->assertEquals(1, count($routes), 'One route is loaded');
|
$this->assertCount(2, $routes, 'Two routes are loaded');
|
||||||
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
|
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
|
||||||
$route = $routes['blog_show'];
|
|
||||||
$this->assertEquals('/blog/{slug}', $route->getPath());
|
foreach ($routes as $route) {
|
||||||
$this->assertEquals('MyBlogBundle:Blog:show', $route->getDefault('_controller'));
|
$this->assertEquals('/blog/{slug}', $route->getPath());
|
||||||
$this->assertEquals('GET', $route->getRequirement('_method'));
|
$this->assertEquals('MyBlogBundle:Blog:show', $route->getDefault('_controller'));
|
||||||
$this->assertEquals('\w+', $route->getRequirement('locale'));
|
$this->assertEquals('GET', $route->getRequirement('_method'));
|
||||||
$this->assertEquals('{locale}.example.com', $route->getHost());
|
$this->assertEquals('https', $route->getRequirement('_scheme'));
|
||||||
$this->assertEquals('RouteCompiler', $route->getOption('compiler_class'));
|
$this->assertEquals('\w+', $route->getRequirement('locale'));
|
||||||
|
$this->assertEquals('{locale}.example.com', $route->getHost());
|
||||||
|
$this->assertEquals('RouteCompiler', $route->getOption('compiler_class'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadWithResource()
|
public function testLoadWithResource()
|
||||||
@ -96,7 +99,7 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
|||||||
$routeCollection = $loader->load('validresource.yml');
|
$routeCollection = $loader->load('validresource.yml');
|
||||||
$routes = $routeCollection->all();
|
$routes = $routeCollection->all();
|
||||||
|
|
||||||
$this->assertEquals(1, count($routes), 'One route is loaded');
|
$this->assertCount(2, $routes, 'Two routes are loaded');
|
||||||
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
|
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes);
|
||||||
$this->assertEquals('/{foo}/blog/{slug}', $routes['blog_show']->getPath());
|
$this->assertEquals('/{foo}/blog/{slug}', $routes['blog_show']->getPath());
|
||||||
$this->assertEquals('MyBlogBundle:Blog:show', $routes['blog_show']->getDefault('_controller'));
|
$this->assertEquals('MyBlogBundle:Blog:show', $routes['blog_show']->getDefault('_controller'));
|
||||||
|
@ -117,14 +117,16 @@ class ContextListener implements ListenerInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$request = $event->getRequest();
|
$request = $event->getRequest();
|
||||||
$session = $request->hasPreviousSession() ? $request->getSession() : null;
|
$session = $request->getSession();
|
||||||
|
|
||||||
if (null === $session) {
|
if (null === $session) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((null === $token = $this->context->getToken()) || ($token instanceof AnonymousToken)) {
|
if ((null === $token = $this->context->getToken()) || ($token instanceof AnonymousToken)) {
|
||||||
$session->remove('_security_'.$this->contextKey);
|
if ($request->hasPreviousSession()) {
|
||||||
|
$session->remove('_security_'.$this->contextKey);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$session->set('_security_'.$this->contextKey, serialize($token));
|
$session->set('_security_'.$this->contextKey, serialize($token));
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,25 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
$listener = new ContextListener($this->securityContext, array(), 'session');
|
$listener = new ContextListener($this->securityContext, array(), 'session');
|
||||||
$listener->onKernelResponse($event);
|
$listener->onKernelResponse($event);
|
||||||
|
|
||||||
|
$this->assertTrue($session->isStarted());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testOnKernelResponseWithoutSessionNorToken()
|
||||||
|
{
|
||||||
|
$request = new Request();
|
||||||
|
$session = new Session(new MockArraySessionStorage());
|
||||||
|
$request->setSession($session);
|
||||||
|
|
||||||
|
$event = new FilterResponseEvent(
|
||||||
|
$this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'),
|
||||||
|
$request,
|
||||||
|
HttpKernelInterface::MASTER_REQUEST,
|
||||||
|
new Response()
|
||||||
|
);
|
||||||
|
|
||||||
|
$listener = new ContextListener($this->securityContext, array(), 'session');
|
||||||
|
$listener->onKernelResponse($event);
|
||||||
|
|
||||||
$this->assertFalse($session->isStarted());
|
$this->assertFalse($session->isStarted());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,6 +301,14 @@ class ClassMetadata extends ElementMetadata implements MetadataInterface, ClassB
|
|||||||
return $this->members[$property];
|
return $this->members[$property];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function hasPropertyMetadata($property)
|
||||||
|
{
|
||||||
|
return array_key_exists($property, $this->members);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -18,6 +18,15 @@ namespace Symfony\Component\Validator;
|
|||||||
*/
|
*/
|
||||||
interface PropertyMetadataContainerInterface
|
interface PropertyMetadataContainerInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Check if there's any metadata attached to the given named property.
|
||||||
|
*
|
||||||
|
* @param string $property The property name.
|
||||||
|
*
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
public function hasPropertyMetadata($property);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all metadata instances for the given named property.
|
* Returns all metadata instances for the given named property.
|
||||||
*
|
*
|
||||||
|
@ -187,6 +187,10 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
$result = $this->validator->validateProperty($entity, 'firstName');
|
$result = $this->validator->validateProperty($entity, 'firstName');
|
||||||
|
|
||||||
$this->assertCount(1, $result);
|
$this->assertCount(1, $result);
|
||||||
|
|
||||||
|
$result = $this->validator->validateProperty($entity, 'lastName');
|
||||||
|
|
||||||
|
$this->assertCount(0, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidatePropertyValue()
|
public function testValidatePropertyValue()
|
||||||
|
@ -112,6 +112,10 @@ class Validator implements ValidatorInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->resolveGroups($groups) as $group) {
|
foreach ($this->resolveGroups($groups) as $group) {
|
||||||
|
if (!$metadata->hasPropertyMetadata($property)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($metadata->getPropertyMetadata($property) as $propMeta) {
|
foreach ($metadata->getPropertyMetadata($property) as $propMeta) {
|
||||||
$propMeta->accept($visitor, $propMeta->getPropertyValue($containingValue), $group, $property);
|
$propMeta->accept($visitor, $propMeta->getPropertyValue($containingValue), $group, $property);
|
||||||
}
|
}
|
||||||
@ -139,6 +143,10 @@ class Validator implements ValidatorInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->resolveGroups($groups) as $group) {
|
foreach ($this->resolveGroups($groups) as $group) {
|
||||||
|
if (!$metadata->hasPropertyMetadata($property)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($metadata->getPropertyMetadata($property) as $propMeta) {
|
foreach ($metadata->getPropertyMetadata($property) as $propMeta) {
|
||||||
$propMeta->accept($visitor, $value, $group, $property);
|
$propMeta->accept($visitor, $value, $group, $property);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user