Work In Progress

This book is currently work in progress. Some sections are not yet written. Thank you for your understanding!

Service Provider

As discussed in a previous section, the service provider file is mandatory for Joomla 4 native plugins, lives in the plugin's services folder and always named provider.php.

The absolutely minimal minimal service provider file looks like the following:

<?php
defined('_JEXEC') || die;

use Joomla\CMS\Extension\PluginInterface;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Joomla\Event\DispatcherInterface;
use Acme\Plugin\System\Example\Extension\Example;

return new class implements ServiceProviderInterface
{
    /**
     * Registers the service provider with a DI container.
     *
     * @param   Container  $container  The DI container.
     *
     * @return  void
     *
     * @since   4.2.0
     */
    public function register(Container $container)
    {
        $container->set(
            PluginInterface::class,
            function (Container $container) {
                $config  = (array) PluginHelper::getPlugin('system', 'example');
                $subject = $container->get(DispatcherInterface::class);

                return new Example($subject, $config);
            }
        );
    }
};

As you can see the service provider returns an anonymous PHP class which implements the Joomla\DI\ServiceProviderInterface. That's the standard way to extend Joomla's DIC. Joomla creates a copy of its DIC and uses it as our plugin's own DIC. The service providers we set up in our plugin stay with our plugin, they do not leak out to the global application scope (the global Joomla DIC you get through the Joomla\CMS\Factory::getContainer() static method).

The code in the anonymous function does the bare minimum of setting up a plugin. If you need to register custom service providers for your plugin do it before this code.

The return line creates the plugin object from the plugin's class. If you need to push services into your plugin's object instance you will have to replace that line with something like this:

$plugin = Example($subject, $config);
$plugin->setMyCustomService($container->get(MyCustomService::class));

return $plugin;