Search code examples
phpsymfonyroutes

How to add custom routes to Symfony 2 before container compilation?


Let me explain the case in further details because the title doesn't explain it very well without being too long.

I'm building a mini framework on top of SF2 to use with our legacy system. We developed a mini, simple plugin system, each plugin will have its own routing.xml which may look like this:

routes:
  admin_plugins:
    pattern:  /manager/
    defaults: { _controller: plugins\riCore\AdminController::indexAction }

We want to obviously add these routes into the routeCollection, but there is 1 tweak: we want to prepend the route pattern and id with the plugin name. We used to loop through the list of plugin and do it manually like this:

self::$container->get('router')->getRouteCollection()->add($plugin_lc_name . '_' . $key, new Route($route['pattern'], $route['defaults'], $route['requirements'], $route['options']));

However, now that we moved to use SF2 kernel and do a compilation of the container, we began to run into this problem:

[21-Oct-2012 08:40:57] PHP Fatal error:  Call to undefined method Symfony\Component\Routing\RouteCollection::__set_state() in plugins\cache\prod\pluginsProdProjectContainer.php on line 791

So I figured it could be due to the fact that we tried to getRouteCollection() the too soon and perhaps there must be a way around?


Solution

  • To answer my question, yes it seems to work. I just haven't found a way to make SF2 cache those routes yet. Below is part of the code I'm using to add dynamic routes. As you can see I want to add certain prefixes to routes

    $plugin_lc_name = strtolower($plugin);
                    foreach ($plugins_settings[$plugin]['routes'] as $key => $route) {
                        $route = array_merge(array('pattern'      => '',
                                                   'defaults'     => array(),
                                                   'requirements' => array(),
                                                   'options'      => array()), $route);
                        if (strpos($route['pattern'], '/') !== false)
                            $route['pattern'] = $plugin_lc_name . $route['pattern'];
                        else
                            $route['pattern'] = $plugin_lc_name . '_' . $route['pattern'];
    
                        $container::get('router')->getRouteCollection()->add($plugin_lc_name . '_' . $key, new Route($route['pattern'], $route['defaults'], $route['requirements'], $route['options']));
                    }