Bundle Collection
The BundleCollection
is a container which is used to register every used bundle. As Pimcore gathers bundles from multiple
sources - registered via code in App\Kernel
and registered through config/bundles.php
config, it makes sense to have
a unified API how bundles can be registered.
While Symfony's standard edition uses a registerBundles
method building an array of bundles to load, Pimcore expects you
to register your bundles in the registerBundlesToCollection()
method and to use the bundle collection to add bundles.
Bundles without a priority are registered with a default priority of 0. You can set a negative value if you need to set a priority lower than default.
Below are a couple of examples how the bundle collection can be used:
<?php
namespace App;
use Pimcore\HttpKernel\BundleCollection\BundleCollection;
use Pimcore\HttpKernel\BundleCollection\Item;
use Pimcore\HttpKernel\BundleCollection\LazyLoadedItem;
use Pimcore\Kernel as PimcoreKernel;
class Kernel extends PimcoreKernel
{
public function registerBundlesToCollection(BundleCollection $collection): void
{
// add a bundle
$collection->addBundle(new BundleA());
// add a bundle, set a higher priority and restrict it to an environment
$collection->addBundle(new BundleB(), 10, ['dev']);
// add a bundle again - it will be ignored and still be loaded with prio 10
$collection->addBundle(new BundleB());
// add a bundle as string argument to load it lazily - the class instance will
// only be built when really needed (when the environment matches), so this makes
// sense for every item added with an environment restriction
$collection->addBundle(BundleC::class, 10, ['dev']);
// addBundle() is actually just a wrapper for add() which you can also directly use
$collection->add(new Item(new BundleD(), 10, ['dev', 'prod']));
// addBundle() is actually just a wrapper for add() which you can also directly use
$collection->add(new LazyLoadedItem(BundleE::class, 10, ['dev']));
// the collection expectes an ItemInterface - if needed you can get fancy and implement
// your own item type
$collection->add(new FancyItem(/* whatever your item needs */));
}
}
Bundle Dependencies
If a bundle depends on other bundles, e.g. because it uses features provided by a third-party bundle you need to
make sure that third-party bundle is loaded together with your bundle. You can either instruct your users to manually
load the bundles your bundle depends on in their App\Kernel
or you can implement the DependentBundleInterface
and define a list of bundles which should be loaded together with your bundle:
<?php
namespace CustomBundle;
use Pimcore\HttpKernel\Bundle\DependentBundleInterface;
use Pimcore\HttpKernel\BundleCollection\BundleCollection;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class CustomBundle extends Bundle implements DependentBundleInterface
{
public static function registerDependentBundles(BundleCollection $collection): void
{
// register any bundles your bundle depends on here
$collection->addBundle(new FooBundle);
}
}
Important: the registerDependentBundles
method will be called as soon as your bundle is added to the collection. Even
if your bundle has environment restrictions, the bundles added to the collection from registerDependentBundles
will still
be loaded. If you need to restrict the environments where the dependencies should be loaded, restrict them with the env
argument to addBundle()
. For performance reasons, you should add the bundle as lazy by adding a class name as string or
by using addItem
directly and passing a LazyLoadedItem
instance. This ensures that the bundle instance is only built
when it is really needed. Example:
As example:
<?php
// ...
use Pimcore\HttpKernel\BundleCollection\LazyLoadedItem;
class CustomBundle extends Bundle implements DependentBundleInterface
{
public static function registerDependentBundles(BundleCollection $collection): void
{
// call addBundle with a class name as string and restrict it to the dev environment
$collection->addBundle(FooBundle::class, 0, ['dev']);
// directly add a LazyLoadedItem - this is what addBundle does internally when gets a string
$collection->add(new LazyLoadedItem(FooBundle::class, 0, ['dev']));
}
}
Overriding collection items
In case bundle defines a dependency which has the wrong priority or environment restrictions for your project you can
override the dependency definition by adding the item to the collection before it is loaded as dependency. The dependency
is simply ignored and your item will be used. Let's assume CustomBundle
defines FooBundle
as dependency and loads it
with a priority of 10, but we need to set the priority to 25:
<?php
// ...
class CustomBundle extends Bundle implements DependentBundleInterface
{
public static function registerDependentBundles(BundleCollection $collection): void
{
$collection->addBundle(FooBundle::class, 10);
}
}
To override this, register FooBundle
manually with your priority:
<?php
namespace App;
use Pimcore\HttpKernel\BundleCollection\BundleCollection;
use Pimcore\Kernel as PimcoreKernel;
class Kernel extends PimcoreKernel
{
public function registerBundlesToCollection(BundleCollection $collection): void
{
// register FooBundle manually
$collection->addBundle(FooBundle::class, 25);
// FooBundle won't be registered again here as it is already registered
$collection->addBundle(new \CustomBundle\CustomBundle);
}
}