Using a custom RouteParser (setDefaultConditions replacement)


#1

Long overdue, but I’m currently working on porting a Slim v2 site to Slim v3 (latest). I have most of the functionality ported over now and wanted to look at the now obsolete \Slim\Route::setDefaultConditions() functionality that was abandoned in favor of FastRoute.

I have added the following to my container configuration, where \SlimWorks\RouteParser is a facade to \FastRoute\RouteParser\Std. \SlimWorks\RouteParser implements setDefaultConditions and the parse() method post-processes the route data provided by Std.

   'router' => function ($c) {
        $routerCacheFile = false;
        if (isset($c->get('settings')['routerCacheFile'])) {
            $routerCacheFile = $c->get('settings')['routerCacheFile'];
        }   

        if (! $c->has('routeparser')) {
            $parser = new \SlimWorks\RouteParser();
            $c['routeparser'] = $parser;
        }   

        $router = (new \Slim\Router($c->routeparser))->setCacheFile($routerCacheFile);
        if (method_exists($router, 'setContainer')) {
            $router->setContainer($c);
        }   

        return $router;
    },  

While testing this, it would not apply the default condition. Doing some dumping and traces, I found out that the actual \SlimWorks\RouteParser being used, is a new instance and not the one I instantiated. The reason is FastRoute\simpleDispatcher, which does new $options['routeParser'] on the passed in RouteParser.

This quick hack proofed my problem:

--- functions.php       2017-08-15 22:40:51.075500118 +0200
+++ functions.new       2017-08-15 22:39:33.883729611 +0200
@@ -18,7 +18,7 @@
         ];
         /** @var RouteCollector $routeCollector */
         $routeCollector = new $options['routeCollector'](
-            new $options['routeParser'], new $options['dataGenerator']
+            $options['routeParser'] instanceof RouteParser ? $options['routeParser'] : new $options['routeParser'], new $options['dataGenerator']
         );
         $routeDefinitionCallback($routeCollector);

Does anybody have a smart idea how to implement this properly?