Profile_save_profile Drupal не работает в hook_cron, когда запускается cron сервера - PullRequest
0 голосов
/ 05 августа 2009

У меня проблема со следующей реализацией hook_cron в Drupal 6.1.3.

Сценарий, приведенный ниже, работает точно так, как ожидается: он отправляет приветственное письмо новым участникам и обновляет скрытое поле в их профиле, чтобы указать, что письмо было отправлено. В письме нет ошибок, учтены все новые участники и т. Д.

Проблема в том, что последняя строка - обновление профиля - не работает, когда 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 ]

2 голосов
/ 19 марта 2010

Для безопасного переключения пользователей 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 точка орг / узел / 218104

2 голосов
/ 06 августа 2009

да, я подтверждаю, что профиль пользователя drupal cron является «анонимным», поэтому вы должны добавить права пользователя de manager для «анонимного» пользователя, что не очень хорошо с точки зрения безопасности.

2 голосов
/ 06 августа 2009

Не совсем случайное предположение ... но близко ...

Когда «реальный» cron запускает код, он запускает его как конкретного пользователя.

Точно так же, когда вы запускаете код Cron Drupal вручную, код также будет работать от имени конкретного пользователя.

Я подозреваю, что два пользователя разные, с разными разрешениями, и это вызывает сбой.

Имеет ли пользователь задания cron доступ для записи в базу данных или только для чтения?

Существуют ли какие-либо файлы журналов, сгенерированные заданием cron?

Обновление : под «пользователем» выше я имею в виду учетные записи пользователей на хост-сервере, а не учетные записи Drupal. Например, в тестовой системе, которую я использую для тестирования изменений в Drupal, Apache работает под учетной записью noone.

0 голосов
/ 07 августа 2009

profile_save_profile не проверяет разрешения или, насколько я вижу, действительно 'global $ user', поэтому я не знаю, является ли это реальной проблемой.

 $new_member = user_load($item->uid);

Это выглядит неправильно user_load должен принимать массив, а не uid (если только вы не используете Drupal7), но если это не сработает, остальная часть кода тоже не будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...