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

cod*_*ama 6 drupal-7

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

function mymodule_init() {
    mymodule_redirect_now();
}
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,"mymodule_redirect_now"通常不会执行任何操作,但有时可能会导致"drupal_goto"被触发.这在实践中有效,但会导致其他问题:

  1. 任何cron文件也会自动失败.(即cron.php)
  2. 单元测试失败(因为它们无法完成,因为这个"goto"被视为失败)

哪个是最正确的放置这样的重定向逻辑的地方,以避免单元测试失败和cron作业失败?

UPDATE

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

function mymodule_init() {
    mymodule_redirect_now();
}
Run Code Online (Sandbox Code Playgroud)

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

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

基本上,如果使用具有US IP且当前路径不是US路径,则必须将它们重定向到/ us路径.

问题是,如果我从命令行或浏览器运行cron,它会在转到任何其他函数之前点击上面的代码,但由于"drupal_goto",它实际上并不执行cron代码.

  1. 做我上面做的事情是不好的做法吗?如果是的话,更好的选择是什么?
  2. 在这种情况下,如何阻止cron执行init代码?

Nik*_*erg 4

hook_init()正如您所注意到的,它将始终在请求开始时运行。

\n

当您说“\xe2\x80\xa6 根据各种自定义规则重定向用户”时。你是什​​么意思?用户在提交包含某些内容的表单时是否被重定向?如果访问一个(或一组)特定 URL,用户是否会被重定向?有什么条件呢?是规则模块吗?

\n

根据您所指的自定义规则,会有不同的答案。例如,如果规则与节点有关(加载、查看、编辑、\xe2\x80\xa6),则必须使用hook_node_$op()where$op可以是“查看”、“加载”或“提交”。举个例子:

\n
// Redirect user when submitting a node of type \'book\'\nfunction mymodule_node_submit($node, $form, &$form_state) {\n  if ($node->type === \'book\') {\n    drupal_goto("some/place/else");\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

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

\n

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

\n

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

\n

作为旁注,您可能需要考虑使用hook_url_inbound_alter()更多信息)。它可能与您想要做的事情完全兼容,也可能不兼容。看看Redirect模块做了什么,特别是函数redirect_can_redirect()

\n