PHP/MySQL different value for each row - php

I've searched and I've tried many different things but I haven't been able to come up with anything to work the way I want. What I have is a direct message system but I want to show next to the users name how many new messages they have from that person if it's more than 0. Everything I've tried just shows one value for all of the conversations. In my database I have a column that is if the user who received the message read it, if they had it turns the 'no' into a 'yes', otherwise it shows 'no'.
Thanks in advance for your help!
EDIT:
One thing for my database...Only the first message in the conversation has both the to_id and from_id after that all the other messages in the conversation only has the from_id. So what I'm trying to do is count how many where the from_id is not your user_id, so the non-signed in user user_id. If that makes sense.
Here is my code accessing the database:
// Get the conversations
$get_conversations = "SELECT dm.convo_id, dm.message_id, dm.to_id, dm.from_id, dm.user2read, u.name, u.user_id" .
" FROM users u" .
" JOIN direct_messages dm" .
" ON dm.from_id = u.user_id" .
" OR dm.to_id = u.user_id" .
" WHERE u.user_id = " . $_SESSION['user_id'];
" GROUP BY dm.convo_id" .
" LIMIT 1";
// Run the conversation query
$convo_result = mysql_query($get_conversations);
And then some HTML code
And more php in the body tags
<?php
while ($teg = mysql_fetch_array($convo_result)) {
if($teg) {
$to_id2 = $teg['to_id'];
$from_id2 = $teg['from_id'];
if($from_id2 == $_SESSION['user_id']) {
$id_of_other_person = $to_id2;
} else if($from_id2 != $_SESSION['user_id']) {
$id_of_other_person = $from_id2;
}
// Get the name of the other person
$get_other_name = "SELECT name FROM users WHERE user_id = " . $id_of_other_person;
// Run the query on the other person's name
$query_name = mysql_query($get_other_name);
if($query_name) {
$yelp = mysql_fetch_array($query_name);
$name_of_other_person = $yelp['name'];
}
$get_user2read = "SELECT dm.convo_id, dm.message_id, dm.to_id, dm.from_id, dm.user2read, u.name, u.user_id" .
" FROM users u" .
" JOIN direct_messages dm" .
" ON dm.from_id = u.user_id" .
" OR dm.to_id = u.user_id" .
" WHERE u.user_id = " . $_SESSION['user_id'];
" AND user2read = 'no'" .
" GROUP BY dm.convo_id" .
" LIMIT 1";
$query_user2read = mysql_query($get_user2read);
$alg = mysql_fetch_array($query_user2read);
?>
<?php if(COUNT($alg['user2read']) > 0 && $alg['user2read'] == 'no') : ?>
<h3>You have <?php echo COUNT($teg['user2read']); ?> new messages - from <?php echo $name_of_other_person; ?></h3>
<?php else : ?>
<?php endif; ?>
<?php
}
}
?>
I would post in image of my direct_messages table but I don't have enough reputation...
Here is a diagram of my table:
Field Type Collation Attributes Null Default Extra Action
convo_id bigint(20) No
message_id int(11) No
to_id int(11) No
from_id int(11) No
message varchar(5000) latin1_swedish_ci No
timestamp timestamp No CURRENT_TIMESTAMP
user1read varchar(3) latin1_swedish_ci No
user2read varchar(3) latin1_swedish_ci No
EDITED: I erased the backslashes

This is not correct:
<h3>You have <?php echo COUNT($teg['user2read']); ?> new messages - from <?php echo $name_of_other_person; ?></h3>
count() is used for arrays, but the elements of $teg are just the column values from the table. If you want to count records grouped by a column, you need to use the MySQL COUNT() function in your query. Or in this case, since you only want to count messages that fit a specific criteria, use SUM():
$get_conversations = "SELECT dm.convo_id, dm.message_id, dm.to_id, dm.from_id, u.name, u.user_id, SUM(dm.user2read = 'no') unread_count" .
" FROM users u" .
" JOIN direct_messages dm" .
" ON dm.from_id = u.user_id" .
" OR dm.to_id = u.user_id" .
" WHERE u.user_id = " . $_SESSION['user_id'] .
" AND dm.user2read = 'no' " .
" GROUP BY dm.convo_id" .
" LIMIT 1";
Then you can use $teg['unread_count'] to get the count of unread messages in that conversation.
I don't think you need the inner query $get_user2read. All the information is in $get_conversations now. It was wrong, because it wasn't getting the row specific to the conversation in that iteration of the loop.

This
$yelp = mysql_fetch_array($query_name);
$name_of_other_person = $yelp\['name'\];
looks wrong.
You need to loop the $yelp like you did $teg.

Related

PHP JOIN Two MySQL table in result

I have two MySQL table for insert comment data and reviews data like this :
comments:
|id|post_id|text|name|timestamp|approved|parent_id|type|ip|
reviews:
|id|postID|comments_id|reviewfield1|reviewfield2|reviewfield3
in action I insert for each comments One reviews. Now, I need to show/print comment list with comment name and text + reviewfield1 reviewfield2 reviewfield3 for each comments where comments is approved like this :
commenter 1
text
reviewfield1
reviewfield2
reviewfield3
TRY:
"SELECT name,text,timestamp FROM " . COMMENTS . " LEFT JOIN " . REVIEWS . " WHERE " . COMMENTS . ".id = " . REVIEWS . ".comments_id AND
post_id = ? AND type = ? AND approved = 1 ", $id, $type"
But this not work for me. how do generate this with PHP JOIN method?
You are making mistake in the query. It must be like this:
"SELECT name,text,timestamp,reviewfield1 FROM " . COMMENTS . " LEFT JOIN " . REVIEWS . " ON " . COMMENTS . ".id = " . REVIEWS . ".comments_id WHERE
post_id = ? AND type = ? AND approved = 1 ", $id, $type"
And you can select rows from the second(joined) table, same as the first one.

threaded comments using php mysql

I have this table for insert comments data:(comments)
|id|message|timestamp|approved|parent_id|name|email|
and this table for insert reviews for comments:(reviews)
|id|cid|review_field1|review_field2|review_field3|...
php function :
function _comments_($id,$type){
$DB = mySqli::f("SELECT id,name,email,message,timestamp,review_field_1,review_field_2,review_field_3 FROM " . NEWS_COMMENTS . " LEFT JOIN " . NEWS_REVIEWS . " ON " . NEWS_COMMENTS . ".id = " . NEWS_REVIEWS . ".cid WHERE
pid = ? AND type = ? AND approved = 1 ORDER BY timestamp DESC LIMIT 12", $id, $type);
foreach($DB as $row){
$commentdata[] = $row;
}
return $commentdata;
}
for result:
<?PHP
$comments_list = _comments_('125','news');
foreach($comments_list as $row):
?>
/// HTML tags
<?PHP
$endforeach;
?>
This worked for me and show list of comments and reviews for each comments.
Now i need to show threaded comments(parent) for each comment.
how do can i show threaded comments ?!
NOTE: for parent comment i dont send reviews.

Grabbing info from two different tables, assistance

I am trying to make a members page. For the rank it shows numbers so I made another table that has the rank id (1,2,3 etc) and added a name to it also.
Here is my code.
<?php
$getCoB = mysql_query("SELECT * FROM `members`
WHERE `CoB` = '1' && `user_state` = '1' ORDER BY `id`");
$id = ($getCoB['rank']);
$rankInfo = mysql_query("SELECT * FROM `ranks` WHERE `id` = '".$id."'");?>
<h2 class="title">Council of Balance members</h2>
<style>tr:nth-of-type(odd) { background-color:#F0F0F0;}</style>
<div style='padding:5px;'>
<?php
if(mysql_num_rows($getCoB) == 0)
{
echo "There are no Council of Balance members.";
} else {
echo "<table cellpadding=20 width=100%>";
while($row = mysql_fetch_assoc($getCoB))
{
echo "<tr><td style='background-color:transparent;'><b>". $row['name']
. "</b></td><td>Rank: ".$rankInfo['name']." <br/> Role: ". $row['role']."</td>";
}
echo "</table>";
}
?>
The problem is rankInfo['name'] is not showing up. I tried to do something on this line while($row = mysql_fetch_assoc($getCoB)) and tried to make it something like this while($row = mysql_fetch_assoc($getCoB)) || while($rank = mysql_fetch_assoc($rankInfo) and changed this part <td>Rank: ". $rankInfo['name'] . " to this <td>Rank: ". $rank['name'] . " but I end up with an error. If I leave it like it is, it just shows Rank: without the name I added into my database.
You can combine your two queries into one using an inner join.
<?php
$getCoB = mysql_query("SELECT m.name as member_name, m.role, r.name as rank_name
FROM `members` as m INNER JOIN `ranks` as r ON m.rank = r.id
WHERE `CoB` = '1' && `user_state` = '1' ORDER BY m.id");
?>
Because of how INNER JOIN works, this will only display members who have corresponding records in the ranks table. If there are some members that you want to display that have no rank record, use LEFT JOIN instead.
Then when you echo out the data, be sure to refer to the item you have fetched ($row) each time. In your code, you are referring to $rankInfo['name'], where $rankInfo is not a variable, but a mysql query from which no rows have been fetched.
while($row = mysql_fetch_assoc($getCoB)) {
echo "<tr><td style='background-color:transparent;'><b>". $row['member_name']
. "</b></td><td>Rank: ". $row['rank_name'] . " <br/> Role: " . $row['role'] . "</td>";
}

Can't get score to update with this mysql statement

I'm guessing that I'm just a little rusty or something because it seems like this should be working. Am I missing something here...
Here is the code I am trying to use...
<?php
echo dbConn();
$existing_time = mysql_result(mysql_query("SELECT p_time FROM scores WHERE p_uid=$uid"), 0);
$existing_category = mysql_result(mysql_query("SELECT p_cat FROM scores WHERE p_uid=$uid AND p_cat=$pieces"), 0);
if ($existing_category == "") {
mysql_query(
"INSERT INTO scores VALUES (
'',
'$uid',
'$pusername',
'$time',
'$pieces'
)");
} elseif ($existing_time <= $time) {
echo "No Change! Old Score Was Better (Lower)";
} elseif ($existing_time > $time) {
mysql_query("UPDATE scores SET p_time = " . $time . " WHERE p_uid = " . $uid . " AND p_cat = " . $pieces . "");
};
?>
Now... Here is what I am trying to do...
I am collecting info from the database where the users username AND category match. If the category for that user does not exist, it inserts the latest score. (This much works.)
Then, if the category does exist but the old score is better, it just does nothing. (This part works too)...
However, what I can't seem to do is get it to update the last score, if the current score is better (lower score, since this is a time based game.) It doesn't update the score.
I am trying it this way: By updating a row in "scores" where the USERNAME and the CATEGORY match at the same time.
Please note... where it says "pieces". this is a category. Where it says "time", this is a score. The score is returned as 00:00:00 for hours minutes and seconds.
EXAMPLE: (in parentheses is the database row name)
id (ID) = just KEY id in sequencial order
user id (p_uid) = 123456789
username (p_username) = somename
score (p_time) = 00:01:03
category (p_cat) = 10
Change you update statement to:
mysql_query("UPDATE scores SET p_time = '" . $time . "' WHERE p_uid = " . $uid . " AND p_cat = " . $pieces . "");
You have missed quotes in the update statement around $time.

How to control last visitor ip through sql and php?

I am trying to make a unique visitors counter for my pages using mysql and php. Im my DB table i have a "views" column and a "last_ip" column.
If the ip of the current user is equal to the last ip stored on DB the counter dies, if the current user ip is different from the last ip stored on DB the current user ip is stored as last ip on DB and the counter sums +1 to the views on DB.
The main idea is:
1 - check the ip of the current user and save it to variable $viewer_ip
2 - check the last ip stored on DB and save it to variable $last_viewer_ip
3 - compare those 2 variables, if $viewer_ip =! $last_viewer_ip the function should store $last_viewer_ip in "last_ip" field and sums +1 in "views" field. Else it should do nothing.
<?php
$viewer_ip = $user_ip = $h->cage->server->testIp('REMOTE_ADDR');
$sql = "SELECT post_last_viewer_ip FROM " . TABLE_POSTS . " WHERE post_id = %d";
$last_viewer_ip = $h->db->get_var($h->db->prepare($sql, $h->post->id));
if ($viewer_ip AND $viewer_ip != $last_viewer_ip) {
$sql = "UPDATE " . TABLE_POSTS . " SET post_last_viewer_ip = '" . $viewer_ip . "' WHERE post_id = %d";
$h->db->query($h->db->prepare($sql, $h->post->id));
}
if ($viewer_ip != $last_viewer_ip) {
$sql = "UPDATE " . TABLE_POSTS . " SET post_views = post_views + 1 WHERE post_id = %d";
$h->db->query($h->db->prepare($sql, $h->post->id));
}
?>
that code works in parts, cause it sums like 3 views, on each visit, as u can see, that code is a trash, cause i did it myself and i am no expert.
Anyone can try a fix on this? ty.
You need to store the session id of your visitors to the database to be able to do that kind of thing correctly. A unique visitor is considered one that is there for one specific session. If the user closes the browser and comes back, then it is another visitor.
If you want truly unique visitors, you need to store cookies too and use them to identify your visitors, but then again, cookie blocked? Cookie flushed? You're screwed...
Last method is to force a login, with a login you usually have a user_id, that user_id becomes your unicity.
I'll let you decide how you want to handle your unicity...
For the storage part, you need at least 1 table where you store the requests and identity of your requesters. Store in that table the following information:
Page/SpecificRequest
UserIP/SessionID/CookieID/UserId
RequestDate
RequestTime
Then on each page request, store a request in that table such as:
INSERT INTO myrequests VALUES(
$_REQUEST['URI'],
session_id(),
date('Y-m-d'),
date('G:i:s')
)
And then, to retrieve the unique visitor count, you just group on the data:
SELECT RequestDate, COUNT(*) AS uniquevisitors
FROM myrequests
GROUP BY RequestDate, session_id()
Good luck
Try it this way..
You need one separate table (TABLE_WITH_LOGS) for IP logs, which has 3 columns post_viewer_ip varchar(15), timestamp timestamp, post_id bigint (or whatever type you have for you post ids).
The code will look something like that one..
$timeout = 30*60; // count as a new visit after 30 minutes
$viewer_ip = $user_ip = $h->cage->server->testIp('REMOTE_ADDR');
// check if there is a record within the timeout period
$sql = "SELECT count(*) FROM " . TABLE_WITH_LOGS . " WHERE post_id = %d
AND ip = '%s' AND `timestamp` > NOW() - $timeout";
$rows = $h->db->get_var($h->db->prepare($sql, $h->post->id, $viewer_ip));
if ($rows == 0) { // no recent records in DB, insert new one
$sql = "INSERT INTO " . TABLE_WITH_LOGS . " SET post_viewer_ip = '" .
$viewer_ip . "', `timestamp` = NOW() WHERE post_id = %d";
$h->db->query($h->db->prepare($sql, $h->post->id));
// update counter
$sql = "UPDATE " . TABLE_POSTS . " SET post_views = post_views + 1
WHERE post_id = %d";
$h->db->query($h->db->prepare($sql, $h->post->id));
}
else { // there is at least one record, update it with current timestamp
$sql = "UPDATE " . TABLE_WITH_LOGS . " SET `timestamp` = NOW()
WHERE post_id = %d and post_viewer_ip = '$viewer_ip' LIMIT 1";
$h->db->query($h->db->prepare($sql, $h->post->id));
}
// cleanup table from time to time
if (rand(1,5)<2) {
$sql = "DELETE " . TABLE_WITH_LOGS . " WHERE `timestamp` < NOW() - $timeout";
$h->db->query($sql);
}
ps: you may skip part with timestamp update and always insert a new record. It will make less (only by one :)) SQL requests.
$timeout = 30*60; // count as a new visit after 30 minutes
$viewer_ip = $user_ip = $h->cage->server->testIp('REMOTE_ADDR');
// check if there is a record within the timeout period
$sql = "SELECT count(*) FROM " . TABLE_WITH_LOGS . " WHERE post_id = %d
AND ip = '%s' AND `timestamp` > NOW() - $timeout";
$rows = $h->db->get_var($h->db->prepare($sql, $h->post->id, $viewer_ip));
if ($rows == 0) { // no recent records in DB, update counter
$sql = "UPDATE " . TABLE_POSTS . " SET post_views = post_views + 1
WHERE post_id = %d";
$h->db->query($h->db->prepare($sql, $h->post->id));
}
// record last visit
$sql = "INSERT INTO " . TABLE_WITH_LOGS . " SET post_viewer_ip = '" .
$viewer_ip . "', `timestamp` = NOW() WHERE post_id = %d";
$h->db->query($h->db->prepare($sql, $h->post->id));
// cleanup table from time to time
if (rand(1,5)<2) {
$sql = "DELETE " . TABLE_WITH_LOGS . " WHERE `timestamp` < NOW() - $timeout";
$h->db->query($sql);
}

Categories