Hi,
I must be a real dolt, I found the super great for my needs module Pay-Per-Node, installed the ecommerce module, installed the Pay-Per-Node module, created a fantastic new pay-per-node item, set up paypal, and bought myself a spiffy new ability to create one page with a test account.

But... It didn't work, I wasn't allowed to create the page! I have the purchase history, but no authorization to create the page.
UNTIL!!! I log out... the anonymous user has one pay-per-node credit!

DOH! I tried a few more tests and have poked all around the settings here, but I'm clearly missing something obvious, as the credits keep getting assigned to nobody instead of the logged in user.

Any idea's?

many thanks,
DS

Comments

Rolf van de Krol’s picture

Try to replace paypernode_nodeapi in your paypernode.module file with this one. The difference is, that it reads $node->name instead of $node->uid, because at the time of inserting $node->uid is not set. Or at least, as far as i know, not for users with administer nodes permissions.

/**
 * Implementation of hook_nodeapi()
 */
function paypernode_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
  // DEBUG:
  /*
  if($op == 'insert') {
    print $op;
    var_dump($node);
  }
  */
  if($op == 'insert' && isset($node->paypernode)){
    // Decrease user balance for this node type
    // Get uid from node
    $user = user_load(array('name' => $node->name));
    paypernode_user_update($user->uid, $node->type, 0, 1);
    $typename = node_get_name($node);
    $left = paypernode_user_can_create($node->type, TRUE); // Last argument to refresh cache
    // Log event and display additional user message.
    watchdog('paypernode', t('Pay-per-node %typename node created. %number nodes left.', array('%number' => $left, '%typename' => $typename)));
    drupal_set_message(t("The node has been charged into the pay-per-node system. You have %number nodes of type %typename left.", array('%number' => $left, '%typename' => $typename)));
  }
}

Sorry that it isn't a official patch. diff doesn't seem to do what it should do on my computer.

Edit: Finally got diff to doing it's job. Here is the patch:

--- paypernode.module	2006-12-10 20:04:20.000000000 +0100
+++ new/paypernode.module	2007-01-29 23:06:24.921875000 +0100
@@ -272,7 +272,8 @@ function paypernode_nodeapi(&$node, $op,
   if($op == 'insert' && isset($node->paypernode)){
     // Decrease user balance for this node type
     // Get uid from node
-    paypernode_user_update($node->uid, $node->type, 0, 1);
+    $user = user_load(array('name' => $node->name));
+    paypernode_user_update($user->uid, $node->type, 0, 1);
     $typename = node_get_name($node);
     $left = paypernode_user_can_create($node->type, TRUE); // Last argument to refresh cache
     // Log event and display additional user message.
docStone’s picture

I so appreciate the patch, learned something new (how to apply patches) but no dice... Same result.
I've got two different test pay per node items set up, and I'm using paypal sandbox accounts, the transactions are going through no problems, and the node credit's are getting added, but in every case, before and after I applied the patch, the credits are only visible when no one is logged in.

Sigh, this is exactly the function that I need, but I can't get it to work...
Appreciate your help though,
-Ds

docStone’s picture

I'm looking at the module, and I think here is where the problem lies for sure:

 case 'on payment completion':
      if($node->node_type && $node->qty && $node->node_qtty) {
        global $user;
        $number = $node->qty * $node->node_qtty;
        paypernode_user_update($user->uid, $node->node_type, $number);
        drupal_set_message(t('You can create now %number nodes of type %node_type', array('%number' => $node->qty, '%node_type' => node_get_name($node->node_type))));
      } else {
        // Error condition
        drupal_set_message(t("No new node types added. Please contact site administrator"));
      }


Before I payed any attention to what it's doing I tried your code to get the user:

$user = user_load(array('name' => $node->name));

of course it adds the balance to my admin account..
But, that's what I needed to figure out what the problem is.

Clearly, we just need the uid of the currently logged in user.
Searching the forums I found this thread: http://drupal.org/node/80012
which contains the following tidbits:

AFAIK, I should be able to use $user->uid which should return the uid. Calling that returns nothing. Or Null, I'm not sure, but I know its not returning the uid of the current user. Trying to do a print_r($user) also returns nothing, so it seems like the $user global is empty. If I explicitly declare Global $user; in the php, I then get the user login block which is normally not there.

AH HA! Now we know why the credits are getting assigned to the anonymous user.

In the same thread is a single reply (no one had an answer) it says:

This is happening to me in an ecommerce module, and I need to know how to get the user context back since the user is still logged in.

So it seems that this is a problem perhaps with the ecommerce module, I wonder if this other fellow is leaving the site to head over to paypal for the billing. Could it be that the user context is lost since the IPN ping happens from paypal???

We're getting somewhere I think...

docStone’s picture

From my issue report:

I now have this functioning...
the problem is that the global user is not available to the IPN page, since it's called by paypal not an actual user. I kind of suspected that.

With a little poking around at similar problems on the forums I finally got the one piece of help I needed to fix this...

in the on payment completion I needed to grab the UID of the user making the purchase another way... here's what I have:

$txnid = substr($_POST['item_number'],6);
$tmpResult = db_query('SELECT uid FROM {ec_transaction} WHERE txnid ='. $txnid);       
$myUID = db_result($tmpResult);

then, you have to make a minor change to the call to paypernode, see my changed line below:

        paypernode_user_update($myUID, $node->node_type, $number);

This is NOT an elegant solution, it's just one that works.

Hope it's helpful to someone else in the future.

If there is a smarter way to get the single value back from the database by the way, I would love to know, that's really clunky, I had expected to be able to write something like:

$myUID=db_result('Select UID from {ec_transaction} where txnid=$txnid'); 

but that didn't fly, I was forced to get the result set (of one item!) and then grab the value out of it.
It's probably not a big deal, but confused me for a few minutes.

EDIT: --- A bit later now, and I've found that the when content is created, it doesn't get deducted properly!
this fix is simple, you need to add global $user; (it works here!) so the proper user gets the deduction done in the function: paypernode_nodeapi

should look like this:

function paypernode_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
  // DEBUG:
  /* 
  if($op == 'insert') {
    print $op;
    var_dump($node);
  }
  */
  if($op == 'insert' && isset($node->paypernode)){
    // Decrease user balance for this node type
    // Get uid from node
   //actually, getting the uid from the node doesn't work for me, but adding the next line fixes it...
    global $user;
    paypernode_user_update($user->uid, $node->type, 0, 1);
    $typename = node_get_name($node);
    $left = paypernode_user_can_create($node->type, TRUE); // Last argument to refresh cache
    // Log event and display additional user message.
    watchdog('paypernode', t('Pay-per-node %typename node created. %number nodes left.', array('%number' => $left, '%typename' => $typename)));
    drupal_set_message(t("The node has been charged into the pay-per-node system. You have %number nodes of type %typename left.", array('%number' => $left, '%typename' => $typename)));
  }
}

Thanks for all the help, I'm glad this is working now.
-doc

johntymatts’s picture

Could you go through a bit more step by step with find and replace for those of us who are dum and struggling?

Adam Messinger’s picture

This seems like the kind of thing that should be filed as a bug report on the project's tracking page. That would get the module author's attention on the matter, and maybe get some testing going by other Pay-Per-Node users that monitor the project. If the issue can be duplicated, you may see an official patch.

docStone’s picture

thanks zenscope, I've posted something over there already, now changed it to a bug report from a support request :)

It's really odd behavior that simply makes no sense to me, it seems like others are using this module properly.
ds

Adam Messinger’s picture

It's really odd behavior that simply makes no sense to me, it seems like others are using this module properly.

It could be something idiosyncratic to your setup, like a conflict with another installed module or a configuration hang-up. While you wait for some action on the bug report, you might try disabling other modules -- starting with other e-commerce modules and modules that affect node permissions -- and see if that magically fixes anything. It also never hurts to retrace your footsteps and make sure you've done all the necessary configuration on the back-end.

As a Drupal newbie I'm shooting in the dark with some of this advice. It's good standard practice, however, no matter what system you're using. In essence, you're limiting any interference that could be obscuring the true problem and double checking to make sure... well, to make sure that you aren't the problem. Surprising how often that happens, no matter how long you've been doing this stuff. ;-)

Best of luck, and happy troubleshooting.

docStone’s picture

It's actually what I did yesterday, I installed a vanilla version of drupal in a different directory and made sure it was all good.
I then installed the ecommerce module and the pay-per-node module and gave it a go. No dice there either.

I'll have to poke around and see how to test pay-per-view without ecommerce, it seems that you would need some mechanisim to create the node credits.

FWIW, as an admin, I can assign credits to users and all works as it is supposed to.

I suppose it's important to clarify at this point that the trouble *appears* to occur during the callback from paypal to ecommerce/pay-per-node. I presume the patch given above was an attempt to remedy that error.

I'm a drupal new user as well, just started playing with it on my personal site about 2 weeks ago and had a friend drop a project in my lap that seemed perfect if I can get this kind of function to work...
thanks for your suggestions!
-doc

Adam Messinger’s picture

You're very welcome. I hope it works out for you.

-----------------------------------------
I make websites.
http://www.zenscope.com/

johntymatts’s picture

user warning: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 query: SELECT uid FROM ec_transaction WHERE txnid = in

Is the error message I get after applying Doc stone patch any suggestions?


    case 'on payment completion':
      if($node->node_type && $node->qty && $node->node_qtty) {
        global $user;
        $number = $node->qty * $node->node_qtty;
//Patch applied
$txnid = substr($_POST['item_number'],6);
$tmpResult = db_query('SELECT uid FROM {ec_transaction} WHERE txnid ='. $txnid);      
$myUID = db_result($tmpResult);
//Line changed from original
               paypernode_user_update($myUID, $node->node_type, $number);
        drupal_set_message(t('You can create now %number nodes of type %node_type', array('%number' => $node->qty, '%node_type' => node_get_name($node->node_type))));
      } else {
        // Error condition
        drupal_set_message(t("No new node types added. Please contact site administrator"));
      }

      break;
marcoBauli’s picture

after applying the code above:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 query: paypernode_productapi SELECT uid FROM ec_transaction WHERE txnid = in /home/public_html/test/includes/database.mysql.inc on line 120.

no node credits assigned nowere, not to authenticated nor to anonymous users.

Used COD as payment method. Help greatly apreciated!

EDIT:

applied a new patch that solved the problem. You can find it here in the queue

basically:

paypernode.module

row 479

case 'on payment completion':
if($node->node_type && $node->qty && $node->node_qtty) {
$number = $node->qty * $node->node_qtty;
$tmpResult = db_query('SELECT uid FROM {ec_transaction} WHERE txnid ='. $node->txnid);
$myUID = db_result($tmpResult);
paypernode_user_update($myUID, $node->node_type, $number);

function paypernode_nodeapi, row 272

if($op == 'insert' && isset($node->paypernode)){
// Decrease user balance for this node type
// Get uid from node
global $user;
paypernode_user_update($user->uid, $node->type, 0, 1);