Once user has posted, can't ever post again - bug in time limit between posts issue
Coyote - October 12, 2006 - 00:09
| Project: | UIE Forum |
| Version: | 4.7.x-1.x-dev |
| Component: | Code |
| Category: | bug report |
| Priority: | critical |
| Assigned: | zoro |
| Status: | closed |
Jump to:
Description
When a user posts to one of the forum areas, and then tries to post again, a message appears telling them that the admin has set a delay between their posts, and that they have to wait.
The problem is, it claims that they posted minus some thousands of seconds before, and won't let them post again, no matter how long they wait, even if, in the settings, the delay is set to zero.
Sample message:
Forum administrators require at least 0 seconds between posts. You last posted -13968 seconds ago
Needless to say, it's hard to use a forum if this is happening. ; )
Is it something possibly to do with different time formatting on different systems or databases?

#1
Looks like the issue is that the forum stores dates as a mysql timestamp field, but then the module code uses strtotime to convert it to a UNIX timestamp. This can give unpredictable results on some systems, depending on things like ceiling of integer values, etc.
#2
I can see how that would cause a problem alright ;)
Can you try setting the time to a number > 0? It's possible that it's only a problem with the post-timeout is 0, depending on how I coded the checker for it (I can't remember off the top of my head)
If this turns out to be the root of the problem then I may look at an alternative way of doing this, but I have a feeling it has to do with the timeout being set to 0.
Daniel
#3
#4
same problem for me too, even with timeout > 0,
I tried with 5 seconds, it shows the error
#5
that ain't good :)
I'll have a look later on
#6
When I first noticed the problem, the timeout was set to the default of 15 seconds. I tried setting it to zero to see if that would fix it - it didn't.
When I looked through the code, it doesn't do a specific "if" to disable the check if it's set to zero - it just does the time calculation based on a delay of zero. Since the problem is probably with UNIX timestamping on differing systems, that still causes a weird time.
Basically, different systems have different ways of handling UNIX timestamps that occur before the initial era (or presumably, after it). In addition to that, they are rendered as an integer representing a number of seconds since the beginning of the UNIX era, and some systems will have a different "ceiling" for how large an integer can be. When you try to stuff a larger integer into the memory space that can only hold a smaller one, you get what look like unpredictable results or negative numbers.
That _could_ be the problem, anyway.
A quick workaround, until the issue is resolved might be to insert a check that completely disables the post timeout check of the value is set to zero. That way, people who are experiencing the issue could still use the forum until it's fixed for real (just without the wait-between-posts functionality).
A note: the post time limit is _not_ checked for admin users.
Coyote
#7
Admins and moderators on a given forum aren't affected by the post timeout - that's by design.
I'll take your advice and remove the check for now though - thanks for the detail!
#8
I figured the admin and mod exclusion was by design (and should absolutely be like that!). : )
You might take a look and see how some other BB systems handle this feature... most of them have some method of preventing too-rapid posts, or other flood-filtering. I'm suspicious of the methods that involve cookies, since a bot could conceivably just reset a cookie and keep posting over and over.
#9
I've been bitten by this issue on this module too, but I've at least found the possible cause and a workaround.
Basically my tests with regular users would give me that same message, except the number of seconds would always be just under -21600 seconds. That is -6 hours, which corresponds to my server being set as American CST, or GMT-06. When I set my server to run as UTC or GMT, this bug then goes away and users are able to post (after the set delay).
This module needs to take the timezone settings into account some how, either when inserting the posts into the database, or when displaying them (and using the calculation to determine the "last time posted").
#10
Oh, and when I now post, the times shown are always set 6 hours into the future, no matter what setting the user or the Drupal system is set at.
#11
Ooooh, excellent, nice find :)
In the (very) near future, the module will move over to using drupal's node system, so this shouldn't be too much of a problem for much longer. If the node-changeover doesn't happen, then I'll be modifying the database and code to store the dates in the same format that drupal does, so as to stop this from happening again.
Thanks for the bughunting!
Daniel
#12
Well, got the posting to work no mater what the timezone setting of the server is. In functions.inc.php, I modified the function uieforum_posted_too_soon($timeout) to look like the following:
/** Checks to see if a user has posted too soon since their last post.
**/
function uieforum_posted_too_soon($timeout)
{
// Need to account for the server's timezone.
Global $user;
$time = time();
$offset = (date("O") / 100) * 60 * 60;
$userslastpost = get_last_post_time_for_user($user->uid);
$ender = $time - strtotime($userslastpost) - $offset;
if($ender <= $timeout)
return $ender;
else
return false;
}
I really don't know if this is "right", but it does seem to work.
#13
Right, so the node changeover hasn't happened yet, and I haven't sorted out this timezone issue. I'm open to suggestion as to how it would be best done without database modifications :)
#14
I would suggest changing F_Posts.Posted to an unsigned integer data type and storing a Unix timestamp there. This is mostly because the datetime data type is specific to MySQL. Using an integer would make it more portable as well as simplify formatting -- see format_date().
Assuming you don't want to alter the database, your only choice is to reconcile the difference in time zones. F_Posts.Posted is in GMT while the time it is being compared to is the local time.
These are my changes (in functions.inc.php)
1) Adjust the local timestamp to GMT (to match the timestamp stored in the database)
around line 1206:
<?php
function uieforum_posted_too_soon($timeout)
{
Global $user;
$localtod = gettimeofday();
$time = $localtod['sec'] + ( $localtod['minuteswest'] * 60 );
$userslastpost = get_last_post_time_for_user($user->uid);
$ender = $time - $userslastpost;
?>
2) Convert the Posted datetime field to a Unix timestamp more reliably:
around line 457:
<?phpfunction get_last_post_time_for_user($uid)
{
$query = db_query("SELECT UNIX_TIMESTAMP(MAX({F_Posts}.Posted)) as Posted FROM {F_Posts} WHERE {F_Posts}.Poster=%d", $uid);
$obj = db_fetch_object($query);
?>
The function get_last_post_time_for_user is only used in uieforum_posted_too_soon() so the return value can be changed with no ill effects. Since it looks like this module is already MySQL only, I don't feel too bad about using UNIX_TIMESTAMP().
#15
This is also an issue in 5.x-1.x-dev and the fix in #14 fixes it as well.
#16
This fix doesn't work for me - the unix time stamp of the last post increases every second.
I don't have time to look any further at the moment, I'll look again tonight.
#17
Rernst - can you confirm for me that this fix works correctly?
Ie: That instant reposting is prevented (timeout) but that posting isn't completely disabled?
#18
It does. I tested with min post intervals of 30 and 120 seconds, and it rejected the post if the user had posted less than that number of seconds ago.
#19
It doesn't behave like that for me - I either can't post at all, or I can post all the time no matter what.
:/
#20
I'm pretty certain that this has been fixed now. If not, then let me know.
The changes probably won't come up until the next tar-run later on tonight.
Daniel
#21