Commit 21713807 authored by catch's avatar catch

Issue #2103145 by tim.plunkett, damiankloip, neclimdul: Fixed...

Issue #2103145 by tim.plunkett, damiankloip, neclimdul: Fixed ParameterConverter mangles raw values.
parent 8a5c9202
......@@ -156,7 +156,14 @@ public function enhance(array $defaults, Request $request) {
// variables in the route path pattern.
$route = $defaults[RouteObjectInterface::ROUTE_OBJECT];
$variables = array_flip($route->compile()->getVariables());
$defaults['_raw_variables'] = new ParameterBag(array_intersect_key($defaults, $variables));
// Foreach will copy the values from the array it iterates. Even if they
// are references, use it to break them. This avoids any scenarios where raw
// variables also get replaced with converted values.
$raw_variables = array();
foreach (array_intersect_key($defaults, $variables) as $key => $value) {
$raw_variables[$key] = $value;
}
$defaults['_raw_variables'] = new ParameterBag($raw_variables);
// Skip this enhancer if there are no parameter definitions.
if (!$parameters = $route->getOption('parameters')) {
......
......@@ -9,7 +9,10 @@
use Drupal\Core\ParamConverter\ParamConverterManager;
use Drupal\Tests\UnitTestCase;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Route;
/**
* Tests the typed data resolver manager.
......@@ -142,4 +145,49 @@ public function providerTestGetConverter() {
);
}
/**
* Tests the enhance method.
*
* @see \Drupal\Core\ParamConverter\ParamConverterManager::enhance().
*/
public function testEnhance() {
// Create a mock route using a mock parameter converter.
$converter = $this->getMock('Drupal\Core\ParamConverter\ParamConverterInterface');
$this->manager->addConverter('test_convert');
$this->container->set('test_convert', $converter);
$route = new Route('/test/{id}');
$parameters = array();
$parameters['id'] = array(
'converter' => 'test_convert'
);
$route->setOption('parameters', $parameters);
$defaults = array();
$defaults[RouteObjectInterface::ROUTE_OBJECT] = $route;
$defaults['id'] = 1;
$defaults['_entity'] = &$defaults['id'];
$request = new Request();
$entity = $this->getMockBuilder('\Drupal\user\Entity\User')
->disableOriginalConstructor()
->getMock();
$converter->expects($this->once())
->method('convert')
->with($this->equalTo(1))
->will($this->returnValue($entity));
$defaults = $this->manager->enhance($defaults, $request);
// The value of 1 should be upcast to the User object for UID 1.
$this->assertSame($entity, $defaults['id']);
// The parameter for the user ID should be stored in the raw variables.
$this->assertTrue($defaults['_raw_variables']->has('id'));
// The raw non-upcasted value for the user should be the UID.
$this->assertEquals(1, $defaults['_raw_variables']->get('id'));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment