Search code examples
symfonybundles

Symfony2 use getDoctrine() in AppKernel to dynamically register bundles


I have created an application where I can manage multiple websites. There are a lot of "extensions" (bundles) that can be used in the websites if they have the right to use it. The rights (which website can use wich bundles) are managed in my application and are saved in the database (with the namespace of the allowed bundle).

EDIT: When I call a website the bundles are loaded in the WebsiteKernel (a normal AppKernel that is commonly used by each website). Each website has its's own app- and web-folder. So there is a separate app-cache for each website. Each website has it's own WebsiteKernel.php (= a normal AppKernel).

Now I want to register the allowed bundles for the currently called website dynamically in the its WebsiteKernel. In the post "Is it possible to dynamically register bundles in Symfony2?" this was done by looking into the bundle-directories. I would like to do this the same way but I only want to include the bundles that are saved as "allowed for this website" in the database.

To do so I need access to a repository to get the allowed bundle-namespaces. I thought I could do something like $this->getDoctrine()->getRepository('MyAppBundle:MyObject'); but I don't know how to call this function in the WebsiteKernel (= AppKernel). When I try to call $this->getDoctrine() I have a UndefinedMethodExeption. Of course I try to do this after the doctrine-bundle has been registered.

So the question is: How do I have to change the code in the WebsiteKernel (= AppKernel) to use $this->getDoctrine()?

Btw.: This two posts have a similar problem but they hasn't been answered yet.


Solution

  • NOTE: The question was changed completely so this answer is no longer relevant. I should probably delete it but it does explain the problems with dynamically loading bundles.

    The reason the questions have not been answered is that you basically can't do what you want.

    First off, the doctrine entity manager has not yet been defined when AppKernel::registerBundles is called. It's a bit of a chicken and egg thing. Bundles are registered, all of the configuration files are processed and merged then the dependency injection service definitions(including the entity manager) are created and cached.

    With a better understanding of the bootstrap process you could create your own database connection and pull bundle class names from a database. Of course the routing stuff has not been done yet so figuring out which bundles to load based on the route would mean further hacks.

    The final major problem is that all of the configuration information ends up being cached. Take a look at app/cache. Rebuilding the cache is a time consuming process. Rebuilding the cache on each request would bring your production system to a crawl. And if another request comes in while the first one is being processed then you are really screwed as the second request will probably crash the first one when the cache is rebuilt.

    The only approach that I know of is to setup an app for each website.