2015-05-25 20 views
6

Utworzono niestandardowy moduł, który przekierowuje użytkownika na podstawie różnych reguł niestandardowych. Mój problem polega na zastanawianiu się, gdzie umieścić kod. W tej chwili mam:Gdzie umieścić logikę przekierowania w Drupal?

function mymodule_init() { 
    mymodule_redirect_now(); 
} 

W „mymodule_redirect_now” generalnie nic nie robić w większości przypadków, ale czasami może to spowodować „drupal_goto” wyrzuceniu off. Działa to w praktyce, ale powoduje inne problemy:

  1. Dowolny z plików cron automatycznie również zawiedzie. (Tj cron.php)
  2. testy jednostkowe nie (jak w nie można zakończyć, ponieważ ta „goto” jest postrzegany jako niepowodzenie)

Gdzie byłoby najbardziej właściwe miejsce, aby umieścić przekierowanie logikę tak , aby uniknąć niepowodzenia testów jednostkowych i nieudanych zadań crona?

UPDATE

starałem się uprościć to pytanie, by raczej obniżając ją do jeszcze jednego prostego pytania. Zasadniczo, chcę wiedzieć, jak zatrzymać crona od wykonywania następujący kod:

function mymodule_init() { 
    mymodule_redirect_now(); 
} 

Cron zawsze wykonuje coś w init, ale w tym przypadku, wyobraźmy sobie, że przekierowanie ma następującą logiką:

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

Zasadniczo, jeśli użycie ma amerykański adres IP, a obecna ścieżka nie jest ścieżką USA, musi przekierować je do ścieżki/us.

Problem polega na tym, że jeśli uruchomię crona z wiersza poleceń lub przeglądarki, uderzy w powyższy kod przed przejściem do jakiejkolwiek innej funkcji, ale z powodu "drupal_goto", to faktycznie nigdy nie wykonuje crona kod.

  1. Czy to jest zła praktyka robić to, co robię powyżej? a jeśli tak, to jaka jest lepsza alternatywa?
  2. W jaki sposób mogę zatrzymać cron przed uruchomieniem kodu init?

Odpowiedz

4

hook_init() będzie zawsze uruchamiany na początku żądania, jak już zauważyłeś.

Kiedy mówisz "... przekierowuje użytkownika na podstawie różnych reguł niestandardowych." co masz na myśli? Czy użytkownik jest przekierowywany podczas przesyłania formularza z pewną zawartością? Czy użytkownik jest przekierowywany podczas odwiedzania (lub zestawu) określonych adresów URL? Jakie są warunki? Czy to jest Rules module?

W zależności od reguł niestandardowych masz na myśli różne odpowiedzi. Na przykład, jeśli reguły mają coś wspólnego z węzłami (ładowanie, przeglądanie, edytowanie, ...), musisz użyć hook_node_$op() gdzie $op może być np. "zobacz" lub "załaduj" lub "prześlij". Jako przykład:

// 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"); 
    } 
} 

Edycja

Istnieją dwie kwestie w grę tutaj jak ja to widzę.Jednym z nich jest , gdzie w kodzie umieszcza się logikę przekierowania, która w Drupalu 7 (i 6) tak naprawdę nie ma dobrej krótkiej odpowiedzi, wszystko zależy od kontekstu. To może być w odpowiedzi na formularz załadunku lub postaci składającego lub węzła załadunku lub oglądania lub edycji (et.c.) lub szereg innych warunków. Te warunki wymagają, aby logika przekierowania znajdowała się w różnych miejscach kodu. Właśnie to koncentrowałem na odpowiedziach powyżej.

Drugi numer, który po przeczytaniu twoich wyjaśnień wydaje się głównym winowajcą, jest innego rodzaju. Cron i testy jednostkowe nie będą miały wszystkich informacji, które posiada zwykły użytkownik przeglądarki.

Będziesz musiał wykryć, czy cron is running, a nie przekierować, gdy tak się stanie. Jak widzisz w linku powyżej cron tworzy tymczasowego (anonimowego) użytkownika i nie zapisuje żadnych danych sesji. Ma to tendencję do łamania wielu przebiegów crona. Ponieważ drupal_exit() more or less kills everything.

Co do testów jednostkowych drupal_goto(), jestem mniej pewny tutaj, ale uważam, że łamie się z tego samego powodu. Możesz spróbować wyszydzić część funkcji, aby nie przekierować.


I jako marginesie warto rozważyć użycie hook_url_inbound_alter() (more info). Może być lub może nie być zgodny z dokładnie tym, co chcesz zrobić ... Look at what the Redirect module does, zwłaszcza funkcja redirect_can_redirect().

+0

Używam init jako miejsca, z którego robię kontrole, i na tej podstawie przekierowuję użytkownika za pomocą drupal_goto. Problem polega na tym, że powoduje to również przerwanie testów jednostkowych i zadań cron, ponieważ w niektórych przypadkach uruchamiają one reguły. Więc bez robienia konkretnych wyjątków dla pewnych ścieżek, chciałbym wiedzieć, jaki jest ogólny sposób radzenia sobie z ustawianiem reguł przekierowujących użytkownika, który polega na tym, że po raz pierwszy trafili na serwer? – coderama

+0

Nie ma "ogólnej drogi", droga jest zależna od tego, z czym testujesz, chyba że mówimy o module Reguły (który ma swoją własną dokumentację) (https://www.drupal.org/documentation/modules/rules)). Wszyscy odwiedzający, którzy nie są zalogowani w Drupal, są tym samym użytkownikiem (User ID 0), co oznacza, że ​​nie można zapisać zmiennej na obiekcie użytkownika, aby sprawdzić, ale podejrzewam, że możesz rozwiązać to za pomocą 'user_cookie_save ($ values) '. W zależności od twoich rzeczywistych warunków będziesz musiał użyć różnych haków Drupala, aby osiągnąć swoje przekierowanie. –

+0

Czy mamy do czynienia z powszechnym zrozumieniem tego pseudokodu: 'if ($ visitor_hits_server_first_time === true) {then_only_do_redirect_once(); } '? –