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.
Related
I have a blog and I want to add a function "Notify me of new comments by email" to each post, when the user comments a post.
Im working with PHP and MySQL.
I was thinking about to send a mail to the users who has commented some posts and has checked the checkbox "Notify me of new comments by email" with a query like:
$query = mysql_query("SELECT COUNT(post_id) AS NumberOfComments FROM comments WHERE post_id = $post_id");
$row = mysql_fetch_assoc($query);
if($row['NumberOfComments '] > $NumberOfComments){
mail("someone#example.com","subject","message");
}
But if someone deleted a comment from the post and a new comment has been added then it would be the same number of comments and no mail will be sent. Any ideas on how the query could be better?
It depends on when you want to notify the user.
Do they want to be notified of every comment? Then the functionality which posts the comment would also send the notification. Any time a comment is posted, check for users to be notified and notify them.
Do they want a periodic (daily, weekly, etc.) notification that there exist new comments? Then you still don't want a count. What you want in that case is to check if there exist new records. There are a couple of ways to go about this:
Based on identifiers. If you know the ID of the last comment about which the user was notified (which you may need to store somewhere in a notifications table) then you check if there exist new IDs above that one. If so, there are new comments.
Based on date. If you know the timestamp of the last comment about which the user was notified (which you can store somewhere or calculate on the fly based on the period of notifications) then you check if there exist new comments since that time. If so, there are new comments.
As you've found, simply counting the records isn't a meaningful indication of what you're looking for. All a record count does is tell you how many records there are. If you want to know when those records were posted, you need a timestamp of some kind. If you want to know if records match previously known records, you need an identifier of some kind.
Never assume information derived from data which doesn't hold that information. Store the information you need to know.
Do this mailing on the insertion from the comment to the database, then you dont need this extra query.
EDIT:
So you store the user's who want to get notified in the database
with a table with a id user_id post_id i named it comment_notify
then you can do something like that
// Insert comment to database
$userWhoWantGetNotified = mysql_query("SELECT * FROM comment_notify WHERE post_id = $postId");
while ($entry = mysql_fetch_assoc($userWhoWantGetNotified )) {
$userId = $entry["user_id"];
// get email from user_id
mail(..);
}
i have a example table to store posts like
id|title|content|
now i want count view post like
What is the way to do that thanks
You should have a field in your table to store the views count, so you can update the count of viewers with something similar to:
UPDATE `table` SET `views` = `views` + 1 WHERE `id`= $post_id
You may want to avoid spamming by refreshing the page or make sure its a unique viewer. There are several ways you can do that.
If you want to be serious about it you will have to use a table to store IP addresses and relate them to viewed posts in order to not count again, like Gautam3164 suggested.
But creating new records every time a client view a post can be too computationally expensive and, unless its strictily necessary for the case, it should be avoided.
You can instead abuse the $_SESSION to store the IDs of the recently viewed posts, in order to not increment the counter if the same client view them again.
For instance:
if (!isset($_SESSION['recent_posts'][$post_id])) {
mysql_query("UPDATE `table` SET `views` = `views` + 1 WHERE `id`= $post_id");
$_SESSION['recent_posts'][$post_id] = 1;
}
It should solve the spam problem in a very simple and cheap way.
For that you have to add one column in your table.
For example lets say,
You have column name Views
You have to put update query on the top of the page like this
UPDATE table SET Views= Views+1 WHERE ID= 'current page id'
You can make a new table called Counter as example the table contains:
post_id|views
when ever the user visit the page you increment this counter
or you can add a field called views in the same posts table
if you want to count unique views you may store IP ADDRESS as will and check if the ip exists you don't increment that view.
You can get the ip address in php like this:
$_SERVER['REMOTE_ADDR'];
The best way doing that would be using cookies you can refer to this for it.
You may need to store the IPaddress of the viewer using $_SERVER['REMOTE_ADDR'] of the page was opened and store it in DB with that page id and each time you need to check for the maintaining the unique IP addresses.
Means you need to enable the increment of the page view count for the single IP address.
1) First Check for the DB that whether the page view with the current IP address($_SERVER['REMOTE_ADDR']).
2) If is already exists then do nothing.
3) If there is no ,then add a row into DB with the current page id and ip address.
4) Then extract/count the number of views as counting the rows from DB with that page id.
Every time you need to repeat these things.You can also use LOGIN system for mainting the page count.
I'm developing a blog system with php and mysql with the following db structure:
Article
-id
-firstMessage
-lastMessage
-body
Comment
- id
- article_id
- publiched_date
- body
The idea here is make use of pagination, where the article with a lot of comments shows a link tree like [first][1][2][3][last], 10 comments by page. Everything goes fine, I have create a nice sql that select 10 messages according to the page number by url:
example.com/?article=3&page=2
Where is the ploblem? Well, supponse that I have this url in my homepage:
example.com/?article=3&message=3565
According to the url above, How can I determinate the page number where this message is? Do you have any idea to guide me to the right direction?
Edit
The messages ids are not consecutives, for example, an article could have the comments: 125, 364, 561, 1522
If you show 10 comments per page and request message 3565, you can do this:
$pageNumber = floor($_GET['message'] / 10) + 1;
EDIT
Thanks #Alix.
EDIT #2
After the edit made to the OP, without seeing what the database structure looks like, worst-case scenario, you'd have to fetch the whole list of comments as it would appear on the site and find the index of the message you're looking for.
I realize that's not necessarily what you wanted to hear, but there's no real other way to know without seeing what your database looks like.
Basically, select the comments from the same article, sorted by ID (or another column if the id can be out of order--non-consecutive is fine), and do a little math with the result. Here's the code (demo):
SELECT (
SELECT CEILING((count(*) + 1) / 10)
FROM `Comment`
WHERE `id` < `comment`.`id`
AND `article_id` = `comment`.`article_id`
) AS `page`
FROM `Comment`
WHERE `id` = ?
AND `article_id` = ?
Simply plug in the comment ID and article ID where the ? are (or, even better, use this exact code in a prepared statement). If you change the number of comments per page, make sure you change the 10 in the query as well.
For this query, you just need an index on article_id (and a PRIMARY index on id).
I guess you have to make a query, something like that should work :
SELECT CEIL((COUNT(id) + 1) / $nb_message_per_page) AS page_for_message
FROM comment
WHERE article_id = $article_id
AND published_date < (SELECT published_date FROM comment WHERE id = $message_id)
Depending of the sorting choose for displaying comments you have to change the < for a >, that query assume a published_date DESC sorting
PS: I don't know if it's a typo or not but you have write publiched_date in you DB schema
EDIT
If no sorting are made, rows are probably sort by PRIMARY KEY which will be like a published_date DESC sorting
EDIT 2
As #bfrohs says this query give inaccurate results (for one case but it will happen) if the test (<) is on published_date (or any other column containing non-unique data) instead of id.
As there are no ordering, using id is a better solution.
You need to set the number of items to display per page and use that to divide the messages into pages
It's rather non-trivial to go from a message-number back to a page. Easiest method is to simply pass the page number in to the message reading script, so you can simply embed that page number in your "back" link, eg...
messages.php:
1234
readmessage.php:
Back
this'll save you the trouble of having to calculate which page you came from, since you simply carry the page number along with you.
I have a website where users can rate comments that are left on pages. Each comment has a unique ID (E.g. 402934) If I want users to be able to thumb-up/thumb-down said comments I can see how I would make a simple counter code to keep track of the number of thumb-ups vs thumb-downs but how can I make sure that each user only ranks said comment once. I was going to make a database with each comment number as a row and in that row having an array of all the users that have ranked it thumbs up and all the users that have ranked it thumbs down but I had a feeling that wasn't the best way. My next thought was to have a table for each user and then having an array showing all the comments said user has ranked. It would probably run faster this way (e.g. checking from a user's 150 rankings verse a comment's 6050 rankings but I still feel like there is a better way... any ideas?
Create a new table with user_id, comment_id and vote TINYINT(1).
A value of 1 in vote is a thumbs up, A value of 0 in vote is a thumbs down.
Have a UNIQUE KEY constraint on (comment_id, user_id).
If you follow the above it will be easy to check whether a user has cast a vote on a specific comment, if you'd like to be able to quickly (as in fast execution) see all the comments a user has made you should also add an INDEX to user_id.
When a user votes you could use REPLACE INTO to user_comment_thumbs, such as the below:
REPLACE INTO `user_comment_thumbs` (user_id,comment_id,vote)
VALUES (#user_id, #comment_id, #vote);
If the user has already made a vote the entry in the table will be updated, otherwise a new row will be inserted.
I've got a website where people can make posts and comment on them. I want to make a new comment notification system, so when a user logs in he can see number of new comments to his posts.
My idea is to add a 'read' table, where I will store user_id and comment_id (means user_id read comment_id). But this can make some performance issue, when table will grow big.
What's the best way to implement this?
One way to achieve that is just to save a created date for post and comment, and a "last visit" date for the user (or "last time the user click on the "show me new post" link).
Then, you just need to get all the post and comment that have a newer date than the one you find in the user table.
How about just storing the user and comment IDs for unread comments instead? Then when the user reads the comment, you can delete that row from the table.
Wouldn't it be better to store the post time in the notifications table and then look for the user's last activity (again storing the value in the users table). Then you could do a simple query:
$lastActivityTime = User->GetLastActivity();
$result = mysql_num_rows(mysql_query("SELECT COUNT(`id`) FROM `notifications` WHERE `postTime` > '$lastActivityTime'"));
Good luck!
You can choose a different storage than mySQL for this data (Like : MongoDB).
Or you can make pub/sub implementation for notifying users. (With using pubsub you dont need to store data. Just notify)