The basic idea is that userpoints_something() will return an object that can be further defined with methods, which will allow better validation and much simplified code.

I need to investigate if we can/want to support adding points with just a single function call. Maybe making operation and points required arguments of the factory function and the returned object would save itself automatically in the __destruct() method.

CommentFileSizeAuthor
#9 new_api3.patch147.19 KBberdir
#7 new_api2.patch147.85 KBberdir
#3 new_api.patch120.62 KBberdir

Comments

BenK’s picture

Subscribing

berdir’s picture

Writing down some ideas..

The function will probably be called userpoints_grant_points() or something along those lines. It will have two required arguments, an $operation string and $points. Everything else will have default values. $uid could be a third, optional argument since that is one of the most frequently used arguments. I don't want more arguments than that, though.

That function will then return an object with getter and setter functions, the setter functions will be chainable.

Example:

userpoints_grant_points('yourmodule_operation', $some_points, $uid)
  ->setEntity($entity_type, $entity_id)
  ->setDescription($description)
  ->setDisplay(TRUE)
  ->setStatus(UserpointsTransaction::STATUS_PENDING)
  ->save();

To be continued...

berdir’s picture

Status: Active » Needs review
StatusFileSize
new120.62 KB

Ok, here is a first patch. This patch does quite a few things more than I originally thought of, but it makes sense to do this right now, as it will make it much easier to refactored.

Notes:
- This patch is BIG. 1600 added lines, 1200 removed.
- The patch adds a new UserpointsTransaction class that is used instead of stdClass both when adding new transactions and also when loading entites
- The actual properties are kept as protected properties, with lots of getter and setter functions.
- To avoid breaking compatibility with existing code that *accesses* properties, a magic __get() method has been added.
- userpoints_grant_points() now works exactly as outlined above and all it has to do is pass these arguments forward to the UserpointsTransaction
- Many helper functions that extracted/formatted something of the transaction object have been moved directly into the UserpointsTransaction class. For example, instead of userpoints_create_description($transaction); , it is now simply $transaction->getReason();
- That class is now quite big (1200+ lines of code), but 50% of that are comments and it's all in a separate file that is only loaded when needed. I am not sure if it would make to move all formatting stuff like getReason() and getTableRow() into a separate class and just forward the call.
- I've added a few new tests for this, removed some and ported others. All tests should pass now.
- This already implements that transactions can not be altered after being saved (unless they are pending) but the UI doesn't support it yet. Trying to change something will simply result in an exception.
- I also removed a large part of README.txt (api documentation and services documentation) and instead linked to http://api.worldempire.ch.
- I wrote lots and lots of documentation, which can be reviewed on http://api.worldempire.ch/api/userpoints/7-2.

TODO:
- Improve the UI regarding the last point
- Rules/Services integration needs to be updated.

Warning: Make sure that you disable all modules that integrate with Userpoints before applying this patch. Specifically modules which grant points. Not doing so will result in fatal errors because the old function is removed.

guybrush’s picture

Looks good - it's nice to see more OO being used!

One small change that I think would be good in userpoints.modul is to change:
function userpoints_access_view_transaction($transaction) {
to
function userpoints_access_view_transaction(UserpointsTransaction $transaction) {
[similar to what you did in userpoints_admin_access_transaction_pending()]

guybrush’s picture

One other niggly thing, I think that in userpoints.transaction.inc, the line:
return!empty($this->denied_reasons);
should be formatted with a space after the 'return':
return !empty($this->denied_reasons);

berdir’s picture

Re #5: Yeah, makes sense. I was wondering if it would make sense to define a interface for the UserpointsTransaction class and use that for places like this. Because that's basically a coding standard in core. But it really doesn't make much sense here I think...

#6: Nice catch, will fix that in the next re-roll.

berdir’s picture

StatusFileSize
new147.85 KB

Big patch just got even bigger:

Updates:

- Fixed coding style from #6 and added type as suggested in #5
- Updated the UI, currently everything is disabled when trying to edit a saved transaction, we can discuss/improve this in #1258050: Making transactions read-only after approved/declined + Make it easy to create reverting/adjusting transactions
- Updated rules/services integration
- Wrote some tests for the rules integration.

Note: I usually put feature branches for Userpoints, see https://github.com/Berdir/userpoints/commits/1258042 for this issue, as I don't want them on d.o until we have something like per-issue repositories.

Status: Needs review » Needs work

The last submitted patch, new_api2.patch, failed testing.

berdir’s picture

Status: Needs work » Needs review
StatusFileSize
new147.19 KB

Added the rules.module dependency to the test and removed a debug call that caused the fatal error in the grant points test.

Yay testbot! :)

berdir’s picture

Status: Needs review » Fixed

I decided to go ahead with this and just commit it. 7.x-2.x is a development branch and there are quite some tests to verify that this is working pretty well.

We'll deal with bugs and stuff in separate issues.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

rfay’s picture

Status: Closed (fixed) » Needs work

Hmm.. I think some documentation is required here, as this breaks all users of an important function.

andypost’s picture

Yes this require change notification, to allow module developers to reflect this change in contrib

berdir’s picture

Status: Needs work » Fixed

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.