2015-05-25 58 views
6

我創建了一個基於各種自定義規則重定向用戶的自定義模塊。我的問題是搞清楚在哪裏放置代碼。現在,我有:在Drupal中放置重定向邏輯的位置?

function mymodule_init() { 
    mymodule_redirect_now(); 
} 

的「mymodule_redirect_now」一般不會做在大多數情況下任何東西,但有時也可能導致「drupal_goto」被解僱了。這在實踐中可行,但會導致其他問題:

  1. 任何cron文件自動失敗。 (即cron.php)
  2. 單元測試失敗(如不能完成,因爲這個「轉到」被看作是一個失敗)

在哪裏將是把重定向邏輯這樣的最正確的地方,以避免失敗的單元測試和失敗的cron作業?

UPDATE

我試圖簡化這個問題,而通過把它歸結爲一個更簡單的問題。基本上,我想知道如何從執行以下代碼停止的cron:

function mymodule_init() { 
    mymodule_redirect_now(); 
} 

的Cron一直執行初始化任何東西,但在這種情況下,讓我們想象重定向具有以下邏輯:

function mymodule_redirect_now() 
{ 
    if (!$currentPathIsUS && $ipIsUS) { // lets pretend for now this always happens... 
     drupal_goto("us"); 
    } 
} 

基本上,如果使用的是US IP,並且當前路徑不是US路徑,則必須將它們重定向到/ us路徑。

問題是,如果我從命令行或瀏覽器運行cron,它在轉到任何其他函數之前碰到上述代碼,但由於「drupal_goto」,它實際上並沒有執行cron碼。

  1. 做上面我在做什麼是不好的做法?如果是這樣,那麼更好的選擇是什麼?
  2. 在這種情況下,如何停止執行init代碼的cron?

回答

4

hook_init()將始終在請求開始時運行,因爲您已經注意到了。

當您說「... ...根據各種自定義規則重定向用戶」。你什麼意思?用戶在提交包含某些內容的表單時是否被重定向?如果訪問一個(或一組)特定的URL,用戶是否被重定向?那裏有什麼條件?是Rules module

根據您定義的自定義規則,會有不同的答案。例如,如果規則與節點有關(加載,查看,編輯...),則必須使用hook_node_$op(),其中$op可以是例如「查看」,或「加載」或「提交」。舉個例子:

// Redirect user when submitting a node of type 'book' 
function mymodule_node_submit($node, $form, &$form_state) { 
    if ($node->type === 'book') { 
    drupal_goto("some/place/else"); 
    } 
} 

編輯

有兩個問題在這裏打球,因爲我看到它。一個是,在代碼中放置重定向邏輯,它在Drupal 7(和6)中確實沒有很好的簡短答案,這一切都取決於上下文。這可能是響應於形式裝載或提交形式或節點裝載觀看編輯(et.c.)或一些其它條件。這些條件要求重定向邏輯位於代碼中的不同位置。這就是我正在專注於回答上面的問題。

第二個問題,在閱讀您的澄清似乎是主要的罪魁禍首,是一個不同的類型。 Cron和單元測試不會擁有常規Web瀏覽器訪問者的所有信息。

您將必須檢測是否cron is running而不是在發生這種情況時重定向。正如你在上面的鏈接中看到的,cron創建一個臨時(匿名)用戶並且不會保存任何會話數據。這有一個打破許多克朗運行的趨勢。因爲drupal_exit() more or less kills everything

至於單元測試drupal_goto(),我在這裏不太確定,但我相信它因爲同樣的原因而中斷。你可以嘗試模擬一部分函數實際上不重定向。


而作爲一個側面說明,你可能要考慮使用hook_url_inbound_alter()more info)。它可能會或可能不會完全符合你想要做的... Look at what the Redirect module does,尤其是功能redirect_can_redirect()

+0

我使用init作爲我檢查的地方,並基於此,使用drupal_goto重定向用戶。問題是,這也打破了單元測試和cron的工作,因爲在某些情況下,它們觸發了規則。因此,在沒有爲特定路徑規定特定例外情況的情況下,我想知道,設置規則的一般方法是什麼?重定向依賴於第一次訪問服務器的用戶? – coderama

+0

沒有「通用方法」,除非我們正在談論規則模塊(它有自己的[文檔](https://www.drupal.org/documentation/modules),否則這種方式取決於您正在測試的內容/規則))。所有未在Drupal中登錄的訪問者都是同一個用戶(用戶ID 0),這意味着你不能在用戶對象上保存一個變量來檢查,但是我懷疑你可以用'user_cookie_save($ values)來解決這個問題。 '。根據你的實際情況,你將不得不使用不同的Drupal鉤子來實現你的重定向。 –

+0

我們對這個僞代碼有一個共同的理解:'if($ visitor_hits_server_first_time === true){then_only_do_redirect_once(); }'? –