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.
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 | |
---|---|
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 | |
---|---|
You can call
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 = \Joomla\CMS\Factory::getApplication() ->bootComponent('com_content') ->getMVCFactory() ->createModel('Article', 'Administrator'); |