Работаем с событиями без плагина или как перехватить редирект в Joomla 5
В расширении быстрого заказа для JoomShopping. Я создаю экземпляр модели Checkout и вызываю метод checkStep().
$checkoutModel = JSFactory::getModel('checkout', 'Site'); $checkoutModel->checkStep(2);
В методе checkStep есть условия, при выполнении которых происходит установка сообщения и редирект.
if (!$check) { JSError::raiseNotice('', 'Message'); $mainframe->redirect('Url'); exit(); }
Но мне надо получить результат метода checkStep или исключение. И продолжить работу.
Смотрим какое событие вызывается при редиректе — ApplicationEvents::BEFORE_RESPOND.
Подписываться на события могут не только плагины, но и любые другие callable объекты.
Создадим функцию которая получает заголовки редиректа, удаляет их и бросает исключение:
$onApplicationBeforeRespond = function() { $app = Factory::getApplication(); $response = $app->getResponse(); $status = $response->getHeader('Status'); $location = $response->getHeader('Location'); $response = $response->withoutHeader('Status'); $response = $response->withoutHeader('Location'); $app->setResponse($response); throw new RedirectCaughtException($status[0], $location[0]); };
Перед вызовом $checkoutModel->checkStep(2); подпишем нашу функцию на прослушивание события, а после отпишем. И обернём вызов в try/catch.
$dispatcher->addListener( ApplicationEvents::BEFORE_RESPOND, $onApplicationBeforeRespond ); try { $checkoutModel->checkStep(2); } catch (RedirectCaughtException $e) { // Обрабатываем исключение } $dispatcher->removeListener( ApplicationEvents::BEFORE_RESPOND, $onApplicationBeforeRespond );
Таким образом мы можем перехватывать редиректы внутри блока try.
