2013-10-08 20 views
2

我有一個擴展ErrorPage和ErrorPage_Controller的「智能錯誤頁面」類,基本上它做了什麼a)檢測它是否是404,然後b)試圖找到潛在的重定向頁面基於一些自定義搜索邏輯。如果該頁面在其他地方找到,用戶將自動重定向到該位置。我知道SilverStripe的基本版本已經基於重命名/移動的SiteTree元素,但是這是更先進的。在擴展ErrorPage [_Controller]中用SilverStripe 3.1覆蓋404頭部

無論如何,從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未找到」 以及「位置:[URL]」頭 - 但它似乎是不可能重寫404個狀態。

任何想法如何我可以恢復預期的「HTTP/1.1 302找到」頭? PS:我試過$ this-> getResponse() - > setStatusCode(302)等沒有運氣。

回答

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; 
    } 
    } 
} 
+0

學習新的東西每一天。 +1 – schellmax

+0

謝謝 - 完美無缺! – Axllent

+1

如何使它301重定向: $ response-> getResponse() - >重定向('contact-us',301); –