在Drupal中放置重定向逻辑的位置?

时间:2015-05-25 07:52:25

标签: drupal-7

我创建了一个自定义模块,可根据各种自定义规则重定向用户。我的问题是找出放置代码的位置。现在,我有:

function mymodule_init() {
    mymodule_redirect_now();
}

" mymodule_redirect_now"在大多数情况下通常不做任何事情,但有时可能会导致" drupal_goto"被解雇了。这在实践中有效,但会导致其他问题:

  1. 任何cron文件也会自动失败。 (即cron.php)
  2. 单元测试失败(因为他们无法完成,因为这" goto"被视为失败)
  3. 在哪里放置像这样的重定向逻辑的最正确的地方,以避免单元测试失败和cron作业失败?

    更新

    我试图简化这个问题,而不是把它归结为一个更简单的问题。基本上,我想知道如何阻止cron执行以下代码:

    function mymodule_init() {
        mymodule_redirect_now();
    }
    

    Cron总是在init中执行任何操作,但在这种情况下,让我们想象重定向具有以下逻辑:

    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. 在这种情况下如何阻止cron执行init代码?

1 个答案:

答案 0 :(得分: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_goto()

修改

我看到这里有两个问题在起作用。一个是在代码中放置重定向逻辑,在Drupal 7(和6)中没有真正的简短答案,这一切都取决于上下文。它可以响应表单加载或表单提交或节点加载查看编辑(et.c。)或许多其他条件。这些条件需要重定向逻辑位于代码中的不同位置。这就是我上面专注于回答的问题。

第二个问题,在阅读你的澄清时似乎是罪魁祸首,是另一种类型。 Cron和单元测试不具备常规Web浏览器访问者的所有信息。

当发生这种情况时,您必须检测cron is running是否重定向。正如您在上面的链接中看到的那样,cron创建了一个临时(匿名)用户并且不会保存任何会话数据。这有打破许多cron运行的趋势。因为drupal_exit() more or less kills everything

至于单元测试redirect_can_redirect(),我在这里不太确定,但我认为它因同样的原因而中断。您可以尝试模拟部分功能实际上不重定向。

作为旁注,您可能需要考虑使用hook_url_inbound_alter()more info)。它可能与您想要做的事情完全兼容...... Look at what the Redirect module does,尤其是函数F