Friendship system - php

I have two tables:
users:
user_id
user_name
...
friends:
user_id (user who sent friend request)
friend_id (user who received a friend request)
confirmed (1 = friends, 0 = friend request)
I want each user to be able to see their friends and friend requests. I have problem with displaying friends usernames. I made it work, but it's a poor solution and I want to solve this problem using only one query (if possible).
I tried:
$sql = "SELECT friends.friend_id, friends.user_id, users.user_name FROM friends
INNER JOIN users ON friends.user_id = users.user_id
WHERE friends.user_id = " . $_SESSION['user_id'] . " AND confirmed = 1
OR friends.friend_id = " . $_SESSION['user_id'] . " AND confirmed = 1;";
My problem is that it will show user_name of users that have user_id same as user_id in friends table. My query needs to check if user_id is the same as the $_SESSION['user_id'], and if it's the same then it must return user_name of the user that has the user_id the same as friend_id in friends table.

Formulate your SQL query in the following way,
$sql = "SELECT
" . $_SESSION['user_id'] . " as user_id,
IF(u2.user_id = " . $_SESSION['user_id'] . ", u1.user_id, f.friend_id) as friend_id,
IF(f.user_id = " . $_SESSION['user_id'] . ", u2.user_name, u1.user_name) as friend_username
FROM users as u1
INNER JOIN friends as f
ON u1.user_id = f.user_id
INNER JOIN users as u2
ON f.friend_id = u2.user_id
WHERE (f.user_id = " . $_SESSION['user_id'] . " OR f.friend_id = " . $_SESSION['user_id'] . ") AND f.confirmed = 1";
Here's the live demo: http://sqlfiddle.com/#!9/e10252/7
Sidenote: Learn about prepared statement because right now your query is susceptible to SQL injection attack. Also see how you can prevent SQL injection in PHP.

Related

Selecting specific data using table joins

I am attempting to output some a user username from the user table by joining it from a questions table, the intention being I can show which user posted this specific question.
users with id, username
discussion_q id, question_text, user_id
Here is where I am at:
$sql = "SELECT q.id AS questionId, q.question_text AS questionText, q.user_id AS questionUserId, q.published AS questionPub, users.id AS userId
FROM discussion_q
JOIN users
ON questionUserId = userId
WHERE project_id = '$projectId'
ORDER BY published";
I am getting 0 results returned back to me of course. I am sure I have over engineered this or missed something simple?
Here is my php to return the results:
$result = $conn->query($sql);
if (mysqli_num_rows($result) > 0) {
while($row = mysqli_fetch_assoc($result)) {
echo '<div class="twelve columns">
<p>' . $row['question_text'] . '</p>
<p>' . $row['published'] . ' by ' . $row['username'] . '</p>
</div>';
}
} else {
echo "0 results";
}
So the end goal is to output the question_text with the username of the user who posted.
$sql = "SELECT q.id AS questionId, q.question_text AS questionText, q.user_id AS questionUserId, q.published AS questionPub, users.id AS userId
FROM discussion AS q
JOIN users
ON (q.user_id = users.id)
WHERE project_id = '$projectId'
ORDER BY published";

PHP/MySQL different value for each row

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.

Friendship Query - PHP & mysql

below is my query which returns session user's friends.
$new_friends = $db->query("
SELECT user.id, user.name_surname
FROM user
JOIN friendship ON user.id = friendship.sender_id or user.id = friendship.receiver_id
WHERE (friendship.receiver_id =" . $_SESSION["SES_USER_ID"] . " OR friendship.sender_id =" . $_SESSION["SES_USER_ID"] . ")
AND user.id != " . $_SESSION["SES_USER_ID"] . "");
$new_friends->setFetchMode(PDO::FETCH_ASSOC);
$new_friends_data = $new_friends->fetchAll();
It is working good, there is not any problem about it. Now I want to improve my site with new properties so I want to add "NEW PEOPLE" section to my site. Fetched people must not session user's friend and hisself/herself.
I tried to use below code for "YOU MAY KNOW" section. But it is returning again session user's friends.
$new_friends2 = $db->query("
SELECT user.id, user.name_surname
FROM user
JOIN friendship ON user.id = friendship.sender_id or user.id = friendship.receiver_id
WHERE (friendship.receiver_id !=" . $_SESSION["SES_USER_ID"] . " OR friendship.sender_id !=" . $_SESSION["SES_USER_ID"] . ")
AND user.id != " . $_SESSION["SES_USER_ID"] . "");
$new_friends2->setFetchMode(PDO::FETCH_ASSOC);
$new_friends_data2 = $new_friends->fetchAll();
//look carefully I change some equations from = to !=
How can I fix it?
Basically I want to return people who are not session user's friends.
WHERE (friendship.receiver_id !=" . $_SESSION["SES_USER_ID"] . " OR friendship.sender_id !=" . $_SESSION["SES_USER_ID"] . ")
OR here allows one of those columns to have SES_USER_ID change it to AND
Your question is not clear enough!
But looking at the question, you should replace or with and !!

Form inserting data duplicate times from all users

I can't figure out why, but whenever a user makes a post on the site I am working on it will post to the database multiple times, 1 entry for each member on the site(currently 3).
Here is my code.
Add_topic.php
$category=$_POST['category'];
$sub_category=$_POST['sub_category'];
$topic_data=$_POST['topic_data'];
$posted=date("h:i:s d/m/Y"); //create date time
$sql = "INSERT INTO `topics`(category, sub_category, topic_data, posted_by, posted)VALUES('$category', '$sub_category', '$topic_data', '".$_SESSION['user_id']."', '$posted')";
$result=mysql_query($sql);
if($result){
header("Location: topics.php?category=$category&sub_category=$sub_category");
exit();
}
Topics.php
$sql = "SELECT users.user_id, users.username, users.profile, topics.topic_id, topics.category, topics.sub_category,
topics.topic_data, topics.posted_by, topics.posted, topics.view, topics.reply
FROM users, topics WHERE topics.category = '" . $_GET['category'] . "' AND topics.sub_category = '" . $_GET['sub_category'] . "' ORDER BY topics.posted DESC";
$result = mysql_query($sql);
while($rows = mysql_fetch_array($result)){
I don't think that add_topic.php is inserting multiple rows. You can verify this by looking directly at your table.
I believe your issue is your query in Topics.php.
$sql = "SELECT users.user_id, users.username, users.profile, topics.topic_id,
topics.category, topics.sub_category, topics.topic_data,
topics.posted_by, topics.posted, topics.view, topics.reply
FROM users, topics
WHERE topics.category = '" . $_GET['category'] . "'
AND topics.sub_category = '" . $_GET['sub_category'] . "'
ORDER BY topics.posted DESC";
You are doing a join on users and topics, but you are not defining what links them. So it is creating a row for each user to each topic post.
You can see it as the 1st example result set at this SQLFiddle - http://sqlfiddle.com/#!2/7dfc4/4
What you want to do is LEFT JOIN users to topics ON topics.posted_by = users.user_id.
That is the 2nd example result set at - http://sqlfiddle.com/#!2/7dfc4/4
So your query would now be (escaping your $_GET to prevent SQL Injection) -
$sql = "SELECT users.user_id, users.username, users.profile, topics.topic_id,
topics.category, topics.sub_category, topics.topic_data,
topics.posted_by, topics.posted, topics.view, topics.reply
FROM topics
LEFT JOIN users
ON topics.posted_by = users.user_id
WHERE topics.category = '" . mysql_real_escape_string($_GET['category']) . "'
AND topics.sub_category = '" . mysql_real_escape_string($_GET['sub_category']) . "'
ORDER BY topics.posted DESC";
note - you should not be using mysql_* functions in new code. It is depreciated as of php v.5.5. You should update your code to mysqli_* or PDO. http://php.net/manual/en/mysqlinfo.api.choosing.php

how can I build this update query

I have two values from URL. This is those,
$_GET['a'] // this variable has a email address
$_GET['b'] // this variable has a code to activate my account.
I am trying to create UPDATE query using these two values, but problem is these two values belong to two different tables. email has in contact table and active column has in user table.
This is my code so far:
$q = "UPDATE tutors SET active = NULL
WHERE (active='" . mysqli_real_escape_string($dbc, $_GET['z']) . "')
LIMIT 1";
This code is working for me. but I need to check both values in WHERE clause. Can anybody help me to build this query?
UPDATE :
$q = "UPDATE tutors t, contact c SET t.active = NULL
WHERE t.active = '" . mysqli_real_escape_string($dbc, $_GET['z']) . "'
AND c.email = '" . mysqli_real_escape_string($dbc, $_GET['y']) . "'
AND t.contact_id = c.contact_id
LIMIT 1";
Thank you.
At a guess: something like this would work if your tutors and contacts are linked via a contact_id in the tutors table.
<?php
$q = "UPDATE tutors T, contacts C SET T.active = NULL
WHERE T.active = '" . mysqli_real_escape_string($dbc, $_GET['z']) . "'
AND C.email = '" . mysqli_real_escape_string($dbc, $_GET['a']) . "'
AND T.contact_id = C.contact_id"
but... I would need more information about your database schema to make this a more precise answer.

Categories