Drupal的profile_save_profile在hook_cron中不起作用,当由服务器的cron运行时

时间:2009-08-05 19:42:49

标签: php drupal

我在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");
        }
    }
}

4 个答案:

答案 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),但是如果这不起作用,其余的代码也会失败。