Work In Progress

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

The lifetime of a component

In the previous section we talked about the new concepts in the Joomla 4 MVC but it's really hard to understand how they all work together. It's best if we talk about the lifetime of a component, i.e. what happens when you try to access a Joomla URL in the form index.php?option=com_example&view=foo.

The lifetime of our component starts in the application object (SiteApplication, AdministratorApplication or ApiApplication), namely its dispatch() method. All these methods do some initialisation and call Joomla\CMS\Component::renderComponent(). This method runs this line where things get interesting for our component:

$app->bootComponent($option)->getDispatcher($app)->dispatch();

Let's rewrite it so it's more readable:

$componentExtension = $app->bootComponent($option)
            $componentDispatcher = $componentExtension->getDispatcher($app)
            $componentDispatcher->dispatch();

What Joomla does is ask the application object to somehow get a component extension object — even if it is a legacy component using the Joomla 3 MVC. Then it asks the component extension object to get it the component's Dispatcher object. Finally, it tells the component's Dispatcher to dispatch (execute) the component.

These three steps are crucial to understanding the difference between legacy Joomla 3 MVC components, modern Joomla 4 MVC components and how Joomla 4 makes them all work.

Booting the component

The bootComponent method is implemented by Joomla\CMS\Extension\ExtensionManagerTrait. The first thing it does, by calling its loadExtension method, is to figure out if this is a Joomla 4 MVC or Joomla 3 MVC component. It does that by looking for the services/provider.php file under the component's root. As you may have guessed this is our component's service provider and the reason why all Joomla 4 MVC components, even the simplest ones for which we could infer their service provider, really do need to have a service provider file.

If the file exists it's loaded and its services are registered into the copy of the Joomla DIC which is used as our component's DIC.

[Note]Note

This means that our component only sees a frozen in time copy of the global application services. You cannot register any services in the component's DIC and expect them to be available in the global application.

If the file does not exist, Joomla creates an instance of the Joomla\CMS\Extension\LegacyComponent. As you can see, this extension object uses a legacy MVC factory object which "speaks" the Joomla 3 non-namespaced MVC class names and a legacy component dispatcher which looks for the componentName.php (in our example: example.php) component entry point file and loads it. This is exactly how Joomla 4 can render components using Joomla 3 MVC.

The rest of this section will talk about a Joomla 4 MVC component.

Finally, Joomla returns the component's extension object as the result of the bootComponent method.

[Tip]Tip

You can call \Joomla\CMS\Factory::getApplication()->bootComponent('com_example') to get the com_example component's extension object anytime, anywhere — including in modules and plugins. If you subclass the Joomla\CMS\Extension\MVCExtension class in your own component you can create your own methods to return ANY OBJECT KNOWN TO THE COMPONENT AND ITS CONTAINER.

This is of enormous importance.

You can instantiate any MVC class of the component. You have access to your HTML helper, categories service and router service. You can get an instance of any of the custom services you created in your component. All of that WITHOUT any static helpers in your extension, WITHOUT worrying that something might break if you call your code outside your component. Your Models can provide a public API for third party developers communicating with your component.

Joomla core components already do that. For example, you can get the backend ArticleModel of com_content in a frontend component or plugin to create a new Joomla article the right way:

$articleModel = \Joomla\CMS\Factory::getApplication()
                    ->bootComponent('com_content')
                    ->getMVCFactory()
                    ->createModel('Article', 'Administrator');