2

On my website I use the module PayPal Donations. When you donate money, the module get various info from PayPal using IPN callbacks. In a block, I show a list of people who have donated money. However, instead of using the username that is delivered by PayPal, I want to use the username from Drupal.

Unfortunately, my attempt to use the Drupal username does not work. Drupal doesn't write anything in the username field.

This is what I tried:

I've found the following code:

global $user; 
print $user->name;

This works beautifully and displays the username of the current logged in user.

So I wanted to use some of this code to replace the first name and last name (which comes from PayPal) with the Drupal username.

This code adds add the first and last name from PayPal to the database.

$entity->field_paypal_donator_name[LANGUAGE_NONE][0]['value'] = $_POST['first_name'] . " " . $_POST['last_name'];

In the top of the document, I've written global $user; and I've replaced

$entity->field_paypal_donator_name[LANGUAGE_NONE][0]['value'] = $_POST['first_name'] . " " . $_POST['last_name'];

with

$entity->field_paypal_donator_name[LANGUAGE_NONE][0]['value'] = $user->name;

The full code is the following one.

/**
 * @file
 * Handling the PayPal IPN callbacks
 */

/**
 * IPN callback function().
 */

  global $user;

function paypal_donations__ipn_callback() {
  $paypal_host = variable_get('paypal_donations_service_url', 'www.sandbox.paypal.com');
  header("Content-type: text/html");
  header("Expires: Wed, 29 Jan 1975 04:15:00 GMT");
  header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  header("Cache-Control: no-cache, must-revalidate");
  header("Pragma: no-cache");

  // Read the post from PayPal system and add 'cmd'.
  $req = 'cmd=_notify-validate';

  foreach ($_POST as $key => $value) {
    $value = urlencode(stripslashes($value));
    $req .= "&$key=$value";
  }

  $header = '';

  // Post back to PayPal system to validate.
  $header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
  $header .= "Host: " . $paypal_host . "\r\n";
  $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
  $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";

  $fp = fsockopen('ssl://' . $paypal_host, 443, $errno, $errstr, 30);

  if (!$fp) {
    watchdog('paypal', 'HTTP error');
  }
  else {
    fwrite($fp, $header . $req);
    watchdog('paypal', $header . $req);

    while (!feof($fp)) {
      $res = fgets($fp, 1024);
      if (strcmp($res, "VERIFIED") == 0) {
        global $user;

        if (!empty($_POST['txn_id'])) {

          if ($_POST['txn_type'] == 'web_accept') {
            $donation_type = 'single';
          }
          elseif ($_POST['txn_type'] == 'subscr_payment') {
            $donation_type = 'recurring';
          }

          $entity = new stdClass();
          $entity->field_paypal_transaction_id[LANGUAGE_NONE][0]['value'] = $_POST['txn_id'];
          $entity->field_paypal_donator_email[LANGUAGE_NONE][0]['value'] = $_POST['payer_email'];
          $entity->field_paypal_donations_amount[LANGUAGE_NONE][0]['value'] = $_POST['mc_gross'];
          $entity->field_paypal_donator_name[LANGUAGE_NONE][0]['value'] = $user->name; // my attempt to use the Drupal username instead of the PayPal first name.
          //$entity->field_paypal_donator_name[LANGUAGE_NONE][0]['value'] = $_POST['first_name'] . " " . $_POST['last_name']; // original line
          $entity->field_paypal_donator_country[LANGUAGE_NONE][0]['value'] = $_POST['address_country'];
          $entity->field_paypal_donations_type[LANGUAGE_NONE][0]['value'] = $donation_type;
          $entity->created = time();

          entity_save('paypal_donations_item', $entity);

          module_invoke_all("paypal_donations_made", $entity, $_POST);
          watchdog('paypal', 'Paypal payment received with transaction id @txn_id.', array('@txn_id' => $_POST['txn_id']), WATCHDOG_NOTICE);

          drupal_mail('paypal_donations', 'payer_confirmation', $_POST['payer_email'], user_preferred_language($user), array(
            'first_name' => $_POST['first_name'],
            'amount' => $_POST['mc_gross'],
            'donation_type' => $donation_type,
          ));

          drupal_mail('paypal_donations', 'admin_confirmation', $_POST['receiver_email'], user_preferred_language($user), array(
            'name' => $_POST['first_name'] . " " . $_POST['last_name'],
            'amount' => $_POST['mc_gross'],
          ));
          }
        }
      }
    fclose ($fp);
  }

  die();
}

(The altered line is 11 [added global $user;] and line 64 [where I try to use $user->name; to get the Drupal username].)

I'm no expert in PHP and this is my (poorly?) attempt to use the Drupal username instead of the first and last name coming from PayPal.

Can anyone tell my why it doesn't work?

  • In which file are you exactly using that code? Is it a module file, or what else? Is that file used by Drupal? – kiamlaluno Sep 13 '15 at 20:14
  • It's a module file called paypal_donations.ipn.inc – hjorslev Sep 13 '15 at 20:33
1

The global $user object is loaded based on the user's session, which is identified by looking up the value of their session cookie in (usually) the database. However, the PayPal IPN request is not made by the user: it comes directly from PayPal's servers to yours; so it doesn't contain the user's session cookie.

Not sure what's the best way to fix that. Ideally the module would record the user ID and associate it with the transaction ID, and look that up to find the correct user object. If it doesn't, you may want to file a bug report. Note that the module seems to expect the $user object to be correctly populated, as it attempts to use it for localisation of notification emails - which apparently isn't working either - so this probably really is a bug.

0

Have you tried declaring your variable from inside of your callback ?

function paypal_donations__ipn_callback() {
  global $user;
  $paypal_host = variable_get('paypal_donations_service_url','www.sandbox.paypal.com');
  header("Content-type: text/html");
}
  • Thanks for your suggestion, I just tried it. However, no luck. It still doens't get the username. – hjorslev Sep 13 '15 at 19:18
  • Remove the declaration from line 11, and keep the one on line 49. What's in the $user object ? Is it empty ? – p0832414 Sep 13 '15 at 19:50
  • Okay, I tried that without luck. The $user object should contain the username of the logged in user. If I use this code global $user; print $user->name; I can print the logged in username, so $user should contain the logged in username. What I don't understand is why it won't insert it into the database. – hjorslev Sep 13 '15 at 20:28
0

I think you might have missed adding those property to the custom Entity defined by paypal_donations module.

In order to add the field visit 'admin/structure/paypal_donations/manage/fields' and add a text field to hold value for user name and make sure machine name of the field should be same as you are using in the code, currently you are using machine name as 'field_paypal_donator_name'.

  • No luck here, unfortunately. I ensured that the new fields machine name matched the one in the code. But no matter what I call the field, shouldn't it be possible to write to this field anyway? I've tried making a variable containing the text anonymous by using $anonymous_post = 'Anonymous'; and then insert it to the database with $entity->field_paypal_donator_name[LANGUAGE_NONE][0]['value'] = $anonymous_post;. That worked flawless. – hjorslev Sep 13 '15 at 20:40
  • then I would suggest you to debug global $user object. If you have dblog module installed add watchdog('custom_debug', 'Debug Global User Object for @user_name, user object: !user', array('@' => $user->name, '!user' => '<pre>' . check_plain(print_r($user, TRUE)) . '</pre>'), WATCHDOG_ERROR); } then check under label custom_debug on 'admin/reports/dblog' page – arpitr Sep 13 '15 at 20:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.