Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 147 additions & 0 deletions docs/building-extensions/plugins/joomla-4-and-5-changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,153 @@ use Joomla\CMS\Event\Result\ResultAwareInterface;

**If you're developing a developing a plugin to handle a `GenericEvent` then it's crucial to use the above mechanisms to avoid the plugin failing whenever the triggering code moves to using a concrete Event class.**

## Summary - Accessing Event Arguments

### Concrete Event Class

You can use this approach if under libraries/src/Event there is a Joomla event class (known as a "concrete" event class) which is specific to the plugin event group. (Only a limited set is available for Joomla 4).

```php
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Event\SubscriberInterface;
use Joomla\CMS\Event\Content\ContentPrepareEvent;

class MyPlugin extends CMSPlugin implements SubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
'onContentPrepare' => 'myOnContentPrepare',
];
}

public function myOnContentPrepare(ContentPrepareEvent $event)
{
$context = $event->getContext();
$item = $event->getItem();
$params = $event->getParams();
$page = $event->getPage();
// ...
}
```

Here in the getter call you must use the correct name for the argument, and in the Joomla manual documentation the correct name is always specified.

You can also find the getter methods in the API documentation for the event class, for example [Event/Content/ContentPrepareEvent methods](cms-api://classes/Joomla-CMS-Event-Content-ContentPrepareEvent.html).

To use an event class your plugin class must implement \Joomla\Event\SubscriberInterface and provide the `getSubscribedEvents` function. Your plugin listener function must then have just the single `$event` parameter.

### Generic Event Class

Use this approach after Joomla 4.0 if you wish to use event classes, but a concrete event class isn't available for your target Joomla version.

```php
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Event\SubscriberInterface;
use Joomla\Event\Event;

class MyPlugin extends CMSPlugin implements SubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
'onContentPrepare' => 'myOnContentPrepare',
];
}

public function myOnContentPrepare(Event $event)
{
[$context, $item, $params, $page] = array_values($event->getArguments());
...
}
```

This approach also works for concrete event classes.

It depends on the order of the arguments in the event class, and the correct order is always given in the documentation.

There is a commitment from the Joomla team to preserve the same order within the event arguments as within the order of the parameters of the legacy method, but this will be removed in Joomla 6. This is implemented via the variable `$legacyArgumentsOrder`, eg in Joomla\CMS\Event\Content\ContentPrepareEvent (in libraries/src/Event/Content/ContentPrepareEvent.php):

```php
class ContentPrepareEvent extends ContentEvent
{
protected $legacyArgumentsOrder = ['context', 'subject', 'params', 'page'];
```

### Traditional Legacy Method

You will be using this method if you developed your plugin before Joomla 4.0. In this case, you're probably better to continue this approach until concrete event classes are available for all the events your plugin listens for.

You shouldn't use this approach for developing a new plugin, as you will have to rework it.

To use the traditional (legacy) method, you specify a public function which has the same name as the event name, and Joomla uses PHP reflection to find your method. You specify the event parameters in your function signature, for example:

```php
use Joomla\CMS\Plugin\CMSPlugin;

class MyPlugin extends CMSPlugin
{
public function onContentPrepare($context, $item, $params, $page)
{
if ($context == "com_content.article") ...
}
```

It doesn't matter what you specify as the names of your function parameters, just on their order in the parameter sequence.
The documentation in the Joomla manual always specifies the correct order of these arguments.

## Summary - Returning Values

### Concrete Event Class

To return a value when using a concrete event class use `$event->addResult()`:

```php
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Event\Content\AfterTitleEvent;

class MyPlugin extends CMSPlugin

public function onContentAfterTitle(AfterTitleEvent $event)
{
...
$event->addResult($value);
}
```

### Generic Event Class

To return a value when using a generic event class use the following:

```php
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Event\Event;

class MyPlugin extends CMSPlugin

public function onContentAfterTitle(Event $event)
{
...
$result = $event->getArgument('result') ?: []; // get the result argument from GenericEvent
$result[] = $value; // add your return value into the array
$event->setArgument('result', $result);
}
```

This approach will also work with concrete event classes.

### Traditional Legacy Method

To return a value when using the legacy method use the PHP `return`:

```
public function onContentAfterTitle($context, $item, $params, $page)
{
...
return $value;
}
```

## Other New Features
### Priority
To use a plugin priority other than the default, specify this in your response to `getSubscribedEvents`
Expand Down
Loading