diff --git a/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php b/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php index 1cbdeab18e..5b963261fe 100644 --- a/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php +++ b/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php @@ -52,7 +52,7 @@ class InlineFragmentRenderer extends RoutableFragmentRenderer $reference = null; if ($uri instanceof ControllerReference) { $reference = $uri; - $uri = $this->generateFragmentUri($uri, $request); + $uri = $this->generateFragmentUri($uri, $request, false); } $subRequest = $this->createSubRequest($uri, $request); diff --git a/src/Symfony/Component/HttpKernel/Fragment/RoutableFragmentRenderer.php b/src/Symfony/Component/HttpKernel/Fragment/RoutableFragmentRenderer.php index 879a0bb7ac..1137ce59f6 100644 --- a/src/Symfony/Component/HttpKernel/Fragment/RoutableFragmentRenderer.php +++ b/src/Symfony/Component/HttpKernel/Fragment/RoutableFragmentRenderer.php @@ -40,12 +40,17 @@ abstract class RoutableFragmentRenderer implements FragmentRendererInterface * Generates a fragment URI for a given controller. * * @param ControllerReference $reference A ControllerReference instance - * @param Request $request A Request instance + * @param Request $request A Request instance + * @param Boolean $strict Whether to allow non-scalar attributes or not * * @return string A fragment URI */ - protected function generateFragmentUri(ControllerReference $reference, Request $request) + protected function generateFragmentUri(ControllerReference $reference, Request $request, $strict = true) { + if ($strict) { + $this->checkNonScalar($reference->attributes); + } + if (!isset($reference->attributes['_format'])) { $reference->attributes['_format'] = $request->getRequestFormat(); } @@ -56,4 +61,17 @@ abstract class RoutableFragmentRenderer implements FragmentRendererInterface return $request->getUriForPath($this->fragmentPath.'?'.http_build_query($reference->query, '', '&')); } + + private function checkNonScalar($values) + { + foreach ($values as $value) { + if (is_array($value)) { + $this->checkNonScalar($value); + } + + if (!is_scalar($value)) { + throw new \LogicException('Controller attributes cannot contain non-scalar values.'); + } + } + } } diff --git a/src/Symfony/Component/HttpKernel/Tests/Fragment/RoutableFragmentRendererTest.php b/src/Symfony/Component/HttpKernel/Tests/Fragment/RoutableFragmentRendererTest.php index 2106f9de75..b780a162d1 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Fragment/RoutableFragmentRendererTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Fragment/RoutableFragmentRendererTest.php @@ -13,7 +13,6 @@ namespace Symfony\Component\HttpKernel\Fragment\Tests\FragmentRenderer; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Controller\ControllerReference; -use Symfony\Component\HttpKernel\Fragment\RoutableFragmentRenderer; class RoutableFragmentRendererTest extends \PHPUnit_Framework_TestCase { @@ -22,7 +21,7 @@ class RoutableFragmentRendererTest extends \PHPUnit_Framework_TestCase */ public function testGenerateFragmentUri($uri, $controller) { - $this->assertEquals($uri, $this->getRenderer()->doGenerateFragmentUri($controller, Request::create('/'))); + $this->assertEquals($uri, $this->callGenerateFragmentUriMethod($controller, Request::create('/'))); } public function getGenerateFragmentUriData() @@ -33,6 +32,7 @@ class RoutableFragmentRendererTest extends \PHPUnit_Framework_TestCase array('http://localhost/_fragment?_path=foo%3Dfoo%26_format%3Djson%26_controller%3Dcontroller', new ControllerReference('controller', array('foo' => 'foo', '_format' => 'json'), array())), array('http://localhost/_fragment?bar=bar&_path=foo%3Dfoo%26_format%3Dhtml%26_controller%3Dcontroller', new ControllerReference('controller', array('foo' => 'foo'), array('bar' => 'bar'))), array('http://localhost/_fragment?foo=foo&_path=_format%3Dhtml%26_controller%3Dcontroller', new ControllerReference('controller', array(), array('foo' => 'foo'))), + array('http://localhost/_fragment?_path=foo%255B0%255D%3Dfoo%26foo%255B1%255D%3Dbar%26_format%3Dhtml%26_controller%3Dcontroller', new ControllerReference('controller', array('foo' => array('foo', 'bar')), array())), ); } @@ -42,22 +42,36 @@ class RoutableFragmentRendererTest extends \PHPUnit_Framework_TestCase $request->attributes->set('_format', 'json'); $controller = new ControllerReference('controller', array(), array()); - $this->assertEquals('http://localhost/_fragment?_path=_format%3Djson%26_controller%3Dcontroller', $this->getRenderer()->doGenerateFragmentUri($controller, $request)); + $this->assertEquals('http://localhost/_fragment?_path=_format%3Djson%26_controller%3Dcontroller', $this->callGenerateFragmentUriMethod($controller, $request)); } - private function getRenderer() + /** + * @expectedException LogicException + */ + public function testGenerateFragmentUriWithObject() { - return new Renderer(); + $controller = new ControllerReference('controller', array('foo' => new Foo(), 'bar' => 'bar'), array()); + + $this->callGenerateFragmentUriMethod($controller, Request::create('/')); + } + + private function callGenerateFragmentUriMethod(ControllerReference $reference, Request $request) + { + $renderer = $this->getMockForAbstractClass('Symfony\Component\HttpKernel\Fragment\RoutableFragmentRenderer'); + $r = new \ReflectionObject($renderer); + $m = $r->getMethod('generateFragmentUri'); + $m->setAccessible(true); + + return $m->invoke($renderer, $reference, $request); } } -class Renderer extends RoutableFragmentRenderer +class Foo { - public function render($uri, Request $request, array $options = array()) {} - public function getName() {} + public $foo; - public function doGenerateFragmentUri(ControllerReference $reference, Request $request) + public function getFoo() { - return parent::generateFragmentUri($reference, $request); + return $this->foo; } }