Where to put redirect logic in Drupal?

I created a custom module that redirects the user based on various user rules. My problem is where to place the code. Right now I have:

function mymodule_init() { mymodule_redirect_now(); } 

"mymodule_redirect_now" usually does nothing in most cases, but sometimes this can cause drupal_goto to start. This works in practice, but causes other problems:

  • Any of the cron files do not work automatically either. (i.e. cron.php)
  • Unit test failures (since they cannot be completed because this "goto" is seen as a failure)

Where would be the most suitable place for redirection logic to avoid failed unit tests and cron job failures?

UPDATE

I tried to simplify this question by translating it into another simple question. Basically, I want to know how to stop cron from executing the following code:

 function mymodule_init() { mymodule_redirect_now(); } 

Cron always does something in init, but in this case, suppose the redirection has the following logic:

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

Basically, if the use has a US IP address and the current path is not an American path, it should redirect them to the / us path.

The problem is that if I run cron from the command line or from the browser, it gets into the above code before moving on to any other function, but because of "drupal_goto" it never executes cron code.

  • Is it a bad practice to do what I do above? and if so, which one is better?
  • How can I stop cron from executing initialization code in this case?
+6
source share
1 answer

hook_init() will always be triggered at the beginning of the request, as you noticed.

When you say "... redirects the user based on various user rules." what do you mean? Is the user redirected when submitting the form with some content? Is the user redirected when visiting (or dialing) specific URLs? What conditions exist? Is this a rule module ?

Depending on which user rules you have in mind, there will be different answers. For example, if the rules have something to do with nodes (loading, viewing, editing, ...), you should use hook_node_$op() , where $op can be, for example, “view” or “download” or “send " As an example:

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

Edit

There are two problems here that I see. One of them is that in the code to host the redirection logic, which in Drupal 7 (and 6) really does not have a good short answer, it all depends on the context. This may be in response to loading a form or submitting a form or loading or viewing a node or viewing or editing (et.c.) or a number of other conditions. These conditions require that the redirection logic be in different places in your code. This is what I focused on, answering above.

The second problem, which, reading your explanations, seems to be the main culprit, has a different type. The Cron and unit tests will not have all the information that a regular web browser visitor has visited.

You will need to determine if cron is working and not being redirected when this happens. As you can see in the link above, cron creates a temporary (anonymous) user and does not save session data. This tends to break many runs. Because drupal_exit () more or less kills everything .

As for unit testing drupal_goto() , I'm less sure here, but I think it breaks for the same reason. You can try to make fun of part of the function so that you don’t actually redirect.


And as a note, you might consider using hook_url_inbound_alter () ( more ). This may or may not be compatible with what you want to do ... See what the Redirect module does , especially the redirect_can_redirect() function.

+4
source

Source: https://habr.com/ru/post/987851/


All Articles