Since we now have several changes that affect the API, it seems that userpoints-z.z-3.x is in order.

I discussed this with jredding briefly, and want to get more comments from those interested.

We must go for arguments as an array, so we can add more arguments in the future without affecting modules too much (as long as the minimum mandatory ones are passed and validated).

So the minimum would be:

$arg = array(
 'op' => 'points',
 'points' = $points,
 );
userpoints_userpointsapi($arg);

A more full example would be:

$arg = array(
 'op' => 'points',
 'points' = $points,
 'uid' = $user->uid,
 'event' = 'comment',
 'cid' => $cid, // category
 'expires' => time() + variable_get('userpoints_expire_comment', 86400),
 'description' => 'points for posting a comment',
 );
userpoints_userpointsapi($arg);

Yes, we will have to break the API this once going from -2.x to -3.x, but this way, we will not break it as much after that.

Comments?

Comments

jredding’s picture

Component: Code » Code: userpoints.module

I was reading http://drupal.org/node/142956 and the following caught my eye.
$op can be
'points' - Points are awarded instantly and adhere to the sites moderation rules
'txn approve' - Points are approved, and the trail is ignored.
'points approved' - Points are awarded instantly and moderation is ignored

In the new API change what would $op be? Because there seems to be unanimous agreement that ALL transactions should be stored. Would it be better to drop $op and instead have a boolean $moderate flag?

Examples:
Current consideration:

$arg = array(
'op' => 'points',
'points' = $points,
);
userpoints_userpointsapi($arg);

The change

$arg = array(
'moderate' => FALSE, 
'points' = $points,
);
userpoints_userpointsapi($arg);

if $arg['moderate'] is NULL then the site's moderation rules apply.
if TRUE then points are moderated regardless of the moderation settings (would that even make sense?)

I only say $opt as being 'points', 'txn approve' or 'points unmoderate'. Since 'txn approve' skips past the txn table (no audit trail) and everyone agree that is bad.. should be drop it completely?

Is there a module/case that would really like to keep txn_approve (skip the txn table)? (super high traffic sites/modules.. possibly?)

Also another comment, shouldn't the minimum call include $uid or if its not pass in would the code take $user->uid?
example

$arg = array(
'op' => 'points',
'points' => $points,
'uid' => $user->uid
);
userpoints_userpointsapi($arg);
kbahey’s picture

First, the $uid. If it is not specified then the current logged in user will be awarded the points. Since this is the most common case, less arguments is better. This is already in:

global $user;
$user->uid;

So, the API can deduce it if it is not specified.

If the user who will be awarded the points is another users (e.g. the user who owns the node, commented the comment, invited the current user, ...etc.) then $uid has to be explicitly specified.

Regarding dropping the $op, I see the merit of having $moderated as a flag. However, I would like to keep $op and default it to 'points'.

So the minimal call would be :

userpoints_userpointsapi(array('points' = $points));

Just one argument!

I am not sure what the implications of dropping 'txn approve' altogether though.

merc mobily, are you lurking out there?

jredding’s picture

OK :: $uid. agreed not needed we'll default to $user->uid (as we currently do). I like the minimal call
$op :: if we kept it we don't need $moderated since we can simply have multiple ops
'points' = Add points and adhere to module defaults
'points approve' = Add points and skip moderation (override module defaults)
'txn approve' = Add points, no moderation, no trail

In regards to txn approve, I see the merit in it for performance reasons. If you're on a website granting a single point for every comment, node, revision, etc. and you're getting thousands/tens-of-thousands of comments/node/revisions a day the userpoints_txn table is going to fill up fast. After a few months it could potentially be filled with 100s of thousands of entries or millions.

Which could affect performance. <-- feedback requested, please

If so should we allow an option to ignore the trail? (which destroys auditing.. but if that's what the users want.. whatever..right?)

Also while we're at it.. should we change the naming convention to something like
'points'
'points approve'
'points notxn'

Just so its a little more intuitive. Because honestly 'txn approve' to me says "Transaction approve' or that a transaction log will be created vs. simply points.

Thoughts?

kbahey’s picture

Add points, no moderation, no trail

No, I want to ALWAYS have a trail no matter what. We can make this transaction approved, but still have a trail.

We can have another thingie like this:

'moderated' => TRUE // Means that the transaction will be moderated and will not reflect immediately to the points balance of the user
or
'moderated' => FALSE // Means that the transaction will not be moderated, and affects the balance immediately.

The default will be whatever the admin choses in the settings, but modules can still override that.

So, 'txn approve' will still be needed in case moderated = TRUE.

Moderation is needed for some sites where abuse of points happen (people rack up point with junk comments to win prizes).

Re: the size of the txn table growing, no one has reported that so far. When it becomes a problem we could use aging where we purge transactions beyond the last year or six months.

Re: "points notxn", I don't like it for these reasons: First the NoSomething is always confusing. Second, we are actually approving a particular transaction, so we can say 'approve txn'.

jredding’s picture

Component: Code: userpoints.module » Code: userpoints

I recently committed the v3 API changes to the BRANCH DRUPAL-5--3. userpoints_api now accepts an array of parameters instead

ex. userpoints_userpointsapi($params = array())

$params requires at a minimum
'op' => 'points' OR 'points approved' (points approved skips moderation)
'points' => (int)

$params can currently contain
$uid (default = $user->uid)
$event (string)
$expirydate = (timestamp when point should expire)
$description = (string)
$reference = indexed, searchable for module use

expirydate is a NEW feature that I added that expires points on a certain date (via cron) by posting an opposite transaction (5 points is expired by adding a -5 points). A trail is always logged.

userpoints_transaction was also modified to accept an array (same as userpointsapi)

example of how to use the new API call
$params = array(
'op' => 'points',
'points' => 10,
'uid' => $user->uid,
'event' => 'admin',
'description' => "Adding a node",
);
userpoints_userpointsapi($params);

due to the changes in the API $op only operates on 'points' and 'points approve'. We could simply the api call and the and api function by reducing to a simple $moderate that would default to the site's setting. Thus the api call could be as simple as

userpointsapi(array('points' => 5))

which we could then reduce even more by testing if $param is_numeric or an array and if numeric assume that its a point. Similar to node_load.

ex. userpointsapi(5);

Those points would then be assigned to the current logged in user and adhere to the site's default settings for moderation, expiration, etc.

Thus the remaining question is :: Can we drop $op and move to $moderated = TRUE/FALSE?

kbahey’s picture

'op' => 'points' OR 'points approved' (points approved skips moderation)

Can we default 'op' to 'points' if 'op' is not specified? This way only 'points' is required.

userpointsapi(array('points' => 5))

Yes, that is what I meant!

which we could then reduce even more by testing if $param is_numeric or an array and if numeric assume that its a point. Similar to node_load.

ex. userpointsapi(5);

Good idea. Makes it even more minimalist.

Thus the remaining question is :: Can we drop $op and move to $moderated = TRUE/FALSE?

Interesting thought. That would be simpler. But two points:

1. Would that be a mechanism where a module can bypass the site setting re: moderation (e.g. site says moderate them, but module X says grant them immediately)?

2. Are you sure we won't need $op for any other cases (e.g. txn approve, ...etc.)?

jredding’s picture

1. Would that be a mechanism where a module can bypass the site setting re: moderation (e.g. site says moderate them, but module X says grant them immediately)?

Yes effectively. $moderate would have the following states
moderate = TRUE (moderate regardless of site settings)
moderate = FALSE (bypass moderation regardless of site settings)
moderate = NULL or not set (adhere to site settings)

It seemed as though some modules wanted to explicitly bypass the moderation status (ex. $op = "txn approve" bypassed moderation)

2. Are you sure we won't need $op for any other cases (e.g. txn approve, ...etc.)?

I don't know the answer to this. Currently "Points before" and "points after" are available for all modules to act on but $op isn't sent onto other modules (thus by dropping this we wouldn't affect them). Within the module itself $op was only being tested for two settings; "points" and "points approve". The only difference was that "points approve" bypassed moderation "txn approve" was being used for points given by an administrator but switching this to moderate = FALSE would solve that issue (and $op isn't being stored anywhere). There is still $event in the DB (and passed via the API call) which (a) is stored in the DB and (b) we could send onto to other module for them to act on.

I have only been using this module for the past several months but I haven't seen any reason for keeping $op going forward. If someone with a longer history of this module could comment it would be greatly appreciated.

kbahey’s picture

Re: moderation bypass by modules. Let us make that a feature and document it. It is powerful and can be misused, but so be it. We give them a sawed off shotgun and they can chose to shoot at their feet if they so wish.

Re: $op, let us nuke it. 'points approve' is only used internally. This makes 'points' the only op that modules use, so it is meaningless to keep it.

Go Jacob Go!

jredding’s picture

Assigned: Unassigned » jredding
Status: Active » Fixed

Revision 1.44.2.14.2.9 in the DRUPAL-5--3 branch implements the API change including the change to $moderation instead of $op.

Version 3 is NOT ready for release as the contributed modules haven't been updated yet.

Anonymous’s picture

Status: Fixed » Closed (fixed)
jredding’s picture

Version: master » 5.x-3.x-dev
mercmobily’s picture

Hi,

For what it's worth, please accept my apologies for missing this thread. I was travelling... I've only just managed to come back to my normal working life :-(

jredding’s picture

Hey merc! Welcome back. No problem about missing the thread but when you get some time could you grab the dev version of 3 and put it threw the ringer. All comments are fully appreciated.

mercmobily’s picture

Thank you for your understanding :-D
OK, I will go through the thread and will have a look!

simple_karma will need to talk to userpoints. So, I will definitely test this a lot...

Bye,

Merc.