View Full Version : Infraction Hook
Chris.08i
12-15-2015, 08:36 PM
Hello,
It's me again - I was wondering if anyone could tell me which hook to latch my plugin onto if I wanted to modify a column within the users table.
I have tried the hooks 'infractiondata_postsave, infractiondata_presave, and memberinfraction_complete".
Either I have the wrong hook, or something in my code is wrong (which is probably the case)
<?php
global $vbulletin, $prepared;
$usersid = $prepared['userid'];
$ipoints = $vbulletin->db->query_first("
SELECT COUNT(*)
FROM " . TABLE_PREFIX . "user.ipoints
WHERE userid = " . $usersid . "
");
$imodpp = 150;
if ($ipoints >= 1) {
$imodpp = $imodpp * ($ipoints * 2.5);
}
if ($ipoints > 0) {
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = reputation - " . $imodpp . "
WHERE userid = " . $usersid)
);
}
?>
MarkFL
12-15-2015, 10:26 PM
Okay, the first thing is, in a plugin you don't want to include the PHP tags. If your code is in an external file called by a plugin, then you do need the tags.
The hook location "infractiondata_postsave" is a good one (assuming you want this code to execute after the infraction is given), and you'll need to make the $userinfo array global to access it. This array will contain information regarding the user receiving the infraction.
You first query looks like it needs some tweaking, but please let me know exactly what you want to accomplish with this code, and I will try to point you in the right direction. :)
Chris.08i
12-15-2015, 10:58 PM
Okay, the first thing is, in a plugin you don't want to include the PHP tags. If your code is in an external file called by a plugin, then you do need the tags.
The hook location "infractiondata_postsave" is a good one (assuming you want this code to execute after the infraction is given), and you'll need to make the $userinfo array global to access it. This array will contain information regarding the user receiving the infraction.
You first query looks like it needs some tweaking, but please let me know exactly what you want to accomplish with this code, and I will try to point you in the right direction. :)
I want to deduct reputation points from the user that is receiving the infraction.
The base amount is 150 points, but each active infraction point (ipoints in users table as far as I know) will apply a 2.5x multiplier. For example, someone with 4 infraction points will receive 1500 points deduction from their reputation column.
I hope that makes sense.
MarkFL
12-16-2015, 01:41 AM
I want to deduct reputation points from the user that is receiving the infraction.
The base amount is 150 points, but each active infraction point (ipoints in users table as far as I know) will apply a 2.5x multiplier. For example, someone with 4 infraction points will receive 1500 points deduction from their reputation column.
I hope that makes sense.
Yes, makes perfect sense. What we can do is get this done with just one query. While this code (hopefully) won't be called often, it's a good idea to get in the practice of minimizing the number of queries for any operation.
global $userinfo;
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = (reputation - (375*ipoints))
WHERE userid = " . $userinfo['userid']
);
Chris.08i
12-16-2015, 05:13 AM
Yes, makes perfect sense. What we can do is get this done with just one query. While this code (hopefully) won't be called often, it's a good idea to get in the practice of minimizing the number of queries for any operation.
global $userinfo;
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = (reputation - (375*ipoints))
WHERE userid = " . $userinfo['userid']
);
What if ipoints = 0?
I still want to deduct 150 from their reputation.
MarkFL
12-16-2015, 05:49 AM
What if ipoints = 0?
I still want to deduct 150 from their reputation.
Your original code indicated that a deduction only occurs when ipoints > 0. But, if you want 150 rep deducted when ipoints = 0, and otherwise 375 * ipoints rep deducted then our code would be (since we don't have a nice linear relationship):
global $userinfo;
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = CASE ipoints
WHEN 0 THEN (reputation - 150)
ELSE (reputation - (375*ipoints))
WHERE userid = " . $userinfo['userid']
);
Chris.08i
12-16-2015, 08:38 AM
Your original code indicated that a deduction only occurs when ipoints > 0. But, if you want 150 rep deducted when ipoints = 0, and otherwise 375 * ipoints rep deducted then our code would be (since we don't have a nice linear relationship):
global $userinfo;
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = CASE ipoints
WHEN 0 THEN (reputation - 150)
ELSE (reputation - (375*ipoints))
WHERE userid = " . $userinfo['userid']
);
Well that sums it up nicely!
I was going to use if statements to create the effect I needed, turns out I don't need to!
Thanks so much for your help Mark, definitely learned a lot these couple days.
Edit: I just tried it - I'm getting a Server 500 error when I try infract someone. Any ideas?
Edit #2: So I globalised $vbulletin as well and it started running the code properly. However it isn't properly deducting from the table.
Edit #3: I got it to deduct!
It turns out we were missing an 'END' to the case which cause an MySQL syntax error.
However it now seems like it's going through both cases and deducting a total of 525 every time, no matter what! Not sure why the case rules aren't working!
Edit #4:
Okay - I got fed up so I ended up going with this. However, this code for some reason deducts double what I calculate it should do. For example, those with 0 ipoints, gets deducted 300 instead of 150, and those with 1 ipoint get deducted 750 instead of 375.
global $userinfo, $vbulletin;
if ($userinfo['ipoints'] == 0) {
$base = 150;
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = reputation - " . $base . "
WHERE userid = " . $userinfo['userid']
);
}
if ($userinfo['ipoints'] > 0) {
$imodpp = 150 * ($userinfo['ipoints'] * 2.5);
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = reputation - " . $imodpp . "
WHERE userid = " . $userinfo['userid']
);
}
I know this isn't the most efficient way - but it's the most working I could get it to so far!
MarkFL
12-17-2015, 03:05 PM
This plugin works correctly on my local dev site:
Product: vBulletin
Hook Location: infractiondata_postsave
Title: Deduct Rep When Infracting
Execution Order: 5
Plugin PHP Code:
global $vbulletin, $db, $userinfo;
$points = $userinfo['ipoints'];
$rep = $userinfo['reputation'];
if ($points > 0)
{
$newrep = ($rep - $points*375);
}
else
{
$newrep = ($rep - 150);
}
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = " . $newrep . "
WHERE userid = " . $userinfo['userid']
);
Plugin is Active: Yes
Chris.08i
12-19-2015, 10:33 AM
I had an adaptation of mine that I have been using for the past couple days that have been working for me.
I have changed over to your code as it's much neater! Thank you again Mark for your time and help!
I was wondering if it was possible to only trigger the above deduction when an actual point is issued, and no deduction for warnings?
MarkFL
12-19-2015, 10:54 AM
I had an adaptation of mine that I have been using for the past couple days that have been working for me.
I have changed over to your code as it's much neater! Thank you again Mark for your time and help!
I was wondering if it was possible to only trigger the above deduction when an actual point is issued, and no deduction for warnings?
Do you mean then a deduction based only on the points being issued at the time, and not on the cumulative total of active points? If so, I would have to investigate to see how to retrieve that value. :)
The code I posted does exactly the opposite of that...it uses $userinfo['ipoints'] which does not include the points currently being given, but rather the number of points accumulated by the user before the current infraction.
edit: Try using the hook location "infraction_update_complete", and at that hook, the points for the current infraction is in $vbulletin->GPC['points']. Then you can base the rep deduction on that and update the user table. :)
Chris.08i
12-19-2015, 10:59 PM
Do you mean then a deduction based only on the points being issued at the time, and not on the cumulative total of active points? If so, I would have to investigate to see how to retrieve that value. :)
The code I posted does exactly the opposite of that...it uses $userinfo['ipoints'] which does not include the points currently being given, but rather the number of points accumulated by the user before the current infraction.
edit: Try using the hook location "infraction_update_complete", and at that hook, the points for the current infraction is in $vbulletin->GPC['points']. Then you can base the rep deduction on that and update the user table. :)
No, the current script works fine. I want it to deduct based on the current active points, so using ipoints is correct.
However, I don't want to issue and deduction when the user is only issued a warning (infraction without points).
MarkFL
12-20-2015, 01:27 AM
If you use the code I posted in post #8, then the deduction will be based on the accumulated active points prior to the infraction being issued. So, for example, suppose a user has 3 active points, and you then issue a warning...$userinfo['ipoints'] will be equal to 3.
But, if you use the hook location and variable I suggested in post #10, then $vbulletin->GPC['points'] will be equal to 0.
Chris.08i
12-22-2015, 08:40 PM
Hi Mark
global $vbulletin, $db, $userinfo;
if ($vbulletin->GPC['points'] == 0) {
continue;
}
$points = $userinfo['ipoints'];
$rep = $userinfo['reputation'];
if ($points > 0)
{
$newrep = ($rep - $points*500);
}
else
{
$newrep = ($rep - 150);
}
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = " . $newrep . "
WHERE userid = " . $userinfo['userid']
);
This is what my revised code looked like, on the hook that you suggested. I'm getting a server 500 error when I try to issue a warning.
Any ideas?
Dragonsys
12-22-2015, 08:57 PM
why are you using continue without a loop?
I would remove this, it is rather pointless in that code:
if ($vbulletin->GPC['points'] == 0) {
continue;
}
or comment it out until you are ready to do something with it. This might be the cause of your 500 error
Chris.08i
12-22-2015, 11:23 PM
why are you using continue without a loop?
I would remove this, it is rather pointless in that code:
if ($vbulletin->GPC['points'] == 0) {
continue;
}
or comment it out until you are ready to do something with it. This might be the cause of your 500 error
I am trying to prevent the bottom code from running if the infraction points being handed out = 0.
Dragonsys
12-22-2015, 11:49 PM
That is not how your code is working. You need to put the bottom inside the if statement. I can post the code when I get home if someone doesn't beat to it
--------------- Added 1450838239 at 1450838239 ---------------
try this:
global $vbulletin, $db, $userinfo;
if ($vbulletin->GPC['points'] != 0) {
$points = $userinfo['ipoints'];
$rep = $userinfo['reputation'];
if ($points > 0)
{
$newrep = ($rep - $points*500);
}
else
{
$newrep = ($rep - 150);
}
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = " . $newrep . "
WHERE userid = " . $userinfo['userid']
);
}
Chris.08i
12-23-2015, 12:56 AM
I tried that - it doesn't work.
I don't get the server 500 error anymore, but it no longer deducts points if the infraction points being handed out is > 0
Dragonsys
12-23-2015, 01:40 AM
sorry, i think I read what you wanted backwards, try this:
global $vbulletin, $db, $userinfo;
if ($vbulletin->GPC['points'] == 0) {
$points = $userinfo['ipoints'];
$rep = $userinfo['reputation'];
if ($points > 0)
{
$newrep = ($rep - $points*500);
}
else
{
$newrep = ($rep - 150);
}
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = " . $newrep . "
WHERE userid = " . $userinfo['userid']
);
}
Chris.08i
12-23-2015, 02:24 AM
Thanks for the reply.
I already have that exact code on my forums - yet it still does not work. It also doesn't make sense to me.
When I read your code, it basically only runs the deduction code when it ISNT an infraction, and IS a warning.
I want the deduction code to only run when there IS points applied to the infraction.
I hope I am making sense.
Dragonsys
12-23-2015, 02:29 AM
ok, that is what I gave you the first time
$vbulletin->GPC['points'] != 0
but you said it didn't work. So I changed it to this:
$vbulletin->GPC['points'] == 0
So what determines an infraction vs a warning, in the code?
--------------- Added 1450845203 at 1450845203 ---------------
the continue you had in your code is what was causing the 500 error for you, as a continue is used to exit a loop, and you did not have a loop. So I moved the code you wanted to run when points is 0, to inside your if statement. Should it run when points is 0, or when it is not 0?
Chris.08i
12-23-2015, 02:34 AM
ok, that is what I gave you the first time
$vbulletin->GPC['points'] != 0
but you said it didn't work. So I changed it to this:
$vbulletin->GPC['points'] == 0
So what determines an infraction vs a warning, in the code?
I am not sure - from what Mark posted earlier, I assumed that $vbulletin->GPC['points'] was the code to determine the number of points being issued in the infraction.
So from my understanding:
An infraction that don't carry points $vbulletin->GPC['points'] == 0 would equal an infraction should skip the bottom code (deduction code).
I have tried either variations, and neither have worked.
Dragonsys
12-23-2015, 02:36 AM
I am not sure - from what Mark posted earlier, I assumed that $vbulletin->GPC['points'] was the code to determine the number of points being issued in the infraction.
So from my understanding:
An infraction that don't carry points $vbulletin->GPC['points'] == 0 would equal an infraction should skip the bottom code (deduction code).
I have tried either variations, and neither have worked.
In that case != 0 should cause it to run the subtraction code, which you said it didn't. I will have to look at the hook some.
--------------- Added 1450845554 at 1450845554 ---------------
based on this post:
If you use the code I posted in post #8, then the deduction will be based on the accumulated active points prior to the infraction being issued. So, for example, suppose a user has 3 active points, and you then issue a warning...$userinfo['ipoints'] will be equal to 3.
But, if you use the hook location and variable I suggested in post #10, then $vbulletin->GPC['points'] will be equal to 0.
I would assume that a Warning is
$vbulletin->GPC['points'] == 0
so an Infraction would be
$vbulletin->GPC['points'] != 0
You want the points to be deducted with an Infraction, but not a Warning, right?
Chris.08i
12-23-2015, 02:42 AM
That is correct.
The hook I am using is 'infraction_update_complete'
Dragonsys
12-23-2015, 02:46 AM
That is correct.
The hook I am using is 'infraction_update_complete'
ok, in that case the first piece of code I posted should work for what you want, but you say it is not actually subtracting the points. Did you get a SQL error?
try this:
global $vbulletin, $db, $userinfo;
if ($vbulletin->GPC['points'] == 0) {
$points = $userinfo['ipoints'];
$rep = $userinfo['reputation'];
if ($points > 0)
{
$newrep = ($rep - $points*500);
}
else
{
$newrep = ($rep - 150);
}
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = " . $newrep . "
WHERE userid = " . $userinfo['userid'] .""
);
}
Chris.08i
12-23-2015, 02:54 AM
So I tried again with == 0 and != 0.
When I tried == 0 - points get deducted when I issue warnings and they don't get deducted when giving an infraction.
When I tried != 0, points are not deducted in either situation.
Dragonsys
12-23-2015, 02:58 AM
So I tried again with == 0 and != 0.
When I tried == 0 - points get deducted when I issue warnings and they don't get deducted when giving an infraction.
When I tried != 0, points are not deducted in either situation.
ok, we are making progress at least, lol. Let's try it this way (assuming this will always be a positive or 0):
global $vbulletin, $db, $userinfo;
if ($vbulletin->GPC['points'] > 0) {
$points = $userinfo['ipoints'];
$rep = $userinfo['reputation'];
if ($points > 0)
{
$newrep = ($rep - $points*500);
}
else
{
$newrep = ($rep - 150);
}
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = " . $newrep . "
WHERE userid = " . $userinfo['userid'] .""
);
}
Chris.08i
12-23-2015, 03:02 AM
Tried that before if I remember correctly. I tried again nevertheless.
Warning does nothing, and infraction does nothing.
Dragonsys
12-23-2015, 03:23 AM
There are minor differences. Ok, let me think on this a bit. I will get a fresh look in the morning.
Chris.08i
12-23-2015, 01:48 PM
There are minor differences. Ok, let me think on this a bit. I will get a fresh look in the morning.
Thanks.
Perhaps the code to check for the infraction points being handed out is wrong, or the hook is wrong? I am not sure how to check either of these though.
Dragonsys
12-23-2015, 03:06 PM
Thanks.
Perhaps the code to check for the infraction points being handed out is wrong, or the hook is wrong? I am not sure how to check either of these though.
I will have to do some checking on my test site and see how GPC['points'] is returned.
I think the hook is right, just need to figure out what is being returned, so we can use it properly
MarkFL
12-23-2015, 03:59 PM
I will have to do some checking on my test site and see how GPC['points'] is returned.
I think the hook is right, just need to figure out what is being returned, so we can use it properly
On my local dev site, it returns the number of points for the infraction being issued. :)
Dragonsys
12-23-2015, 04:09 PM
On my local dev site, it returns the number of points for the infraction being issued. :)
ok, so for a Warning it should return 0 and an Infraction it should be >0 or is it <0?
--------------- Added 1450894187 at 1450894187 ---------------
Chris, what version of vBulletin are you running?
MarkFL
12-23-2015, 04:10 PM
Yes for a warning it returns 0 and, for example if I issue a custom infraction for 1 point, it returns 1.
Dragonsys
12-23-2015, 04:14 PM
Yes for a warning it returns 0 and, for example if I issue a custom infraction for 1 point, it returns 1.
strange, then the code should work. it should have worked by using != 0
--------------- Added 1450894799 at 1450894799 ---------------
Ok, let's try removing some of the unneeded code and just getting the basics.
global $vbulletin, $db, $userinfo;
if ($userinfo['ipoints'] > 0)
{
$newrep = ($userinfo['reputation'] - $userinfo['ipoints']*500);
}
else
{
$newrep = ($userinfo['reputation'] - 150);
}
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = " . $newrep . "
WHERE userid = " . $userinfo['userid']
);
Does this work? It should subtract points for Warning & Infraction
MarkFL
12-23-2015, 04:26 PM
strange, then the code should work. it should have worked by using != 0
This is the last block of code you posted:
global $vbulletin, $db, $userinfo;
if ($vbulletin->GPC['points'] > 0) {
$points = $userinfo['ipoints'];
$rep = $userinfo['reputation'];
if ($points > 0)
{
$newrep = ($rep - $points*500);
}
else
{
$newrep = ($rep - 150);
}
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = " . $newrep . "
WHERE userid = " . $userinfo['userid'] .""
);
}
The only issue I can see is with the quotes at the end of the query...I would write:
global $vbulletin, $db, $userinfo;
if ($vbulletin->GPC['points'] > 0) {
$points = $userinfo['ipoints'];
$rep = $userinfo['reputation'];
if ($points > 0)
{
$newrep = ($rep - $points*500);
}
else
{
$newrep = ($rep - 150);
}
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = " . $newrep . "
WHERE userid = " . $userinfo['userid']
);
}
What this should do is if a user is being issue a warning, nothing happens. If they are being issued an infraction, then if prior to the current infraction they have current active points, they will have 500 rep points deducted per current active infraction points, otherwise their rep will simply be reduced by 150.
--------------- Added 1450895509 at 1450895509 ---------------
...Ok, let's try removing some of the unneeded code and just getting the basics.
global $vbulletin, $db, $userinfo;
if ($userinfo['ipoints'] > 0)
{
$newrep = ($userinfo['reputation'] - $userinfo['ipoints']*500);
}
else
{
$newrep = ($userinfo['reputation'] - 150);
}
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = " . $newrep . "
WHERE userid = " . $userinfo['userid']
);
Does this work? It should subtract points for Warning & Infraction
That will only take into account a user's prior active infraction points, so there will be no difference in what's done between a warning and an infraction being issued.
Dragonsys
12-23-2015, 04:36 PM
The only issue I can see is with the quotes at the end of the query
Right, that was just checking to see if he was getting a SQL error
What this should do is if a user is being issue a warning, nothing happens. If they are being issued an infraction, then if prior to the current infraction they have current active points, they will have 500 rep points deducted per current active infraction points, otherwise their rep will simply be reduced by 150.
I had that and he said ti didn't subtract any points
That will only take into account a user's prior active infraction points, so there will be no difference in what's done between a warning and an infraction being issued.
Correct, I'm trying to see if the basics work, and then figure out why he is having problems with the if statement.
MarkFL
12-23-2015, 04:46 PM
Using the last block of code you posted (with the query edited to remove your test quotes), I tested it on a user on my local dev site who initially had 13 ipoints and 10 rep points. After I issued a 3 point infraction, his ipoints became 16 and his rep became -6490 (which is what we should expect).
This means that at the hook we are using, the ipoints value was still at 13 and $vbulletin->GPC['points'] > 0.
Then I issued that same user a warning, and his rep was unaffected.
The bottom line is the code you posted works flawlessly for me.
Dragonsys
12-23-2015, 05:12 PM
Using the last block of code you posted (with the query edited to remove your test quotes), I tested it on a user on my local dev site who initially had 13 ipoints and 10 rep points. After I issued a 3 point infraction, his ipoints became 16 and his rep became -6490 (which is what we should expect).
This means that at the hook we are using, the ipoints value was still at 13 and $vbulletin->GPC['points'] > 0.
Then I issued that same user a warning, and his rep was unaffected.
The bottom line is the code you posted works flawlessly for me.
Ok, i wonder why it is not working for Chris then.
MarkFL
12-23-2015, 05:23 PM
Oh, if I had a dollar for every time I have wondered, "Why does it work for me, but not the other user?" :)
Dragonsys
12-23-2015, 05:28 PM
Oh, if I had a dollar for every time I have wondered, "Why does it work for me, but not the other user?" :)
I know
Chris.08i
12-23-2015, 09:39 PM
I have tried this code
global $vbulletin, $db, $userinfo;
if ($vbulletin->GPC['points'] > 0) {
$points = $userinfo['ipoints'];
$rep = $userinfo['reputation'];
if ($points > 0)
{
$newrep = ($rep - $points*500);
}
else
{
$newrep = ($rep - 150);
}
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = " . $newrep . "
WHERE userid = " . $userinfo['userid']
);
}
It still will not subtract.
I am running 4.1.4
I really appreciate the help you two are giving me!
Dragonsys
12-23-2015, 10:02 PM
I have tried this code
global $vbulletin, $db, $userinfo;
if ($vbulletin->GPC['points'] > 0) {
$points = $userinfo['ipoints'];
$rep = $userinfo['reputation'];
if ($points > 0)
{
$newrep = ($rep - $points*500);
}
else
{
$newrep = ($rep - 150);
}
$vbulletin->db->query_write("
UPDATE " . TABLE_PREFIX . "user
SET reputation = " . $newrep . "
WHERE userid = " . $userinfo['userid']
);
}
It still will not subtract.
I am running 4.1.4
I really appreciate the help you two are giving me!
Ok, the problem is probably that you are running 4.1.x and we are running 4.2.x. I don't have a pre 4.2 test board.
MarkFL
12-23-2015, 10:19 PM
...I don't have a pre 4.2 test board.
Same here...vB 4.2.1 is the earliest version I have to play with.
vBulletin® v3.8.12 by vBS, Copyright ©2000-2025, vBulletin Solutions Inc.