Skip to content

Commit 5cd1eab

Browse files
authored
Merge pull request #159 from robbiejackson/extension-and-dispatcher
Some tidy-up plus Extension and Dispatcher classes
2 parents da57f27 + 2fac7b2 commit 5cd1eab

File tree

9 files changed

+135
-3
lines changed

9 files changed

+135
-3
lines changed
67.1 KB
Loading
66.2 KB
Loading
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
title: Dispatcher Class for Components
3+
sidebar_position: 2
4+
---
5+
# Dispatcher Class for Components
6+
The Dispatcher class comes into play whenever Joomla wants to run a component in order to capture the output to display on the web page. The class has one main function: `dispatch()`, which will run the component.
7+
8+
So to run a component you first get its Extension class then:
9+
```php
10+
$extension->getDispatcher()->dispatch();
11+
```
12+
How the Extension class gets the Dispatcher class instance via the `getDispatcher()` call is covered in the Dependency Injection documentation; you will find the code for `getDispatcher()` in libraries/src/Extension/Component.php - the Component class in this file is in the inheritance chain of the Extension instance.
13+
14+
(You may be wondering why isn't there just a dispatch() function in the Extension class, rather than having this additional Dispatcher class. I think it's because the Joomla designers wanted a common Extension / Dispatcher pattern among components, modules and plugins, and the Dispatcher class for plugins is a lot more complex.)
15+
16+
For components the main purpose of the Dispatcher `dispatch()` code is to
17+
1. work out which component Controller to use, and then
18+
2. instantiate it
19+
3. call its `execute()` method – basically running the MVC component, starting with the controller
20+
4. call its `redirect()` method (to handle where an HTTP redirect is required)
21+
22+
It works out the Controller to use by examining the HTTP query parameters, in particular the *task* parameter.
23+
It uses the *task* by considering its parts as `<controller type>.<method>` (taking 'display' as default if either part is missing). It will then
24+
- create an instance of the class `<Controller type>Controller`
25+
- call its function `<method>`
26+
27+
If the *task* parameter is missing then it will instantiate `DisplayController` and call its `display()` method.
28+
29+
The Controller will be prefixed with the site or administrator namespace prefix to form the fully qualified classname.
30+
31+
(If you're familiar with Joomla 3 components, then you're probably now realising that this is basically the same as you would have had in your entry point file, as described in [Joomla 3 Model-View-Controller](https://docs.joomla.org/Model-View-Controller) The *task* parameter is treated in much the same way in Joomla 4, except that the DisplayController now fits in better with the other controllers. By the way, you may see for some Joomla components an AjaxController.php. Joomla **hasn't** examined the XHR bit and decided to route to an AjaxController because of it. Rather it's because the client javascript has set 'ajax.something' in the task parameter of the Ajax HTTP request.)
32+
33+
If your component uses the *task* parameter as described above to route to the appropriate controller and method then you'll probably not need to define your own Dispatcher class and can use the standard ComponentDispatcher class provided by Joomla in libraries/src/Dispatcher/ComponentDispatcher.php.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
title: Extension Class for Components
3+
sidebar_position: 1
4+
---
5+
# Extension Class for Components
6+
There are a number of occasions where other Joomla code would want to interact with our component, for example
7+
- the router might want to use our component's custom router to parse and build SEF routes
8+
- if our component supports categories, then `com_categories` will want to display on the categories view a summary by category containing the number of items with that category, split by published status
9+
- if our component supports custom fields then `com_fields` will want to call `getContexts()` to get the types of items which can have custom fields associated with them
10+
- if our component supports multilingual associations then `com_associations` will want to know the types of items which can have associations.
11+
- and of course Joomla will want to run our component to capture the output for the web page.
12+
13+
The reasons for introducing the Extension class becomes clearer if we review how other Joomla code interacted with our extension in Joomla 3.
14+
15+
![Joomla 3 component access](_assets/extension-joomla3.jpg "Accessing a component in Joomla 3")
16+
17+
In Joomla 3 all these other bits of code dipped into our component's code base in a rather haphazard fashion – calling functions in various helper files.
18+
19+
In Joomla 4 this is streamlined:
20+
21+
![Joomla 4 component access](_assets/extension-joomla4.jpg "Accessing a component in Joomla 4")
22+
23+
From Joomla 4 components get a handle on our `com_example` component by calling:
24+
```php
25+
$extension = $app->bootComponent("com_example");
26+
```
27+
28+
They can then call their required function on this Extension instance.
29+
30+
Immediately after the component Extension class is instantiated the Joomla library code will call your Extension's `boot` function, passing your child Dependency Injection Container instance:
31+
```php
32+
$extension->boot($container);
33+
```
34+
This is just an opportunity to let you do, well, really, whatever you like. Sometimes it's used to set up particular classes for using with `HtmlHelper::_()` calls. Or you can use it to save a reference to your child DIC (which can be hard to get otherwise).
35+
36+
After the first instantiation of your component Joomla caches the instance, and if there is another call to
37+
```php
38+
$extension = $app->bootComponent("com_example");
39+
```
40+
it just returns your Extension instance, rather than performing the class instantiation and calling of `boot()` again. You can even call `bootComponent` passing your own component, if you need to get a reference to your own Extension object.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
title: Extension and Dispatcher Classes for Modules
3+
sidebar_position: 3
4+
---
5+
# Extension and Dispatcher Classes for Modules
6+
The Extension and Dispatcher classes for modules perform a similar role to those for components, but they're simpler because Joomla instantiates these classes just for the purpose of executing the module to capture the output (aka rendering the module).
7+
8+
The Extension class instance is accessed in a similar way
9+
```php
10+
$module = $app->bootModule($moduleName, $applicationName);
11+
```
12+
where `$moduleName` is the name of the module (eg 'mod_example') and `$applicationName` is 'site' or 'administrator'.
13+
14+
The default module Extension class is defined in libraries/src/Extension/Module.php, and really just provides a mechanism to get to other classes:
15+
- the Dispatcher class (via a DispatcherFactory object), and,
16+
- the module's own helper class (via a HelperFactory object)
17+
18+
Similar to components, the module Dispatcher class contains the `dispatch()` function, which is used to run the module's code.
19+
```php
20+
$module->getDispatcher($mod, $app)->dispatch();
21+
```
22+
Here `$mod` is a PHP stdClass object representing the module, including data such as the module name, module id, module title, template position, and `$app` is the Application instance.
23+
24+
The default module Dispatcher class is defined in libraries/src/Dispatcher/ModuleDispatcher.php
25+
26+
The Joomla code within the Dispatcher class makes available to the module copies of a number of key data items (which the module may find useful to have):
27+
- the module stdClass described above
28+
- the Application instance
29+
- the Input data – the query parameters associated with the URL (`option`, `view`, etc)
30+
- params – the module's params
31+
- template – the name of the template
32+
33+
Unlike in Joomla 3, from Joomla 4 these data items are copies, so if you change them you're not changing the original data items.
34+
35+
In general you're likely to find that you can use the default module Extension and Dispatcher classes, and you can just provide (eg for mod_example)
36+
- the module manifest XML file – mod_example.xml
37+
- the module entry point file – mod_example.php, just containing PHP code rather than a class
38+
- a module helper file (with code to obtain the required data) – a namespaced class under src/Helper/
39+
- a tmpl file containing the HTML to output – under tmpl/, eg tmpl/default.php
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
title: Extension and Dispatcher Classes for Plugins
3+
sidebar_position: 4
4+
---
5+
# Extension and Dispatcher Classes for Plugins
6+
The equivalent classes for plugins are a little different.
7+
8+
For plugins the Extension class is your plugin code, where you specify the events which want to subscribe to, and the code to execute when that event is triggered. See the plugin documentation for more details.
9+
10+
The plugin Dispatcher class is a class internal to Joomla; you don't implement or override it in your plugin code. To trigger an event the code will call `dispatch(...)` on the Dispatcher instance, passing the details of the name of the plugin event and any associated data items. The `dispatch()` function then calls the associated functions of all the plugins which have subscribed to that type of plugin event.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
title: Extension and Dispatcher Classes
3+
sidebar_position: 2
4+
---
5+
The Extension and Dispatcher classes were introduced to the area of extension developers in Joomla 4, who now need to understand what they are.
6+
7+
In considering Extension and Dispatcher classes we're going to focus initially on component extensions. Later we'll see how the concept is extended to modules and plugins.
8+
9+
You may find it useful to look at this video on the [Component Extension class](https://youtu.be/Rf8GhHQ_b3I) and part of this video on [Component Dispatcher and MVC Factory classes](https://youtu.be/zUu-a2KbdVE).

docs/general-concept/namespaces/finding-classes-with-psr4.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ title: Finding Class files with PSR4
44
---
55
Namespaces allow us to organise our PHP classes in a similar way that directories allow us to organise our files. In particular, the [PSR4 recommendation](https://www.php-fig.org/psr/psr-4/) which Joomla uses enables us to determine what file a certain class should be in.
66

7-
![Namespacing](_assets/namespace.jpg "PSR4 namespacing")
8-
97
To see this, let's take an example of the file administrator/components/com_content/src/View/Articles/HtmlView.php, which contains the code for the view which presents the Articles to the administrator. This file contains the lines
108
```php
119
namespace Joomla\Component\Content\Administrator\View\Articles;
@@ -19,3 +17,5 @@ Joomla holds a list of namespace prefixes strings, and it compares the string co
1917
This namespace prefix has an associated directory within the file system, which is the starting point for finding classes. In this case the directory is administrator/components/com_content/src. (We'll see shortly how the namespace prefixes and associated directories are defined).
2018

2119
Next it removes the matching namespace prefix from the FQN, leaving \View\Articles\HtmlView, and treats this as the path down from the above directory. So the full file path is: administrator/components/com_content/src/View/Articles/HtmlView.php. The diagram gives a pictorial view of this.
20+
21+
![Namespacing](_assets/namespace.jpg "PSR4 namespacing")
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
---
22
title: Namespaces
3+
sidebar_position: 1
34
---
45
Namespacing was progressively introduced for Joomla classes over a number of Joomla 3.x releases. In Joomla 4 nearly all of the Joomla classes were namespaced, and it was expected that Joomla extensions were namespaced as well.
56

67
If you're not familiar with PHP namespacing then you can find general information online, for example at https://www.php.net/manual/en/language.namespaces.php
78

8-
This Joomla documentation focuses on how namespacing is implemented within Joomla.
9+
This Joomla documentation focuses on how namespacing is implemented within Joomla. You may find this [video on namespacing](https://youtu.be/4YaILZGnjv4) useful as well.

0 commit comments

Comments
 (0)