Welcome to the Question2Answer Q&A. There's also a demo if you just want to try it out.
+4 votes
448 views
in Q2A Core by
edited by

I know this has been asked several times in one form or another, but after a LOT of searching, I have not been able to find an answer. There were a few answers that pointed to the php code itself, or to the points page in Admin. But, none explained how they are calculated and processed by the script. In other scripts that track points (or other user log activities), they are generally handled with two DB tables and a Cron job scheduler.

1. Daily running table (TABLE 1) that tracts individual activities similar to the following :

USERID REASON POINTS
user1         aupvote 1
user2 cpost 5
user1 aselected 2
user1 cdownvote -1
user3 bonus 50

This table could have thousands of records. 

2. Second Table is the main points summary table (call it qa_userpoints)

At the end of each day a Cron is run on table 1 that tabulates the data and inserts that into table 2. Table one is then emptied and a new day starts. All stats shown to users is taken from table 2. I am aware the following under this scenario:

A. Points that users see would be as of the prior day.

B. When the point values are updated, the previous amounts earned would not change. They only change moving forward.  


I am not sure how the current system works. I see point values in several tables, a Recalculate button on the points page, and a plugin called Point Recalculator. This is not to mention 3rd party plugins all using their own tables. 

What I am looking to understand is the current flow on how points are calculated. I am not even sure how it is possible without using Cron jobs unless the script is looking at (and calculating) all the various tables and data in real-time.

Another question: 

1. User1's current point total is 196 (in qa_userpoints)

2. User1 asks a question that gives him 5 points

It looks like this increases the qposts number by 1. So how does this translate to an additional 5 points in the user's total points when viewing it on the site?

or

1. User1's current point total is 196 (in qa_userpoints)

2. User1 pins a post with a 3rd party plugin that costs him 50 points

How does this translate to a reduction of 50 points to the user's total points? (I understand that different plugins handle this differently, but they still need to add or subtract from the points somehow).

I know from reading other questions regarding points both here on Q2A and on Github, that this is a touchy subject for the contributors. I am just trying to understand the thought process here since I am seeing some weirdness with the point totals.

Thanks in advance!

Q2A version: 1.8.8

1 Answer

+5 votes
by
selected by
 
Best answer

From a bird's eye view, the business logic is extremely simple:

  1. Admins configure how many points some actions or triggers give (e.g. voting questions, getting answers selected, posting, etc)
  2. Users perform actions that execute these steps:
    1. Increase counters for the given user for the event types mentioned above
    2. Recalculate points for the given user as it is just multiplying several values by the amounts set in step 1

I see point values in several tables

I can't speak for third party plugins, but the points for each user are stored in ^userpoints table, points field. The rest of the fields in that table are the counters I mentioned above.

So how does this translate to an additional 5 points in the user's total points when viewing it on the site?

You've configured posting a question to give 5 points. If X is the amount of questions posted by the user, then posting a new question would mean moving from the first equation, to the second (note Y is the result of calculating all the rest of the point modifiers):

(5 * X) + Y = 196

(5 * (X + 1)) + Y = 201

How does this translate to a reduction of 50 points to the user's total points?

It is just a matter of hooking in the recalculation process, which would translate to something similar as adding more terms to the equation. Imagine Z amount of pins, pinning something would mean moving from the first equation to the second one in this way:

(5 * X) + Y + (-50 * Z) = 196

(5 * X) + Y + (-50 * (Z + 1)) = 146

Q2A doesn't make it as simple to hook into that equation, and it makes a bit less efficient than it could. So I suggested several years ago to improve this. Here is the pull request: https://github.com/q2a/question2answer/pull/486

I am seeing some weirdness with the point totals

If you can provide step by step instructions to replicate the weirdness, I'd be happy to take a look at it. At the end of the day, as Edsger Dijkstra said, "If debugging is the process of removing software bugs, then programming must be the process of putting them in".

by
Thanks pupi1985. Thorough as usual. I now see how the items are calculated, but have a question of WHEN they are calculated and placed in the qa_userpoints table?

If I were to assume that the points are all calculated prior to a DB insert, then the only time a recalculation is done is when the Recalculate button (or Point Recalculator) is pressed?

I also assume that when the Recalculate button (or Point Recalculator) is pressed...the system goes back and updates old point values with new point values (even on past events). Correct?
by
Strictly speaking, the re-calculation is the process of removing most counts and generating them from scratch. For example, resetting the amount of votes received by a user and counting them from the actual data. This is only meant for cases in which the counters desynchronize with the actual data. There is no planned scenario in which this could happen. Maybe if someone imports posts or something manually to the DB, for example. This is due to the denormalized database model that has redundant information (the counters, in this case).

The Point Recalculator does something similar and in batch, as well. Nothing special either, but it is clearer when it is needed to be run.

Moving aside from the re-calculation, let's use the word "refresh" to refer to the process in which the equations are calculated again and the points field is updated.

Given these definitions, I understand you wanted to know the events that trigger point refreshes. This is not documented, and is not super clear. However, you can infer most of them by checking the Points admin page. Bear in mind, there are a few more than what you can infer at first sight. For example, posting a question, clearly increases points. However, what about hiding or deleting? Same with answers, but what if an answer is turned into a comment?

Try to follow this voting example. Here you can see the code executed when a vote is performed:

https://github.com/q2a/question2answer/blob/bc1a8bc4fa951da908f14fc15aef65b01e8027a4/qa-include/ajax/vote.php#L45

This is the function that does the magic and is called from the previously linked one:

https://github.com/q2a/question2answer/blob/bc1a8bc4fa951da908f14fc15aef65b01e8027a4/qa-include/app/votes.php#L116

There lots of checks, mainly to avoid DB accesses as much as a possible. However, focus in:

 * qa_db_uservote_set() => Inserts the actual vote, which is irrelevant for the point refresh itself
 * qa_db_points_update_ifuser() => There are two calls here. This is the function that builds the equation (at least the part of the Q2A core, excluding plugins). One is run for the user performing the voting action and the other one is run for the user receiving the vote

This should clarify all the questions you've asked and should expose the fact that recalculation doesn't really play a relevant part in keeping points up to date in the daily basis. That's the refreshing process itself.
by
Thank you for the thoughtful response!
by
@pupi1985. After I update a point value, what is the order of recalculation? I am guessing that I press the Save and Recalculate button (Admin > Points), then press the Recalculate button (Admin > Plugins > Point Recalculator). I feel pretty confident on this...but I am not sure what the Recalculate user points button in the Admin > Stats does. It is under the Database clean-up operations section.

And if I run this operation, should I again press the Recalculate button in the Point Recalculator plugin?

I know that have pretty much beat this dead horse. :)
by
+1
Think of this equation:
(5 * X) + Y = 196

The 196 is the theoretical value and there should be a 196 in the field `points` for the given user.

Updating values in the Admin > Points page would mean changing the equation to, for example:

(10 * X) + Y = 250

The 250 is a bit arbitrary here. The important thing is that the theoretical 250 will be calculated whenever a point refresh happens. Which means the current `points` field for the user is still 196. In order to synchronize the theoretical value with the one in the database, it has to be refreshed.

In order to refresh it, you need to execute one of the actions that trigger point refreshes (e.g. voting, posting, etc). However, in order to avoid having to look for all users and upvote and downvote their points, Q2A provides a way to trigger a point refresh for all users. That's the recalculation process.

Running this operation will run the standard equation, ignoring plugins:

(10 * X) + Y = 250

So you should run the Point Recalculator afterwards as well to complement the original equation with the extended one:

(10 * X) + Y + (-50 * Z) = 200

So the new 200 theoretical value is set to the points table by the plugin.
by
I had to read your response a few times, but I got it now! Thank you. The last remaining question is :

What does the "Recalculate user points" button in the Admin > Stats do? It is under the Database clean-up operations section. Is it the same as the Save and Recalculate button (Admin > Points)? Or something non-related to refreshing the points?
by
+1
It is the same. It is there just as a shortcut
...