Each Joomla event has its own class
In the post Replacing the deprecated CMSApplicationInterface::triggerEvent method in Joomla 5.1.4, I briefly mentioned our own event classes. Now I want to tell you more about them.
Creating a class starts with a namespace, class name and parent
The name and namespace of a class depends on the context. For example, I'm writing an import component for JoomShopping:
Namespace
Event\Model\Price
– The event belongs to the model, but there are other models in the component that also have a method importExcel
. So let's include the model name Price
in namespace.
Class name
Let's call the class BeforeImportExcelEvent
similar to other classes from Joomla core. A component can have event classes with the same name, but a different namespace.
Parent class
The obvious parent for our class is Joomla\CMS\Event\AbstractEvent
which is the parent of both Joomla\CMS\Event\GenericEvent
used by default.
And so, our class is ready to use, but it does not have any advantages.
Disadvantages of the Standard Event Class
The event object's primary purpose is to pass data to an event handler and receive results from it. In class \Joomla\CMS\Event\GenericEvent
methods are available to you getArgument
And setArgument
with which you can work with arguments by name.
<?php
public function onJSImportPriceBeforeImportExcel(Event $event): void
{
$data = $event->getArgument('data');
}
The disadvantage of this approach is that the method getArgument
returns mixed
that is, there could be anything in there, your IDE doesn't know what's in the variable, and it's not the expected data type that could cause an error.
You can add @var
-comment and type check for each argument:
<?php
public function onJSImportPriceBeforeImportExcel(Event $event): void
{
/** @var array $data */
$data = $event->getArgument('data');
if (!is_array($data))
{
throw new Exception('Data must be array');
}
}
But you have to do this in every event of every plugin, which makes the code more cumbersome.
The benefits of a class of its own
Getters and setters for arguments
In your class you can define setters and getters for arguments and methods setArgument
And getArgument
parent class Joomla\CMS\Event\AbstractEvent
will use them.
on
+ Set/Get
+ Имя аргумента с большой буквы
.
In my case onSetData($value)
And onGetData($value)
.
setArgument
will pass the value to the setter and set the result received from it.
getArgument
will pass the value to the getter and return the result received from it.
Native methods
Also, for the convenience of writing plugins, you can add your own method to the event class to receive data: getData(): array
by telling it the return type. This way, the code for getting valid data in the plugin will be reduced to one line, and the IDE will see the data type.
<?php
public function onJSImportPriceBeforeImportExcel(BeforeImportExcelEvent $event): void
{
$data = $event->getData();
}
And here is the code of our class:
<?php
namespace Joomla\Component\Jsimport\Event\Model\Price;
use Joomla\CMS\Event\AbstractEvent;
use function defined;
// phpcs:disable PSR1.Files.SideEffects
defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* @since 1.0.0
*/
class BeforeImportExcelEvent extends AbstractEvent
{
/**
* Setter for the data argument.
*
* @param array $value The value to set
*
* @return array
*
* @since 1.0.0
*/
protected function onSetData(array $value): array
{
if (!count($data))
{
throw new Exception('Data must be not empty array');
}
return $value;
}
/**
* Getter for the data.
*
* @return array
*
* @since 1.0.0
*/
public function onGetData(array $value): array
{
return $value;
}
/**
* @return array
*
* @since 1.0.0
*/
public function getData(): array
{
return $this->getArgument($data);
}
}
In Joomla 5.2.0 there are other parent classes, interfaces and traits for events; I will write about them in the next article.