Skip to content

Commit dc3f7a9

Browse files
artursvondanicolas-grekas
authored andcommitted
[Routing] Add matched and default parameters to redirect responses
1 parent ac107ba commit dc3f7a9

File tree

6 files changed

+107
-63
lines changed

6 files changed

+107
-63
lines changed

src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -333,10 +333,34 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren
333333
}
334334
}
335335

336+
$retOffset = strlen($code);
337+
338+
// optimize parameters array
339+
if ($matches || $hostMatches) {
340+
$vars = array();
341+
if ($hostMatches) {
342+
$vars[] = '$hostMatches';
343+
}
344+
if ($matches) {
345+
$vars[] = '$matches';
346+
}
347+
$vars[] = "array('_route' => '$name')";
348+
349+
$code .= sprintf(
350+
" \$ret = \$this->mergeDefaults(array_replace(%s), %s);\n",
351+
implode(', ', $vars),
352+
str_replace("\n", '', var_export($route->getDefaults(), true))
353+
);
354+
} elseif ($route->getDefaults()) {
355+
$code .= sprintf(" \$ret = %s;\n", str_replace("\n", '', var_export(array_replace($route->getDefaults(), array('_route' => $name)), true)));
356+
} else {
357+
$code .= sprintf(" \$ret = array('_route' => '%s');\n", $name);
358+
}
359+
336360
if ($hasTrailingSlash) {
337361
$code .= <<<EOF
338362
if (substr(\$pathinfo, -1) !== '/') {
339-
return \$this->redirect(\$pathinfo.'/', '$name');
363+
return array_replace(\$ret, \$this->redirect(\$pathinfo.'/', '$name'));
340364
}
341365
342366
@@ -351,33 +375,17 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren
351375
$code .= <<<EOF
352376
\$requiredSchemes = $schemes;
353377
if (!isset(\$requiredSchemes[\$scheme])) {
354-
return \$this->redirect(\$pathinfo, '$name', key(\$requiredSchemes));
378+
return array_replace(\$ret, \$this->redirect(\$pathinfo, '$name', key(\$requiredSchemes)));
355379
}
356380
357381
358382
EOF;
359383
}
360384

361-
// optimize parameters array
362-
if ($matches || $hostMatches) {
363-
$vars = array();
364-
if ($hostMatches) {
365-
$vars[] = '$hostMatches';
366-
}
367-
if ($matches) {
368-
$vars[] = '$matches';
369-
}
370-
$vars[] = "array('_route' => '$name')";
371-
372-
$code .= sprintf(
373-
" return \$this->mergeDefaults(array_replace(%s), %s);\n",
374-
implode(', ', $vars),
375-
str_replace("\n", '', var_export($route->getDefaults(), true))
376-
);
377-
} elseif ($route->getDefaults()) {
378-
$code .= sprintf(" return %s;\n", str_replace("\n", '', var_export(array_replace($route->getDefaults(), array('_route' => $name)), true)));
385+
if ($hasTrailingSlash || $schemes) {
386+
$code .= " return \$ret;\n";
379387
} else {
380-
$code .= sprintf(" return array('_route' => '%s');\n", $name);
388+
$code = substr_replace($code, 'return', $retOffset + 12, 6);
381389
}
382390
$code .= " }\n";
383391

src/Symfony/Component/Routing/Matcher/UrlMatcher.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,9 @@ protected function matchCollection($pathinfo, RouteCollection $routes)
164164
$status = $this->handleRouteRequirements($pathinfo, $name, $route);
165165

166166
if (self::ROUTE_MATCH === $status[0]) {
167-
return $status[1];
167+
$attributes = array_replace($matches, $hostMatches, (array) $status[1]);
168+
169+
return $this->mergeDefaults($attributes, $route->getDefaults());
168170
}
169171

170172
if (self::REQUIREMENT_MISMATCH === $status[0]) {

src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,22 +87,24 @@ public function match($pathinfo)
8787

8888
// baz3
8989
if ('/test/baz3' === $trimmedPathinfo) {
90+
$ret = array('_route' => 'baz3');
9091
if (substr($pathinfo, -1) !== '/') {
91-
return $this->redirect($pathinfo.'/', 'baz3');
92+
return array_replace($ret, $this->redirect($pathinfo.'/', 'baz3'));
9293
}
9394

94-
return array('_route' => 'baz3');
95+
return $ret;
9596
}
9697

9798
}
9899

99100
// baz4
100101
if (preg_match('#^/test/(?P<foo>[^/]++)/?$#s', $pathinfo, $matches)) {
102+
$ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'baz4')), array ());
101103
if (substr($pathinfo, -1) !== '/') {
102-
return $this->redirect($pathinfo.'/', 'baz4');
104+
return array_replace($ret, $this->redirect($pathinfo.'/', 'baz4'));
103105
}
104106

105-
return $this->mergeDefaults(array_replace($matches, array('_route' => 'baz4')), array ());
107+
return $ret;
106108
}
107109

108110
// baz5
@@ -181,11 +183,12 @@ public function match($pathinfo)
181183

182184
// hey
183185
if ('/multi/hey' === $trimmedPathinfo) {
186+
$ret = array('_route' => 'hey');
184187
if (substr($pathinfo, -1) !== '/') {
185-
return $this->redirect($pathinfo.'/', 'hey');
188+
return array_replace($ret, $this->redirect($pathinfo.'/', 'hey'));
186189
}
187190

188-
return array('_route' => 'hey');
191+
return $ret;
189192
}
190193

191194
// overridden2
@@ -326,22 +329,24 @@ public function match($pathinfo)
326329

327330
// secure
328331
if ('/secure' === $pathinfo) {
332+
$ret = array('_route' => 'secure');
329333
$requiredSchemes = array ( 'https' => 0,);
330334
if (!isset($requiredSchemes[$scheme])) {
331-
return $this->redirect($pathinfo, 'secure', key($requiredSchemes));
335+
return array_replace($ret, $this->redirect($pathinfo, 'secure', key($requiredSchemes)));
332336
}
333337

334-
return array('_route' => 'secure');
338+
return $ret;
335339
}
336340

337341
// nonsecure
338342
if ('/nonsecure' === $pathinfo) {
343+
$ret = array('_route' => 'nonsecure');
339344
$requiredSchemes = array ( 'http' => 0,);
340345
if (!isset($requiredSchemes[$scheme])) {
341-
return $this->redirect($pathinfo, 'nonsecure', key($requiredSchemes));
346+
return array_replace($ret, $this->redirect($pathinfo, 'nonsecure', key($requiredSchemes)));
342347
}
343348

344-
return array('_route' => 'nonsecure');
349+
return $ret;
345350
}
346351

347352
throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();

src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher5.php

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -61,29 +61,32 @@ public function match($pathinfo)
6161
if (0 === strpos($pathinfo, '/a')) {
6262
// a_fourth
6363
if ('/a/44' === $trimmedPathinfo) {
64+
$ret = array('_route' => 'a_fourth');
6465
if (substr($pathinfo, -1) !== '/') {
65-
return $this->redirect($pathinfo.'/', 'a_fourth');
66+
return array_replace($ret, $this->redirect($pathinfo.'/', 'a_fourth'));
6667
}
6768

68-
return array('_route' => 'a_fourth');
69+
return $ret;
6970
}
7071

7172
// a_fifth
7273
if ('/a/55' === $trimmedPathinfo) {
74+
$ret = array('_route' => 'a_fifth');
7375
if (substr($pathinfo, -1) !== '/') {
74-
return $this->redirect($pathinfo.'/', 'a_fifth');
76+
return array_replace($ret, $this->redirect($pathinfo.'/', 'a_fifth'));
7577
}
7678

77-
return array('_route' => 'a_fifth');
79+
return $ret;
7880
}
7981

8082
// a_sixth
8183
if ('/a/66' === $trimmedPathinfo) {
84+
$ret = array('_route' => 'a_sixth');
8285
if (substr($pathinfo, -1) !== '/') {
83-
return $this->redirect($pathinfo.'/', 'a_sixth');
86+
return array_replace($ret, $this->redirect($pathinfo.'/', 'a_sixth'));
8487
}
8588

86-
return array('_route' => 'a_sixth');
89+
return $ret;
8790
}
8891

8992
}
@@ -96,59 +99,65 @@ public function match($pathinfo)
9699
if (0 === strpos($pathinfo, '/nested/group')) {
97100
// nested_a
98101
if ('/nested/group/a' === $trimmedPathinfo) {
102+
$ret = array('_route' => 'nested_a');
99103
if (substr($pathinfo, -1) !== '/') {
100-
return $this->redirect($pathinfo.'/', 'nested_a');
104+
return array_replace($ret, $this->redirect($pathinfo.'/', 'nested_a'));
101105
}
102106

103-
return array('_route' => 'nested_a');
107+
return $ret;
104108
}
105109

106110
// nested_b
107111
if ('/nested/group/b' === $trimmedPathinfo) {
112+
$ret = array('_route' => 'nested_b');
108113
if (substr($pathinfo, -1) !== '/') {
109-
return $this->redirect($pathinfo.'/', 'nested_b');
114+
return array_replace($ret, $this->redirect($pathinfo.'/', 'nested_b'));
110115
}
111116

112-
return array('_route' => 'nested_b');
117+
return $ret;
113118
}
114119

115120
// nested_c
116121
if ('/nested/group/c' === $trimmedPathinfo) {
122+
$ret = array('_route' => 'nested_c');
117123
if (substr($pathinfo, -1) !== '/') {
118-
return $this->redirect($pathinfo.'/', 'nested_c');
124+
return array_replace($ret, $this->redirect($pathinfo.'/', 'nested_c'));
119125
}
120126

121-
return array('_route' => 'nested_c');
127+
return $ret;
122128
}
123129

124130
}
125131

126132
elseif (0 === strpos($pathinfo, '/slashed/group')) {
127133
// slashed_a
128134
if ('/slashed/group' === $trimmedPathinfo) {
135+
$ret = array('_route' => 'slashed_a');
129136
if (substr($pathinfo, -1) !== '/') {
130-
return $this->redirect($pathinfo.'/', 'slashed_a');
137+
return array_replace($ret, $this->redirect($pathinfo.'/', 'slashed_a'));
131138
}
132139

133-
return array('_route' => 'slashed_a');
140+
return $ret;
134141
}
135142

136143
// slashed_b
137144
if ('/slashed/group/b' === $trimmedPathinfo) {
145+
$ret = array('_route' => 'slashed_b');
138146
if (substr($pathinfo, -1) !== '/') {
139-
return $this->redirect($pathinfo.'/', 'slashed_b');
147+
return array_replace($ret, $this->redirect($pathinfo.'/', 'slashed_b'));
140148
}
141149

142-
return array('_route' => 'slashed_b');
150+
return $ret;
143151
}
144152

145153
// slashed_c
146154
if ('/slashed/group/c' === $trimmedPathinfo) {
155+
$ret = array('_route' => 'slashed_c');
147156
if (substr($pathinfo, -1) !== '/') {
148-
return $this->redirect($pathinfo.'/', 'slashed_c');
157+
return array_replace($ret, $this->redirect($pathinfo.'/', 'slashed_c'));
149158
}
150159

151-
return array('_route' => 'slashed_c');
160+
return $ret;
152161
}
153162

154163
}

src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher7.php

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,12 @@ public function match($pathinfo)
3838
if (0 === strpos($pathinfo, '/trailing/simple')) {
3939
// simple_trailing_slash_no_methods
4040
if ('/trailing/simple/no-methods' === $trimmedPathinfo) {
41+
$ret = array('_route' => 'simple_trailing_slash_no_methods');
4142
if (substr($pathinfo, -1) !== '/') {
42-
return $this->redirect($pathinfo.'/', 'simple_trailing_slash_no_methods');
43+
return array_replace($ret, $this->redirect($pathinfo.'/', 'simple_trailing_slash_no_methods'));
4344
}
4445

45-
return array('_route' => 'simple_trailing_slash_no_methods');
46+
return $ret;
4647
}
4748

4849
// simple_trailing_slash_GET_method
@@ -52,11 +53,12 @@ public function match($pathinfo)
5253
goto not_simple_trailing_slash_GET_method;
5354
}
5455

56+
$ret = array('_route' => 'simple_trailing_slash_GET_method');
5557
if (substr($pathinfo, -1) !== '/') {
56-
return $this->redirect($pathinfo.'/', 'simple_trailing_slash_GET_method');
58+
return array_replace($ret, $this->redirect($pathinfo.'/', 'simple_trailing_slash_GET_method'));
5759
}
5860

59-
return array('_route' => 'simple_trailing_slash_GET_method');
61+
return $ret;
6062
}
6163
not_simple_trailing_slash_GET_method:
6264

@@ -67,11 +69,12 @@ public function match($pathinfo)
6769
goto not_simple_trailing_slash_HEAD_method;
6870
}
6971

72+
$ret = array('_route' => 'simple_trailing_slash_HEAD_method');
7073
if (substr($pathinfo, -1) !== '/') {
71-
return $this->redirect($pathinfo.'/', 'simple_trailing_slash_HEAD_method');
74+
return array_replace($ret, $this->redirect($pathinfo.'/', 'simple_trailing_slash_HEAD_method'));
7275
}
7376

74-
return array('_route' => 'simple_trailing_slash_HEAD_method');
77+
return $ret;
7578
}
7679
not_simple_trailing_slash_HEAD_method:
7780

@@ -91,11 +94,12 @@ public function match($pathinfo)
9194
elseif (0 === strpos($pathinfo, '/trailing/regex')) {
9295
// regex_trailing_slash_no_methods
9396
if (0 === strpos($pathinfo, '/trailing/regex/no-methods') && preg_match('#^/trailing/regex/no\\-methods/(?P<param>[^/]++)/?$#s', $pathinfo, $matches)) {
97+
$ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_no_methods')), array ());
9498
if (substr($pathinfo, -1) !== '/') {
95-
return $this->redirect($pathinfo.'/', 'regex_trailing_slash_no_methods');
99+
return array_replace($ret, $this->redirect($pathinfo.'/', 'regex_trailing_slash_no_methods'));
96100
}
97101

98-
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_no_methods')), array ());
102+
return $ret;
99103
}
100104

101105
// regex_trailing_slash_GET_method
@@ -105,11 +109,12 @@ public function match($pathinfo)
105109
goto not_regex_trailing_slash_GET_method;
106110
}
107111

112+
$ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_GET_method')), array ());
108113
if (substr($pathinfo, -1) !== '/') {
109-
return $this->redirect($pathinfo.'/', 'regex_trailing_slash_GET_method');
114+
return array_replace($ret, $this->redirect($pathinfo.'/', 'regex_trailing_slash_GET_method'));
110115
}
111116

112-
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_GET_method')), array ());
117+
return $ret;
113118
}
114119
not_regex_trailing_slash_GET_method:
115120

@@ -120,11 +125,12 @@ public function match($pathinfo)
120125
goto not_regex_trailing_slash_HEAD_method;
121126
}
122127

128+
$ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_HEAD_method')), array ());
123129
if (substr($pathinfo, -1) !== '/') {
124-
return $this->redirect($pathinfo.'/', 'regex_trailing_slash_HEAD_method');
130+
return array_replace($ret, $this->redirect($pathinfo.'/', 'regex_trailing_slash_HEAD_method'));
125131
}
126132

127-
return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_HEAD_method')), array ());
133+
return $ret;
128134
}
129135
not_regex_trailing_slash_HEAD_method:
130136

src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,22 @@ public function testNoSchemaRedirectIfOnOfMultipleSchemesMatches()
6565
$matcher = $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($coll, new RequestContext()));
6666
$matcher
6767
->expects($this->never())
68+
->method('redirect');
69+
$matcher->match('/foo');
70+
}
71+
72+
public function testRedirectWithParams()
73+
{
74+
$coll = new RouteCollection();
75+
$coll->add('foo', new Route('/foo/{bar}', array(), array(), array(), '', array('https')));
76+
77+
$matcher = $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($coll, new RequestContext()));
78+
$matcher
79+
->expects($this->once())
6880
->method('redirect')
81+
->with('/foo/baz', 'foo', 'https')
82+
->will($this->returnValue(array('_route' => 'foo')))
6983
;
70-
$matcher->match('/foo');
84+
$this->assertEquals(array('_route' => 'foo', 'bar' => 'baz'), $matcher->match('/foo/baz'));
7185
}
7286
}

0 commit comments

Comments
 (0)