symfonysymfony-cmf

Symfony - Changing config value dynamically


I am using Symfony CMF, it has a RoutingAutoBundle, which exposes these parameters:

cmf_routing_auto:
    ....
    persistence:
        phpcr:
            route_basepath: /routes

I need to set the route_basepath dynamically on the go, is it possible to change config.yml values dynamically?

I am building a CMS that is isolated for every user, to do this, i am storing every users routes in his own PHPCR document.

My idea is to change the routers basepath based on the request HTTP_HOST and or subdomain, in a early request listener.

EDIT

Here is the structure.

enter image description here


Solution

  • For anyone else trying to do this, it's quite a complicated task when you are new to the CMF bundle and AutoRouting, the route_basepath, cannot be changed dynamically by event listeners etc, if you are depending on the request, the request will not be available at that point.

    I managed to do it by doing the following:

    Override the "cmf_routing.phpcr_candidates_prefix" service, and replace all references to it with your own candidates prefix service.

    class OverrideRoutePrefixListener implements CompilerPassInterface
    {
        public function process(ContainerBuilder $container)
        {
            $routePrefixDefinition = $container->getDefinition('cmf_routing.phpcrodm_route_idprefix_listener');
            $routePrefixDefinition->replaceArgument(0, new Reference('app.phpcr_candidates_prefix'));
    
            $routeLocalePrefixDefinition = $container->getDefinition('cmf_routing.phpcrodm_route_locale_listener');
            $routeLocalePrefixDefinition->replaceArgument(0, new Reference('app.phpcr_candidates_prefix'));
        }
    }
    

    Your own service should subclass the original and change the constructor, you might have to copy a bunch of the private fields etc.

    public function __construct(array $prefixes, array $locales = array(), ManagerRegistry $doctrine = null, $limit = 20)
    {
        // Do something else here, if you just want multiple prefixes, its supported by the config 
        // But if you want to fetch them from the database or the like, you have to do this.
        $prefixes = ['/users/admin/sites/test/routes', '/users/admin/sites/test/simple'];
    
        parent::__construct($prefixes, $locales = array(), $doctrine = null, $limit = 20);
        $this->setPrefixes($prefixes);
    
        $this->doctrine = $doctrine;
    }
    

    Inside of your own cmf_routing.phpcr_candidates_prefix, you are free to resolve the prefix to whatever you want.

    The second step is overriding the PhpcrOdmAdapter, you can do this with a compiler pass aswell.

    class OverridePhpcrOdmAdapter implements CompilerPassInterface
    {
        public function process(ContainerBuilder $container)
        {
            $definition = $container->getDefinition('cmf_routing_auto.adapter.phpcr_odm');
            $definition->setClass(PhpcrOdmAdapter::class);
        }
    }
    

    And change the base path at the constructor.