$event->stopPropagation() когда, где и зачем надо останавливать события?
Метод stopPropagation()
, есть у любого события, поддерживающего интерфейс Joomla\Event\EventInterface
, по умолчанию метод описан в классе Joomla\Event\AbstractEvent
.
Как это работает?
События обрабатываются плагинами поочередно, перед каждым вызовом проверяется не остановлено ли событие.
if (isset($this->listeners[$event->getName()])) {
foreach ($this->listeners[$event->getName()] as $listener) {
if ($event->isStopped()) {
return $event;
}
$listener($event);
}
}
Где можно использовать?
Существуют события которые могут или должны быть обработать только одним плагином. Например, событие onUserAuthenticate
, работает до первого успешного результата, если пользователь уже авторизован по токену, то незачем пытаться авторизовать его другими способами.
Ещё пример: в моём компоненте импорта в каждом задании явно указан плагин, обеспечивающий получение файла с данными (по ссылке, почте, и др.)
Откуда вызывать?
Останавливать событие можно в обработчиках событий плагинов сразу после успешной проверки, если событие должно быть обработано только данным плагином.
public function onMyImportCheckNewFiles(CheckNewFilesEvent $event): void
{
$stockTable = $event->getStockTable();
if ($stockTable->plugin == 'email')
{
$event->stopPropagation();
// ...
}
}
Или после достижения цели, если событие обрабатывается всеми плагинами до первого результата.
public function onMyImportCheckNewFiles(CheckNewFilesEvent $event): void
{
$stockTable = $event->getStockTable();
if ($this->chekNewFiles($stockTable))
{
$event->stopPropagation();
}
}
Если событие требует от плагинов какого либо результата, то остановку события можно перенести в метод установки этого результата.
public function onMyImportCheckNewFiles(CheckNewFilesEvent $event): void
{
$stockTable = $event->getStockTable();
if ($newFiles = $this->chekNewFiles($stockTable))
{
// $event->stopPropagation(); будет вызван в методе setNewFiles
$event->setNewFiles($newFiles);
}
}