@@ -29,7 +29,6 @@ class PhpMatcherDumper extends MatcherDumper
29
29
{
30
30
private $ expressionLanguage ;
31
31
private $ signalingException ;
32
- private $ supportsRedirections ;
33
32
34
33
/**
35
34
* @var ExpressionFunctionProviderInterface[]
@@ -57,7 +56,7 @@ public function dump(array $options = array())
57
56
58
57
// trailing slash support is only enabled if we know how to redirect the user
59
58
$ interfaces = class_implements ($ options ['base_class ' ]);
60
- $ this -> supportsRedirections = isset ($ interfaces [RedirectableUrlMatcherInterface::class]);
59
+ $ supportsRedirections = isset ($ interfaces [RedirectableUrlMatcherInterface::class]);
61
60
62
61
return <<<EOF
63
62
<?php
@@ -77,7 +76,7 @@ public function __construct(RequestContext \$context)
77
76
\$this->context = \$context;
78
77
}
79
78
80
- {$ this ->generateMatchMethod ()}
79
+ {$ this ->generateMatchMethod ($ supportsRedirections )}
81
80
}
82
81
83
82
EOF ;
@@ -91,7 +90,7 @@ public function addExpressionLanguageProvider(ExpressionFunctionProviderInterfac
91
90
/**
92
91
* Generates the code for the match method implementing UrlMatcherInterface.
93
92
*/
94
- private function generateMatchMethod (): string
93
+ private function generateMatchMethod (bool $ supportsRedirections ): string
95
94
{
96
95
// Group hosts by same-suffix, re-order when possible
97
96
$ matchHost = false ;
@@ -111,7 +110,7 @@ private function generateMatchMethod(): string
111
110
112
111
$ code = <<<EOF
113
112
{
114
- \$allow = array();
113
+ \$allow = \$ allowSchemes = array();
115
114
\$pathinfo = rawurldecode( \$rawPathinfo);
116
115
\$context = \$this->context;
117
116
\$requestMethod = \$canonicalMethod = \$context->getMethod();
@@ -124,25 +123,44 @@ private function generateMatchMethod(): string
124
123
125
124
EOF ;
126
125
127
- if ($ this -> supportsRedirections ) {
126
+ if ($ supportsRedirections ) {
128
127
return <<<'EOF'
129
128
public function match($pathinfo)
130
129
{
131
- $allow = array();
132
- if ($ret = $this->doMatch($pathinfo, $allow)) {
130
+ $allow = $allowSchemes = array();
131
+ if ($ret = $this->doMatch($pathinfo, $allow, $allowSchemes )) {
133
132
return $ret;
134
133
}
135
- if ('/' !== $pathinfo && in_array($this->context->getMethod(), array('HEAD', 'GET'), true)) {
134
+ if ($allow) {
135
+ throw new MethodNotAllowedException(array_keys($allow));
136
+ }
137
+ if (!in_array($this->context->getMethod(), array('HEAD', 'GET'), true)) {
138
+ // no-op
139
+ } elseif ($allowSchemes) {
140
+ redirect_scheme:
141
+ $scheme = $this->context->getScheme();
142
+ $this->context->setScheme(key($allowSchemes));
143
+ try {
144
+ if ($ret = $this->doMatch($pathinfo)) {
145
+ return $this->redirect($pathinfo, $ret['_route'], $this->context->getScheme()) + $ret;
146
+ }
147
+ } finally {
148
+ $this->context->setScheme($scheme);
149
+ }
150
+ } elseif ('/' !== $pathinfo) {
136
151
$pathinfo = '/' !== $pathinfo[-1] ? $pathinfo.'/' : substr($pathinfo, 0, -1);
137
- if ($ret = $this->doMatch($pathinfo)) {
152
+ if ($ret = $this->doMatch($pathinfo, $allow, $allowSchemes )) {
138
153
return $this->redirect($pathinfo, $ret['_route']) + $ret;
139
154
}
155
+ if ($allowSchemes) {
156
+ goto redirect_scheme;
157
+ }
140
158
}
141
159
142
- throw $allow ? new MethodNotAllowedException(array_keys($allow)) : new ResourceNotFoundException();
160
+ throw new ResourceNotFoundException();
143
161
}
144
162
145
- private function doMatch(string $rawPathinfo, array &$allow = array()): ?array
163
+ private function doMatch(string $rawPathinfo, array &$allow = array(), array &$allowSchemes = array() ): ?array
146
164
147
165
EOF
148
166
.$ code ."\n return null; \n } " ;
@@ -238,9 +256,6 @@ private function compileStaticRoutes(array $staticRoutes, bool $matchHost): stri
238
256
}
239
257
240
258
if (!$ route ->getCondition ()) {
241
- if (!$ this ->supportsRedirections && $ route ->getSchemes ()) {
242
- throw new \LogicException ('The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface. ' );
243
- }
244
259
$ default .= sprintf (
245
260
"%s => array(%s, %s, %s, %s), \n" ,
246
261
self ::export ($ url ),
@@ -535,8 +550,8 @@ private function compileSwitchDefault(bool $hasVars, bool $matchHost): string
535
550
} else {
536
551
$ code = '' ;
537
552
}
538
- if ( $ this -> supportsRedirections ) {
539
- $ code .= <<<EOF
553
+
554
+ $ code .= <<<EOF
540
555
541
556
\$hasRequiredScheme = ! \$requiredSchemes || isset( \$requiredSchemes[ \$context->getScheme()]);
542
557
if ( \$requiredMethods && !isset( \$requiredMethods[ \$canonicalMethod]) && !isset( \$requiredMethods[ \$requestMethod])) {
@@ -546,28 +561,13 @@ private function compileSwitchDefault(bool $hasVars, bool $matchHost): string
546
561
break;
547
562
}
548
563
if (! \$hasRequiredScheme) {
549
- if ('GET' !== \$canonicalMethod) {
550
- break;
551
- }
552
-
553
- return \$this->redirect( \$rawPathinfo, \$ret['_route'], key( \$requiredSchemes)) + \$ret;
554
- }
555
-
556
- return \$ret;
557
-
558
- EOF ;
559
- } else {
560
- $ code .= <<<EOF
561
-
562
- if ( \$requiredMethods && !isset( \$requiredMethods[ \$canonicalMethod]) && !isset( \$requiredMethods[ \$requestMethod])) {
563
- \$allow += \$requiredMethods;
564
+ \$allowSchemes += \$requiredSchemes;
564
565
break;
565
566
}
566
567
567
568
return \$ret;
568
569
569
570
EOF ;
570
- }
571
571
572
572
return $ code ;
573
573
}
@@ -647,9 +647,6 @@ private function compileRoute(Route $route, string $name, bool $checkHost): stri
647
647
}
648
648
649
649
if ($ schemes = $ route ->getSchemes ()) {
650
- if (!$ this ->supportsRedirections ) {
651
- throw new \LogicException ('The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface. ' );
652
- }
653
650
$ schemes = self ::export (array_flip ($ schemes ));
654
651
if ($ methods ) {
655
652
$ code .= <<<EOF
@@ -662,11 +659,8 @@ private function compileRoute(Route $route, string $name, bool $checkHost): stri
662
659
goto $ gotoname;
663
660
}
664
661
if (! \$hasRequiredScheme) {
665
- if ('GET' !== \$canonicalMethod) {
666
- goto $ gotoname;
667
- }
668
-
669
- return \$this->redirect( \$rawPathinfo, ' $ name', key( \$requiredSchemes)) + \$ret;
662
+ \$allowSchemes += \$requiredSchemes;
663
+ goto $ gotoname;
670
664
}
671
665
672
666
@@ -675,11 +669,8 @@ private function compileRoute(Route $route, string $name, bool $checkHost): stri
675
669
$ code .= <<<EOF
676
670
\$requiredSchemes = $ schemes;
677
671
if (!isset( \$requiredSchemes[ \$context->getScheme()])) {
678
- if ('GET' !== \$canonicalMethod) {
679
- goto $ gotoname;
680
- }
681
-
682
- return \$this->redirect( \$rawPathinfo, ' $ name', key( \$requiredSchemes)) + \$ret;
672
+ \$allowSchemes += \$requiredSchemes;
673
+ goto $ gotoname;
683
674
}
684
675
685
676
0 commit comments