One bad apple is all it takes.... but I can see where he's coming from. I'll see if I can help you out here. I read this earlier, but didn't have time to post.
One thing you could do is use mySQL and track what users are in what level for what person. You can do it one of two ways:
1.) One row per person containing the "underlings" ID and what level they are (1-4)
2.) One row per person containing four columns (one per level) of delimited values of user IDs.
This is going to be tricky to explain, so stick with me here. For each example, we'll assume the following (I'm using "credits" to denote value, rather than Euro or whatever):
PersonF comes to your site through a referral by PersonE. PersonA will not get anything from this referral, PersonB will get 1.5 credits, PersonC will get 3, PersonD will get 5, and PersonE will get 10.
Okay, so that's our scenario. I'm using 1.5 credits as an example, although feel free to change it.
One row per person, with only two columns
Using this method, we'd have a table looking something like:
| Ordered By UserID | | Ordered By Level |
+-----------------------------+ |<| +-----------------------------+
| UserID | ReferredID | Level | |>| | UserID | ReferredID | Level |
+--------+------------+-------+ |<| +--------+------------+-------+
| 1 | 2 | 1 | |>| | 1 | 2 | 1 |
| 1 | 3 | 2 | |<| | 2 | 3 | 1 |
| 1 | 4 | 3 | |>| | 3 | 4 | 1 |
| 1 | 5 | 4 | |<| | 4 | 5 | 1 |
| 2 | 3 | 1 | |>| | 5 | 6 | 1 |
| 2 | 4 | 2 | |<| | 1 | 3 | 2 |
| 2 | 5 | 3 | |>| | 2 | 4 | 2 |
| 2 | 6 | 4 | |<| | 3 | 5 | 2 |
| 3 | 4 | 1 | |>| | 4 | 6 | 2 |
| 3 | 5 | 2 | |<| | 1 | 4 | 3 |
| 3 | 6 | 3 | |>| | 2 | 5 | 3 |
| 4 | 5 | 1 | |<| | 3 | 6 | 3 |
| 4 | 6 | 2 | |>| | 1 | 5 | 4 |
| 5 | 6 | 1 | |<| | 2 | 6 | 4 |
+-----------------------------+ |>| +-----------------------------+
They're the same table, just ordered differently.
Now, when PersonF (UserID 6) registers and lists referrer E (UserID 5) we can query for all those where "ReferredID" is equal to 5 and Level is less than 4 (you'll see why in a moment 😉). Now, once we get the list we can add 1 to the "level" for each (so level 1 becomes 2, level 2 becomes 3, etc.). Now, Because UserID 6 hasn't been added yet, we know that userID 5 will be level 1. So we work backwards crediting everyone. We start with our credits table like this:
| UserID | Credits |
+--------+------------+
| 1 | 19.5 |
| 2 | 18 |
| 3 | 15 |
| 4 | 10 |
+---------------------+
Since userID 5 has a new referral, and they're not in there now, we add them and credit them 10, and credit userID 4 with 5, userID 3 with 3, userID 2 with 1.5 to give us:
| UserID | Credits |
+--------+------------+
| 1 | 19.5 |
| 2 | 19.5 |
| 3 | 18 |
| 4 | 15 |
| 5 | 10 |
+---------------------+
Then you'd add these lines:
| UserID | ReferredID | Level |
+--------+------------+-------+
| 2 | 6 | 4 |
| 3 | 6 | 3 |
| 4 | 6 | 2 |
| 5 | 6 | 1 |
Now, that's one way.
Using one row per user, and 4 columns
This way uses the same exact idea as above, except that you now need to move IDs from one "array" to the other. You'd start with something like this table:
| UserID | lvl_1 | lvl_2 | lvl_3 | lvl_4 |
+--------+---------+---------+---------+---------+
| 1 | 2 | 3 | 4 | 5 |
| 2 | 3 | 4 | 5 | |
| 3 | 4 | 5 | | |
| 4 | 5 | | | |
+------------------------------------------------+
and eventually with the addition of userID 6, get this:
| UserID | lvl_1 | lvl_2 | lvl_3 | lvl_4 |
+--------+---------+---------+---------+---------+
| 1 | 2 | 3 | 4 | 5 |
| 2 | 3 | 4 | 5 | 6 |
| 3 | 4 | 5 | 6 | |
| 4 | 5 | 6 | | |
| 5 | 6 | | | |
+------------------------------------------------+
And eventually, if other users joined as userID 1 kept referring, you'd have something like this:
| UserID | lvl_1 | lvl_2 | lvl_3 | lvl_4 |
+--------+---------+---------+---------+---------+
| 1 | 2,7 | 3,8 | 4,9 | 5,10 |
| 2 | 3 | 4 | 5 | 6 |
| 3 | 4 | 5 | 6 | |
| 4 | 5 | 6 | | |
| 5 | 6 | | | |
+------------------------------------------------+
Now, each time 7 referrs something, userID 1 gets 1.5 credits, userID 8 referrs someone 1 gets 3 credits and so on. That makes it easier, but also complicates the SQL queries. But it can be more efficient. You'd really have to do your own benchmarking.
These are only two suggestions and very very crude examples. You will really have to do some good deduction of what I've presented here to get this to work. It may take you some time to get it perfected. So don't get distraught when it doesn't work immediately.