1 | <?php |
||
26 | final class TrailingSlashControllerProvider implements ControllerProviderInterface, ServiceProviderInterface |
||
27 | { |
||
28 | /** |
||
29 | * @param Application $app |
||
30 | * |
||
31 | * @return \Silex\ControllerCollection |
||
32 | */ |
||
33 | 49 | public function connect(Application $app) |
|
34 | { |
||
35 | 49 | $controllers = $app['controllers_factory']; |
|
36 | |||
37 | $handler = function ($resource) use ($app) { |
||
38 | 39 | if ($app['logger']) { |
|
39 | 1 | $app['logger']->debug(sprintf('Appending a trailing slash for the request to `/%s`.', $resource)); |
|
40 | 1 | } |
|
41 | |||
42 | 39 | $request = Request::create( |
|
43 | 39 | '/' . $resource . '/', |
|
44 | 39 | $app['request']->getMethod(), |
|
45 | 39 | [], |
|
46 | 39 | $app['request']->cookies->all(), |
|
47 | 39 | $app['request']->files->all(), |
|
48 | 39 | $app['request']->server->all(), |
|
49 | 39 | $app['request']->getContent() |
|
50 | 39 | ); |
|
51 | 39 | $request = $request->duplicate( |
|
52 | 39 | $app['request']->query->all(), |
|
53 | 39 | $app['request']->request->all() |
|
54 | 39 | ); |
|
55 | 39 | $request->headers->replace($app['request']->headers->all()); |
|
56 | |||
57 | // Make an internal sub-request based off the request that would have 404'd. |
||
58 | // http://silex.sensiolabs.org/doc/usage.html#forwards |
||
59 | 39 | return $app->handle($request, HttpKernelInterface::SUB_REQUEST); |
|
60 | 49 | }; |
|
61 | |||
62 | /** |
||
63 | * Register the catch-all route. |
||
64 | * |
||
65 | * Use a look behind assertion to ensure we only match routes |
||
66 | * with no trailing slash. |
||
67 | * |
||
68 | * @link https://stackoverflow.com/questions/16398471/regex-not-ending-with |
||
69 | */ |
||
70 | 49 | $controllers->match('/{resource}', $handler) |
|
71 | 49 | ->assert('resource', '.*(?<!\/)$') |
|
72 | 49 | ->bind('no_trailing_slash_handler'); |
|
73 | |||
74 | 49 | return $controllers; |
|
75 | } |
||
76 | |||
77 | /** |
||
78 | * @param Application $app |
||
79 | */ |
||
80 | 49 | public function register(Application $app) |
|
81 | { |
||
82 | /** |
||
83 | * We override the default RedirectableUrlMatcher so that Silex doesn't |
||
84 | * respond with 301 to GET requests missing a trailing slash. |
||
85 | */ |
||
86 | 49 | $app['url_matcher'] = $app->share( |
|
87 | 49 | function () use ($app) { |
|
88 | 49 | if ($app['logger']) { |
|
89 | 1 | $app['logger']->debug(sprintf('Overriding the default Silex url matcher to %s.', UrlMatcher::class)); |
|
90 | 1 | } |
|
91 | |||
92 | 49 | return new UrlMatcher($app['routes'], $app['request_context']); |
|
93 | } |
||
94 | 49 | ); |
|
95 | 49 | } |
|
96 | |||
97 | /** |
||
98 | * @param Application $app |
||
99 | */ |
||
100 | 48 | public function boot(Application $app) |
|
103 | } |
||
104 |