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\AbstractEventwhich 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.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *