Limiting activity via PHP - php

I have a social network that allows users to post blogs, ask questions, and message. We have had a slight issue with spamming. For example, we had users sign up, and write about 6 blogs a minute trying to sell stuff.
I am looking for a quick way to limit these activities by the id of the user, let's say only allowing them to post 3 blogs a day.
I have the users stored in a $auth variable and through OOP bring them up by $auth->id for example to be more specific.
Looking for a fast,simple way to do this via php.
thanks in advance /**EDIT*****/
this is what I have so far, and I know for sure $too many is counting as it should, but for some reason my if(statement is not stopping the 4th blog from posting. HERE is the code

Something like CAPTCHA would be appropriate. However, if they're being entered manually, it will do little to stop them. Regardless, no reason you can't implement both methods.
I'm assuming you have a created field in your blogs table. Simply query the table for the number of blogs with today's date before allowing another to be posted. Not sure what database/API you're using. In MySQL, you could do:
SELECT COUNT(*)
FROM blogs
WHERE user_id = USERID
AND DATE(created) = '2011-11-30'

When the user writes and submits a post, save the date they posted on the post's table. Select and count the amount of times they posted today. If they are under their limit, allow the post or else give them the error/warning message.

When a post is made, do something like:
// Get last post time and number of posts today from database
$query = "SELECT
last_post,
posts_today
FROM
users
WHERE
id = '$auth->id'";
$result = mysql_fetch_assoc(mysql_query($query));
// See if this is the first post today
$isNewDay = date('Y-m-d') != date('Y-m-d',strtotime($result['last_post']));
$postsToday = ($isNewDay) ? 0 : (int) $result['posts_today'];
// Only add post if user is allowed
if ($isNewDay || $postsToday < 3) {
/*
Add the post to the database here
*/
// Update the number of posts today in the database
$query = "UPDATE
users
SET
last_post = '".date('Y-m-d H:i:s')."',
posts_today = '".($postsToday + 1)."'
WHERE
id = '$auth->id'";
mysql_query($query);
} else {
echo "You have already made 3 posts today!";
}
...or you could just use a CAPTCHA (as mentioned by others). That's what they're for. Really, you should have one in the signup process...

I'll admit I know next to nothing on PHP programming, but another option (or addition to the CAPTCHA) would be to use a service such as StopForumSpam
There's an example of how to use it here (no idea how good it is, as I don't code PHP (yet)) :)

Related

PHP/MySQL (eFiction) Preventing Multiple Ratings from single user

On my site (which uses the CMS eFiction) users can leave reviews with a rating on chapters of 1-10, if they don't rate the chapter it's logged on the table as a -1. I want to prevent users from leaving multiple ratings. My PHP knowledge is very limited, I believe the code should go before line 144 in review.php (on github here)
dbquery("INSERT INTO ".TABLEPREFIX."fanfiction_reviews (item, type, reviewer, review, rating, date, uid, chapid) VALUES ('$item', 'ST', '$reviewer', '$review', '$rating', now(), '".(USERUID && isNumber(USERUID) ? USERUID : 0)."', '$chapid')");
I'm trying to write a query for the fanfiction_reviews table and if finds an entry that matched the uid (user) and chapid and has a rating, throw them an error message that they already rated the chapter. ETA: To answer a question below, I want the 2nd rating to be ignored or not logged, rather than replacing a previous rating.
As I mentioned, my PHP is limited, I just try to mimic what I find elsewhere in eFiction. Edit: in the following initially had changed useruid = '$uid' which was giving me a fatal mysql error. I changed it to uid = '$uid' and the stopped the error
$ratecount = dbquery("select count(rating) as count FROM ".TABLEPREFIX."fanfiction_reviews WHERE item = '$item' AND chapid = '$chapid' AND uid = '$uid' AND rating != '-1'");
if($ratecount != 0) $output .= write_error(_MULTIPLERATINGS);
With the above pasted in the file, it does give me the "multiple rating error" message BUT it's still logging the rating. How do I get it to not log the rating (or change it to the non-rating of -1)
Thanks in advance for any help!
Try if($ratecount.count != 0) $output .= write_error(_MULTIPLERATINGS);. It's also possible you may need to format it as if($ratecount["count"] != 0) $output .= write_error(_MULTIPLERATINGS);.
As yet another contingency, you might need to loop through the result set, or put a [0] in there to indicate that you want to access the "count" field of the first row in the result set. Your mileage may vary depending on exactly what dbquery() does. Keep in mind that there are many different ways of connecting to, and interacting with a database in php, and different implementations may return results in different ways, and may adhere to slightly different conventions. AFAIK, dbquery() is not a standard function in php.

Count the number of times post has been viewed

I am working on a project where only title of posts are shown on main page and on clicking the title, full post is loaded on another page posts.php code for this is:
<?php echo $row['title']; ?>
Now to count post views I have a column hits in my posts table ,initially value of hits is set to 0 and whenever a post is opened value of hits is increased by 1, for this my code is in posts.php
$id = $_GET['postId'];
$sql = "UPDATE posts SET hits = hits + 1 WHERE post_id = $id";
But this is not a good practice for tracking post views as views increase whenever page is refreshed. I want a clean system to track post views where, for every distinct user or visitor views increase by one irrespective of fact how many times the same user/visitor views same post (as in stackoverflow). Like tracking them by their IP address or something else, just an idea (how these guys do it) or how the stuff works would be enough to let me start my work.
You cannot solve your problem so simply. Your problem is counting unique users who view a page (with, perhaps a time component). You have several problems, as described in the comments. The first is determining what you are counting. For a prototype, IP address is good as anything else for getting started. However, it has many short-comings, and you will need to think hard about identifying a "visitor".
There is a way to solve your problem in SQL, sort of efficiently. But, it requires an additional table at the level of post/visitor. It will have one row per combination, and then you will need to count from there. To quickly get the unique counts, you then need an insert trigger on that table.
Here is a sketch of the code:
create unique index unq_postvisitors_post_visitor on postvisitors(postid, visitorid);
insert into PostVisitors (postid, visitorid)
select $postid, $visitorid
on duplicate key update set counter = counter + 1;
delimiter $$
create trigger trig_PostVisitors
after insert on PostVisitors
begin
update posts
set numvisitors = numvisitors + 1
where posts.post_id = new.post_id;
end;$$
delimiter ;
Simplest way I use to solve this problem is through cookies.
Whenever your page is opened, you check if there's set cookie_name cookie through isset($_COOKIE[$cookie_name]).
If isset returns false, you set a cookie through setcookie(cookie_name, value, expire);, maybe setting expire time to 24h (you have to set it in seconds, so 24h is 84600). Also, you trigger your counting systems with a +1 to your visitor counter.
If isset returns true, do nothing.
PHP Cookies Refs
Try this It'll Work
$refreshed = $_SERVER['HTTP_CACHE_CONTROL'];
if ($refreshed == 'max-age=0'){
$sql = "UPDATE posts SET hits = hits + 1 WHERE post_id = $id";
}
Try this script on the page $_SERVER['HTTP_CACHE_CONTROL'] get place when page is refreshed

How can I successfully implement a "Remember This Action" routine?

I am really having a difficult time getting started with this task.
I have 2 forms on same page.
The first form provides a search box for users to enter one of several search filters like Address, Zip Code, Streets, landlots, even the state name.
If the search produces several results, the user can then click on Advanced Search link.
This Advanced Search contains several checkboxes that allow users to check one or more boxes to narrow their search results.
This works great.
The issue now is to give the user the ability to "save" their search results perhaps using cookies so that next time the user loads this page, the search result
s/he saved last time will become his/her default search page until they change it or until they remove the cookies which wipes out this last Action.
This is more like remembering user's last action when s/he searched this page last time.
My thinking so far, first of all, is to store the SQL query in a Session variable in the php code.
Then, when the user clicks on "Remember This Action" button that I am going to create", I could just have my php code save that session variable value in a cookie.
In other words, I would do something like this:
$tsql = "SELECT Name, FeatType,
MinX, MinY, MaxX, MaxY
FROM mytable
ORDER BY ListOrder, Name DESC";
Session("LastAction") = $tsql
And then have the "Remember This Action" button post to an my php page that simply does:
Cookies("LastAction") = Session("LastAction")
Cookies("LastAction").Expires = Date() + 365 ' expires in one year
Finally, I can provide a "Repeat Last Action" button on our pages and all it does is
$tsql = Request.Cookies("LastAction")
$stmt = sqlsrv_query( $conn, $tsql);
One of the many issues that I am having is that I can't even get beyond this query:
$tsql = "SELECT Name, FeatType,
MinX, MinY, MaxX, MaxY
FROM mytable
ORDER BY ListOrder, Name DESC";
Session("LastAction") = $tsql
I keep getting "invalid" error on
Session("LastAction") = $tsql
Obviously, I am very, very weak on php but working hard to come to speed.
Your assistance is greatly appreciated
I have made some baby steps here.
I am able to get this syntactically correct:
$_SESSION["LastAction"] = $tsql;
I am also able to set the correct
setcookie('LastAction',$_SESSION["LastAction"],time() + (86400 * 365)); // 86400 = 1 year
Now, what is the equivalence of this line in php?
$tsql = Request.Cookies("LastAction")
Above was my best stab at it but I don't think it is correct.
I am basically trying to put a "Remember Last Action" buttonn on another page.
Then use:
$tsql = Request.Cookies("LastAction")
to grab values from another page into this page.
What you are doing here is, basically, saving an SQL query to a cookie (user-editable data).
setcookie('LastAction',$_SESSION["LastAction"] /*We're saving the value, not the session. */,time() + (86400 * 365)); // 86400 = 1 year
Regardless, instead of fooling around with resurrecting sessions based on a sessid saved in a cookie, I'd recommend saving the search flags into a cookie as a serialized array, and then just do your run-off-the-mill search using that data when you need to reuse it.
Basically, you can do:
$saved_search = serialize($search_opts);
setcookie('SavedSearch',$_SESSION["LastAction"],time() + (86400 * 365));
And to reverse the process,
$saved_search = $_COOKIE['SavedSearch'];
$search_opts = unserialize($saved_search);
You will need to figure out from your own code where to snag the $search_opts and how to use them later to run a search, as I do not see the code that makes that part tick.

Ensuring users do not spam "like" button

My friends and I are creating a petition board and i'm adding a like/dislike function to it. I intend to make it such that only users can like/dislike it. Problem is, I do not know how to ensure that the users do not spam the button multiple times and how to register which user has liked/disliked which topic. Below is my code so far.
EDIT: Thanks I am creating the likes/dislikes table right now. But now I have to compare the users with the database to see if they have previously liked a comment. I know I have to use WHERE (to check both likes and dislikes table) but i am not sure how to combine it with IF.
<?php
include connect.php
if (isset($_POST['like']) || isset($_POST['dislike']))
{
if($_SESSION['signed_in']){
if (isset($_POST['like'])) {
$sql="UPDATE
topics
SET
likes=likes+1,
WHERE
id=topic_id";
echo "You liked it";
}
elseif (isset($_POST['dislike'])) {
$sql="UPDATE
topics
SET
dislikes=dislikes+1,
WHERE
id=topic_id";
echo "You disliked it";
}
}
else{
echo 'Please log in.'
}
?>
You should have a table of "likes" with the following columns.
"article_id", "user_id", the primary key should contain both columns
Every time a user likes an article, INSERT INTO likes VALUES($article_id, $user_id);
It will fail if someones Likes twice, thanks to the primary key.
Every time a user dislikes, DELETE FROM likes WHERE article_id = $article_id AND user_id = $user_id. That will allow the user to like again if he wants.
To get the number of Likes for an article, run a SELECT COUNT(*) as nb_of_likes FROM likes WHERE article_id = $article_id instead of storing the number in the article table.
Makes sense ?
The following solutions are possible, which can be used together:
If you use a registration/login mechanism, then you could internally setup some counting mechanism so each user can like once per petition (like Bgi suggested).
You could store a cookie, preventing him for further liking, even if he creates a new user.
Of course people can delete cookies or use other browsers, so you could hash their IP with e.g. md5 and compare the hash if that hash was already using the petition.
Of course multiple people can share the same IP, so IP hashing might not always be a good solution. Alternatively, you could use facebook API, and require that people have some amount of friends or something in order to verify their authenticy.
You will never fully be able to get rid of spammers, depends on how specific is your petition. Hence the more you want to prevent exploiting from using the petition, the less anonymous it will be.

PHP "You have () new comments on your clip", how?

I want to do a function to my users, so on index.php there is e.g:
You have 2 new comments on your clip
How should i do this? I mean i want ideas to do this the easiest way. Table for the videos is member_videos, and tables for the comment is member_videocomments, a comment inside the table is connected by their "videoID", which is the id of the column in member_videos.
Should i do the classic, making a field, which all is 0, until it has been seen by the user its 1 or what should i do.
One alternative to the unread flag on each comment is a last_read_comments timestamp on the user record. Whenever they read their new comments, update the timestamp to the current time. When they land on your homepage, query for all comments newer than that timestamp value.
Why don't you just do a check when you load the video against the comments table that says something like
SELECT COUNT(*) FROM member_videocomments WHERE videoID = videoIDLoaded;
Then get the result set back as an integer and check if that integer is equal to 0, if it is then display 0, else query the database for the comments get the result set back and display all the comments on the page however you like.
Just update a field in the table member_videocomments, something like readbyuser. Leave it at zero until the user views that specific comment.
$result = mysql_query("SELECT id FROM member_videocomments WHERE !readbyuser");
$num_rows = mysql_num_rows($result);
You've given the answer yourself. Just mark the comments when they are actually being displayed to the user. Assuming new comments are not viewed all at once but instead per video clip, I don't think the timestamp approach would be a good solution, because when you update the timestamp once the user has opened one of their newly commented videos, you will lose track of other new comments.
I have a similar situation, and I am using a is_read flag. When comments are added to the database, is_read is set to 0. When a user logs in, I check for any unread comments (it's here that I grab the # of unread comments so I can display it). Then when they view them, I grab the IDs of the comments and run a query to set their is_read to 1.
Matthew's timestamp solution is also good, so really it's up to what you feel more comfortable with.

Categories