Symfony: Adding custom route by code during runtime

During development we always come across situation where you need to add custom routes based on some settings based from the user. In this case we cannot use any of the standard methods like annotation and configuration files in symfony.

In this case you need to use a services and hooks to inject your custom route rules during runtime.

1) In your bundles under Resources\Config\services.yml add the following

services:
  Custom.Router:
    class: [BundleNamespace]\Classes\RoutingService
    arguments: [@service_container,@request_stack]
    tags:
      - { name: routing.loader }

2) Now we need to create a class RoutingService.php

< ?php
namespace &#91;BundleNamespace&#93;\Classes\Service;

use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\Config\Loader\LoaderResolverInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

class RoutingService implements LoaderInterface , ContainerAwareInterface
{
    use ContainerAwareTrait;

    function __construct(ContainerInterface $container = null, RequestStack $request_stack = null)
    {
        $this->setContainer($container);
        $this->setRequestStack($request_stack);
    }

    public function load($resource, $type = null)
    {
        $routes = new RouteCollection();

        $searchRoute = new Route('/{siteSlug}/search/index.php', array(
            '_controller' => '[BundleNamespace]:[Controller]:[Action]',
        ), array(
            'siteSlug' => '[a-zA-Z0-9-]+'
        ));
        $routes->add('search_page', $searchRoute);

        return routes;
    }

    public function supports($resource, $type = null)
    {
        return 'dynamic' === $type;
    }

    public function getResolver()
    {
        // needed, but can be blank, unless you want to load other resources
        // and if you do, using the Loader base class is easier (see below)
    }

    public function setResolver(LoaderResolverInterface $resolver)
    {
        // same as above
    }
}

3) Now in your main routing.yml please include these lines

custom_dynamic:
    resource: .
    type: dynamic

4) Once you are done please make sure you clear cache both env

[sh]./app/console cache:clear
./app/console cache:clear –env=prod
[/sh]

5) Now the custom route should be loaded in.. Please make sure if you add more routes make sure the cache is cleared.

By Imthiaz

Programmer, SAAS, CMS & CRM framework designer, Love Linux & Apple products, Currently addicted to mobile development & working @bluebeetle