使用SilverStripe 3.1覆盖扩展的ErrorPage [_Controller]中的404标头

时间:2013-10-08 21:22:15

标签: silverstripe

我有一个“智能错误页面”类,它扩展了ErrorPage和ErrorPage_Controller,基本上是它做了什么a)检测它是否是404,然后b)尝试根据一些自定义搜索逻辑找到潜在的重定向页面。如果在其他位置找到该页面,则会自动将用户重定向到该位置。我知道SilverStripe的基本版本已基于重命名/移动的SiteTree元素,但这更先进。

无论如何,从3.1开始,似乎无法覆盖发送的404标头(虽然这适用于3.0)。

class IntelligentErrorPage_Controller extends ErrorPage_Controller {
  public function init() {
    parent::init();
    $errorcode = $this->failover->ErrorCode ? $this->failover->ErrorCode : 404;
    if ($errorcode == 404) {
       ... some search logic ...
       if ($RedirectSiteTreePage)
          return $this->redirect($RedirectSiteTreePage->Link());
    }
  }
}

从3.1开始,上面返回“HTTP / 1.1 404 Not Found”以及“Location:[url]”标题 - 但是似乎无法覆盖404状态。< / p>

知道如何恢复预期的“HTTP / 1.1 302 Found”标题吗?

PS:我已尝试过$ this-&gt; getResponse() - &gt; setStatusCode(302)等,也没有运气。

1 个答案:

答案 0 :(得分:4)

由ModelAsController调用init()函数,并且由于此类无法为随机url段找到合适的旧页面,因此在构建自己的响应后重建http响应,因此会覆盖302 404.这发生在ModelAsController的第130行。规避这种方法的一种方法是改变方法并抛出异常,这将阻止对getNestedController的调用。很简单,有一个名为SS_HTTPResponse_Exception的异常。

此代码段适合我(使用302重定向到联系我们页面):

<?php

class IntelligentErrorPage extends ErrorPage {

}
class IntelligentErrorPage_Controller extends ErrorPage_Controller {
  public function init() {
    parent::init();
    $errorcode = $this->failover->ErrorCode ? $this->failover->ErrorCode : 404;
    if ($errorcode == 404) {
       //... some search logic ...
        $response = new SS_HTTPResponse_Exception();
        $response->getResponse()->redirect('contact-us');
        $this->popCurrent();
        throw $response;
    }
  }
}