Drupal 7 Drupal中的重定向逻辑放在哪里?

Drupal 7 Drupal中的重定向逻辑放在哪里?,drupal-7,Drupal 7,我创建了一个自定义模块,根据各种自定义规则重定向用户。我的问题是找出代码的位置。现在,我有: function mymodule_init() { mymodule_redirect_now(); } “mymodule_redirect_now”通常在大多数情况下不起任何作用,但有时可能导致“drupal_goto”被触发。这在实践中起作用,但会导致其他问题: 任何cron文件也会自动失败。(即cron.php) 单元测试失败(例如,它们无法完成,因为这个“转到”被视为失败) 为了避

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

function mymodule_init() {
    mymodule_redirect_now();
}
“mymodule_redirect_now”通常在大多数情况下不起任何作用,但有时可能导致“drupal_goto”被触发。这在实践中起作用,但会导致其他问题:

  • 任何cron文件也会自动失败。(即cron.php)
  • 单元测试失败(例如,它们无法完成,因为这个“转到”被视为失败)
  • 为了避免单元测试失败和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代码

  • 做我上面所做的事情是不是很不好?如果是这样,还有什么更好的选择
  • 在这种情况下,如何阻止cron执行init代码
  • 正如您所注意到的,
    hook_init()
    将始终在请求开始时运行

    当你说“…根据各种自定义规则重定向用户”是什么意思?提交包含某些内容的表单时是否重定向用户?如果用户访问一个(或一组)特定的URL,是否会被重定向?有什么条件?这是最重要的吗

    根据您所指的自定义规则,将有不同的答案。例如,如果规则与节点有关(加载、查看、编辑等),则必须使用
    hook\u node\uuu$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");
      }
    }
    
    编辑

    在我看来,这里有两个问题。一个是在代码中放置重定向逻辑的地方,Drupal7(和6)中的重定向逻辑并没有一个很好的简短答案,这完全取决于上下文。它可能是对表单加载、表单提交、节点加载、查看或编辑(et.c.)或许多其他条件的响应。这些条件要求重定向逻辑位于代码中的不同位置。这就是我在上面集中回答的问题

    第二个问题是另一种类型,在阅读您的澄清后,它似乎是主要的罪魁祸首。Cron和单元测试不会拥有普通web浏览器访问者所拥有的所有信息

    如果发生这种情况,您必须检测是否重定向,而不是重定向。正如您在上面的链接中看到的,cron创建了一个临时(匿名)用户,并且不会保存任何会话数据。这有可能破坏许多cron运行。因为

    至于单元测试
    drupal_goto()
    ,我在这里不太确定,但我相信它会因为同样的原因中断。您可以尝试模拟函数的一部分,使其实际上不重定向



    作为一个旁注,您可能需要考虑使用()。它可能与您想要执行的操作完全兼容,也可能与您不兼容…,尤其是函数

    redirect\u can\u redirect()

    我使用init作为检查的位置,并基于此,使用drupal\u goto重定向用户。问题是,这也破坏了单元测试和cron作业,因为在某些情况下它们触发了规则。因此,在不对某些路径进行特定例外的情况下,我想知道,设置规则重定向依赖于用户第一次访问服务器的用户的一般方法是什么?没有“一般方法”,该方法取决于您测试的对象,除非我们讨论的是规则模块(它有自己的). 所有未登录Drupal的访问者都是同一个用户(用户ID为0),这意味着您无法在用户对象上保存一个变量以进行检查,但我怀疑您可以使用
    user\u cookie\u save($value)
    解决此问题。根据您的实际情况,您必须使用不同的Drupal钩子来实现重定向。我们对这个伪代码是否有共同的理解:
    如果($visitor\u hits\u server\u first\u time===true){然后只做一次重定向()}
    ?几乎正确。它每次都检查。但对于我的问题来说,这几乎是无关紧要的。我试图理解如果我使用drupal_goto和drupal_exit,将不会破坏单元测试的逻辑放在哪里。init函数也由cron调用,因此在其中包含重定向会中断cron。那么我该如何处理这个案子呢?如果($user_hits_server&&$user_requires_redirect_due_due_some_condition){redirect_user()}更正确-->基本上,我检查用户的IP地址,检查区域设置和其他一些内容,并根据这些自定义规则重定向用户。但是我不知道把这个不会破坏单元测试或cron的自定义逻辑放在哪里?