我创建了一个自定义模块,可根据各种自定义规则重定向用户。我的问题是找出放置代码的位置。现在,我有:
function mymodule_init() {
mymodule_redirect_now();
}
" mymodule_redirect_now"在大多数情况下通常不做任何事情,但有时可能会导致" drupal_goto"被解雇了。这在实践中有效,但会导致其他问题:
在哪里放置像这样的重定向逻辑的最正确的地方,以避免单元测试失败和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代码。
答案 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
。