2009-08-05 2 views
0

Ich habe ein Problem mit der folgenden Implementierung von hook_cron in Drupal 6.1.3.Drupal's profile_save_profile Funktioniert nicht in hook_cron, wenn vom cron des Servers ausgeführt

Das folgende Skript läuft genau wie erwartet: Es sendet einen Willkommensbrief an neue Mitglieder und aktualisiert ein verstecktes Feld in seinem Profil, um anzugeben, dass der Brief gesendet wurde. Es gibt keine Fehler in dem Brief, alle neuen Mitglieder werden berücksichtigt, etc.

Das Problem ist, dass die letzte Zeile - Aktualisieren des Profils - scheint nicht zu funktionieren, wenn Drupal Cron von der 'real aufgerufen wird 'Cron auf dem Server.

Wenn ich Cron manuell (wie über /admin/reports/status/run-cron) ausführen, werden die Profilfelder wie erwartet aktualisiert.

Irgendwelche Vorschläge, was könnte dies verursachen?

(Beachten Sie, da es jemand vorschlagen wird: Mitglieder mittels außerhalb von Drupal verbinden, und werden jede Nacht zu Drupal hochgeladen, so Drupal-internes Begrüßungsschreiben wird nicht funktionieren (ich glaube).)

<?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, '[email protected]'); 
      // 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"); 
     } 
    } 
} 

Antwort

2

sicher Benutzer von hier 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 
?> 

genommen wechseln: drupal dot org/node/218104

+0

Perfekt ... danke! – anschauung

+0

Danke! Ich habe die gleiche Frage. – farzan

2

Nicht ganz zufällig raten ... aber nahe ...

Wenn "real" Cron Code ausgeführt wird, wird es als ein bestimmter Benutzer ausgeführt.

Wenn Sie den Drupal Cron-Code manuell ausführen, wird der Code auch als ein bestimmter Benutzer ausgeführt.

Mein Verdacht ist, dass die beiden Benutzer unterschiedlich sind, mit unterschiedlichen Berechtigungen, und das verursacht den Fehler.

Hat der Benutzer des Cron-Jobs Zugriff auf die Datenbank schreiben oder nur lesen?

Gibt es Protokolldateien, die vom Cron-Job generiert wurden?

Update: Von 'Benutzer' oben, ich beziehe mich auf die Benutzerkonten auf dem Host-Server, nicht Drupal-Konten. Auf einem Sandbox-System, das ich zum Testen von Drupal-Änderungen verwende, läuft Apache beispielsweise unter dem Account noone.

+0

Danke für die Antwort - Datenbankberechtigungen sind nicht das Problem, aber ich vermute, dass Sie können Teil der Lösung sein.Ich stelle eine weitere Frage darüber, wie man die Einschränkung, die @ Houssem nennt, umgehen kann. – anschauung

2

yes i bestätigen Drupal cron Benutzerprofil ist „anonymous“, so dass Sie die Erlaubnis de-Manager Benutzer für die „anonyme“ Benutzer hinzufügen müssen, die in der Bezeichnung der Sicherheit ist nicht sehr gut ..

+0

Oh, Schatz. Auf der Grundlage Ihrer Antwort schien ich zu googeln, und das scheint es zu erklären. Danke für die Einsicht. Ich werde eine andere Frage auf dem besten Weg, um dieses Problem zu umgehen. – anschauung

0

profile_save_profile dosn't überprüfe auf Berechtigungen oder, soweit ich das sehen kann, 'global $ user', also weiß ich nicht, ob das das eigentliche Problem ist.

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

Das sieht falsch user_load einen Array keine uid nehmen soll (es sei denn, Sie Drupal7 verwenden), aber wenn das nicht der Rest des Codes funktioniert auch fehlschlagen würde.

+1

user_load kann UIDs anstelle eines Arrays verwenden, wenn Sie die UID des Benutzers bereits kennen. Das Array wird verwendet, um Benutzer auf andere Weise zu finden, wenn Sie keinen einfachen Zugriff auf die UID haben. Notieren Sie Zeile 6 in der Quelle für user_load: if (is_numeric ($ array)) {$ array = array ('uid' => $ array);} – anschauung

+0

Das bringt mir bei, sich die Dokumente und nicht den Code anzusehen. –

Verwandte Themen