From 067b993cf1b109ad872b827f23fefc9f53cef4c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Gonz=C3=A1lez?= Date: Fri, 9 Mar 2018 09:55:19 +0000 Subject: [PATCH 1/2] refs #multiple-path-params fix path parser to allow multiple path params --- src/Parser/Path.php | 18 +++++++++++-- tests/unit/src/Parser/PathTest.php | 42 ++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/Parser/Path.php b/src/Parser/Path.php index a3bd607..055eb95 100644 --- a/src/Parser/Path.php +++ b/src/Parser/Path.php @@ -36,17 +36,31 @@ public function __construct(Request $request, array $parameter, $route) public function getValue() { $path = $this->request->getUri()->getPath(); + preg_match_all("/\{(.*?)\}/", $this->route, $variableMatchersInRoute); $key = str_replace( '{' . $this->parameter['name'] . '}', '(?P<' . $this->parameter['name'] . '>[^/]+)', $this->route ); - $key = "@{$key}@"; + // inject other path variables too into the final regexp key to be able to match it + if (!empty($variableMatchersInRoute[1])) { + foreach ($variableMatchersInRoute[1] as $variableMatcherInRoute) { + $key = str_replace( + '{' . $variableMatcherInRoute . '}', + '(?P<' . $variableMatcherInRoute . '>[^/]+)', + $key + ); + } + } + + $key = "@{$key}@"; if (!preg_match($key, $path, $pathMatches)) { return; } - + if (!isset($pathMatches[$this->parameter['name']])) { + return null; + } $value = $pathMatches[$this->parameter['name']]; if ($this->parameter['type'] === 'array') { $value = $this->explodeValue($value, $this->parameter); diff --git a/tests/unit/src/Parser/PathTest.php b/tests/unit/src/Parser/PathTest.php index b058485..abb9ace 100644 --- a/tests/unit/src/Parser/PathTest.php +++ b/tests/unit/src/Parser/PathTest.php @@ -181,4 +181,46 @@ public function testGetValueReturnsMultipleValuesIfMatched() $this->assertEquals($expectedValue, $result); } + + public function testGetValueReturnsSingleValueIfMatchedMultiplePaths() + { + $expectedValue = '1234'; + + $mockUri = $this->createMock(UriInterface::class); + $mockUri->method('getPath') + ->willReturn("/path/{$expectedValue}/another/one"); + + $mockRequest = $this->createMock(RequestInterface::class); + $mockRequest->method('getUri') + ->willReturn($mockUri); + + $mockParameter = [ + 'name' => 'id', + 'type' => 'string', + ]; + $mockRoute = '/path/{id}/another/{one}'; + + $reflectedPathParser = new ReflectionClass(Path::class); + $reflectedRequest = $reflectedPathParser->getProperty('request'); + $reflectedRequest->setAccessible(true); + $reflectedParameter = $reflectedPathParser->getProperty('parameter'); + $reflectedParameter->setAccessible(true); + $reflectedRoute = $reflectedPathParser->getProperty('route'); + $reflectedRoute->setAccessible(true); + + $pathParser = $this->getMockBuilder(Path::class) + ->disableOriginalConstructor() + ->setMethods([ 'explodeValue' ]) + ->getMock(); + $pathParser->expects($this->never()) + ->method('explodeValue'); + + $reflectedRequest->setValue($pathParser, $mockRequest); + $reflectedParameter->setValue($pathParser, $mockParameter); + $reflectedRoute->setValue($pathParser, $mockRoute); + + $result = $pathParser->getValue(); + + $this->assertEquals($expectedValue, $result); + } } From a0316b5519d21c81b98113e464ec887246ae47a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Gonz=C3=A1lez?= Date: Fri, 9 Mar 2018 09:55:20 +0000 Subject: [PATCH 2/2] fix cs --- src/Parser/Path.php | 1 - tests/unit/src/Parser/PathTest.php | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Parser/Path.php b/src/Parser/Path.php index 055eb95..995a3fd 100644 --- a/src/Parser/Path.php +++ b/src/Parser/Path.php @@ -6,7 +6,6 @@ class Path implements ParserInterface { - use ExplodeTrait; /** @var Request */ diff --git a/tests/unit/src/Parser/PathTest.php b/tests/unit/src/Parser/PathTest.php index abb9ace..776b5b9 100644 --- a/tests/unit/src/Parser/PathTest.php +++ b/tests/unit/src/Parser/PathTest.php @@ -9,7 +9,6 @@ class PathTest extends PHPUnit_Framework_TestCase { - public function testImplementsParserInterface() { $mockRequest = $this->createMock(RequestInterface::class);