У меня есть наблюдатель: <controller_action_predispatch_catalog_category_view>
который запускает функцию в моем наблюдателе для проверки ограничений пользователя.
Если клиенту не разрешено просматривать эту категорию, я хочу показать ему страницу ошибки Magento 404 по умолчанию. Вот где я застрял на данный момент.
Когда я смотрю 404 страницы контроллера: <Mage_Cms_IndexController>
это показывает мне это перенаправление в функцию «defaultIndex»:
$this->_forward('defaultIndex');
что это за функция:
public function defaultIndexAction()
{
$this->getResponse()->setHeader('HTTP/1.1','404 Not Found');
$this->getResponse()->setHeader('Status','404 File not found');
$this->loadLayout();
$this->renderLayout();
}
Но внутри моего наблюдателя я не могу назвать методы loadLayout
а также renderLayout
что вполне очевидно.
Я не хочу использовать перенаправление 301/302 на страницу 404, я хочу показать его непосредственно пользователю без перенаправления.
Что у меня сейчас есть:
Mage::app()->getFrontController()->getResponse()->setHeader('HTTP/1.1','404 Not Found');
Mage::app()->getFrontController()->getResponse()->setHeader('Status','404 File not found');
— Мне нужно сделать страницу 404 вместо макета каталога, но как мне это сделать?
Любые предложения будут высоко ценится.
ОТВЕТ:
Я не мог использовать ->_forward
сразу. Это должно быть инициализировано сначала.
Mage::app()->getFrontController()->getResponse()->setHeader('HTTP/1.1','404 Not Found');
Mage::app()->getFrontController()->getResponse()->setHeader('Status','404 File not found');
$request = Mage::app()->getRequest();
$request->initForward()
->setControllerName('indexController')
->setModuleName('Mage_Cms')
->setActionName('defaultNoRoute')
->setDispatched(false);
Надеюсь, это поможет кому-то 🙂
Я смог достичь этого, не возиться с объектом запроса, фу!
$exception = new Mage_Core_Controller_Varien_Exception("404 THIS REQUEST");
$exception->prepareForward('norouteAction');
throw $exception;
Вот удачно зашел в мои магазины 404 страницы 🙂
Причина в том, что он подхватывается catch
в Mage_Core_Controller_Varien_Action::dispatch
который обрабатывает форвард на norouteAction
public function dispatch($action)
{
try {
$actionMethodName = $this->getActionMethodName($action);
if (!method_exists($this, $actionMethodName)) {
$actionMethodName = 'norouteAction';
}
Varien_Profiler::start(self::PROFILER_KEY.'::predispatch');
$this->preDispatch();
Varien_Profiler::stop(self::PROFILER_KEY.'::predispatch');
if ($this->getRequest()->isDispatched()) {
/**
* preDispatch() didn't change the action, so we can continue
*/
if (!$this->getFlag('', self::FLAG_NO_DISPATCH)) {
$_profilerKey = self::PROFILER_KEY.'::'.$this->getFullActionName();
Varien_Profiler::start($_profilerKey);
$this->$actionMethodName();
Varien_Profiler::stop($_profilerKey);
Varien_Profiler::start(self::PROFILER_KEY.'::postdispatch');
$this->postDispatch();
Varien_Profiler::stop(self::PROFILER_KEY.'::postdispatch');
}
}
}
catch (Mage_Core_Controller_Varien_Exception $e) {
// set prepared flags
foreach ($e->getResultFlags() as $flagData) {
list($action, $flag, $value) = $flagData;
$this->setFlag($action, $flag, $value);
}
// call forward, redirect or an action
list($method, $parameters) = $e->getResultCallback();
switch ($method) {
case Mage_Core_Controller_Varien_Exception::RESULT_REDIRECT:
list($path, $arguments) = $parameters;
$this->_redirect($path, $arguments);
break;
case Mage_Core_Controller_Varien_Exception::RESULT_FORWARD:
list($action, $controller, $module, $params) = $parameters;
$this->_forward($action, $controller, $module, $params);
break;
default:
$actionMethodName = $this->getActionMethodName($method);
$this->getRequest()->setActionName($method);
$this->$actionMethodName($method);
break;
}
}
}