我在Drupal 6.1.3中对hook_cron
的以下实现有疑问。
下面的脚本完全按预期运行:它向新成员发送欢迎信,并更新其个人资料中的隐藏字段以指定该信件已发送。信中没有错误,所有新成员都被记录等等。
问题是最后一行 - 更新配置文件 - 在服务器上的'真正'cron调用Drupal cron时似乎不起作用。
当我手动运行cron(例如通过/admin/reports/status/run-cron
)时,配置文件字段会按预期更新。
有关可能导致此问题的建议吗?
(注意,因为有人会建议:成员通过Drupal之外的方式加入,并且每晚上传到Drupal,所以Drupal的内置欢迎信不会起作用(我认为)。)
<?php
function foo_cron() {
// Find users who have not received the new member letter,
// and send them a welcome email
// Get users who have not recd a message, as per the profile value setting
$pending_count_sql = "SELECT COUNT(*) FROM {profile_values} v
WHERE (v.value = 0) AND (v.fid = 7)"; //fid 7 is the profile field for profile_intro_email_sent
if (db_result(db_query($pending_count_sql))) {
// Load the message template, since we
// know we have users to feed into it.
$email_template_file = "/home/foo/public_html/drupal/" .
drupal_get_path('module', 'foo') .
"/emails/foo-new-member-email-template.txt";
$email_template_data = file_get_contents($email_template_file);
fclose($email_template_fh);
//We'll just pull the uid, since we have to run user_load anyway
$query = "SELECT v.uid FROM {profile_values} v
WHERE (v.value = 0) AND (v.fid = 7)";
$result = db_query(($query));
// Loop through the uids, loading profiles so as to access string replacement variables
while ($item = db_fetch_object($result)) {
$new_member = user_load($item->uid);
$translation_key = array(
// ... code that generates the string replacement array ...
);
// Compose the email component of the message, and send to user
$email_text = t($email_template_data, $translation_key);
$language = user_preferred_language($new_member); // use member's language preference
$params['subject'] = 'New Member Benefits - Welcome to FOO!';
$params['content-type'] = 'text/plain; charset=UTF-8; format=flowed;';
$params['content'] = $email_text;
drupal_mail('foo', 'welcome_letter', $new_member->mail, $language, $params, 'webmaster@foo.org');
// Mark the user's profile to indicate that the message was sent
$change = array(
// Rebuild all of the profile fields in this category,
// since they'll be deleted otherwise
'profile_first_name' => $new_member->profile_first_name,
'profile_last_name' => $new_member->profile_last_name,
'profile_intro_email_sent' => 1);
profile_save_profile($change, $new_member, "Membership Data");
}
}
}
答案 0 :(得分:2)
不是随意猜测......但是接近......
当“真正的”cron运行代码时,它会以特定用户身份运行它。
同样,当您手动运行Drupal cron代码时,代码也将作为特定用户运行。
我怀疑两个用户是不同的,具有不同的权限,这导致失败。
cron作业的用户是否有权写入数据库,还是只读?
cron作业是否生成了任何日志文件?
更新:上面的'用户',我指的是主机服务器上的用户帐户,而不是Drupal帐户。例如,在我用于测试Drupal更改的沙箱系统上,Apache在noone
帐户下运行。
答案 1 :(得分:2)
是的,我确认drupal cron用户个人资料是“匿名的”,所以你必须为“匿名”用户添加权限de manager用户,这在安全方面不是很好..
答案 2 :(得分:2)
安全切换用户 http://api.drupal.org/api/function/session_save_session/6
<?php
global $user;
$original_user = $user;
session_save_session(FALSE); // D7: use drupal_save_session(FALSE);
$user = user_load(array('uid' => 1)); // D7: use user_load(1);
// Take your action here where you pretend to be the user with UID = 1 (typically the admin user on a site)
// If your code fails, it's not a problem because the session will not be saved
$user = $original_user;
session_save_session(TRUE); // // D7: use drupal_save_session(TRUE);
// From here on the $user is back to normal so it's OK for the session to be saved
?>
从这里采取: drupal dot org / node / 218104
答案 3 :(得分:0)
profile_save_profile我不会检查权限,或者我可以看到'全球$ user'所以我不知道这是否是真正的问题。
$new_member = user_load($item->uid);
这看起来不对user_load应该使用数组而不是uid(除非你使用的是Drupal7),但是如果这不起作用,其余的代码也会失败。