How to make a Twitter-like following system - php

How can i make a Twitter-like following system where, if you follow someone, you will receive their tweets. I have a database table called "users", "followings", and "posts". The users table holds the users that are on my site. The followings shows the persons followers, this table is setup like this :'id, user_one, user_two'. And the posts table holds all the tweets or posts that the unique user has.
I have a profile page set up for each user, with a follow button. And also I have a news feed for the user, but in that news feed I need it to show posts from users that the logged-in user is following. So is there anyway for me to have a user follow someone and receive the posts from that user on their news feed.
Now I did some research: their system wouldn't seem to work. I kept getting this error:
Warning: implode() [function.implode]: Invalid arguments passed in function.php on line 12
SELECT
user_id,
body,
stamp
FROM posts
WHERE user_id in ()
ORDER BY stamp DESC
Warning: mysql_fetch_object(): supplied argument is not a valid MySQL result resource in function.php.
This line right here was suppose to help make it where when you follow that person you will receive there tweets and stuff
function show_posts($userid,$limit=0){
$posts = array();
$user_string = implode(',', $userid);
$extra = " and id in ($user_string)";
if ($limit > 0){
$extra = "limit $limit";
}else{
$extra = '';
}
$sql = "select user_id,body, stamp from posts
where user_id in ($user_string)
order by stamp desc $extra";
echo $sql;
$result = mysql_query($sql);
while($data = mysql_fetch_object($result)){
$posts[] = array( 'stamp' => $data->stamp,
'userid' => $data->user_id,
'body' => $data->body
);
}
return $posts;
}
I believe this piece of code, which is supposed to show posts from other users, is causing this problem but I don't know why.

Use a join. For example:
select user_id, text from posts
inner join followings on posts.user_id = followings.followed_id
where followings.follower_id = :user_id;
If I may recommend, stop using the mysql_ functions; they are deprecated and should not be used in newer applications. Instead, I'd recommend using PDO.

Related

Double mysql_fetch_array (get information from the other table to get data) / nest

I tried searching for this question, but theirs is a different error. I'm using PHP 5.2 for some reason.
What I'm trying to do is, get the mysql_fetch_array from one table, then use a column of that table to get a row from another table.
Here is my code (Advanced apologies for the horrible format)
$sql = mysql_query("SELECT * FROM testimonies WHERE visibility != 'Hide' ORDER BY date_submitted DESC");
$testimonyCount = mysql_num_rows($sql); // count the output amount
if ($testimonyCount > 0) {
//get data 'testimonies' table
while($info = mysql_fetch_array($sql)){
$username = $info['username'];
//Get id (in admin table) where username = username (in testimonies table)
$userid = mysql_query("SELECT * FROM admin WHERE username = $username LIMIT 1");
while($user = mysql_fetch_array($userid)){ $id = $user['id'];}
$testimonies .= "<div class='row'><div class='col-lg-2'><center>
<img src='Pictures/Profile_Pictures/".$userid['id'].".jpg' width='160' height='160'>
<br>".$info['username']."</center></div><div class='col-lg-2'><center>
<img src='back/inventory_images/34.jpg' width='160' height='160'><br>"
.$info['product_used']."</center></div><div class='col-lg-8'><center><u>(Date: "
.$info['date_submitted']." - Ordered from our branch in <strong>"
.$info['branch_ordered']."</strong>, City)</u></center>".$info['testimony']."
</div></div><br>";
}
}
else {
$testimonies = "No one has submitted their testimonies yet.";
}
So you see, my table "testimonies" have a column of 'username' and so is the "admin" table.
What' I'm trying to do is get the row of the username (in admin table) where the username is the
same as the one in the "testimonies" table. I used the information from the 2nd table in line 14 for the image src.
Unfortunately it gives me this error:
Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /home/_____/public_html/Testimonies.php on line xx
Notice: Undefined variable: id in /home/_____/public_html/Testimonies.php on line xx
Other's from what I've searched get their data on the first loop, but I don't get anything at all. The 2nd loop is certainly a problem. Help.
Thanks.
First I'll mention that it's a really bad idea to build queries in a such a way that they can be looped. As is for each of your testimonies you're executing another query to get the admin info. So for 10 testimonies you're hitting MySQL 10 times [ +1 for the original query ]. You generally want to get in, get your data, and get out.
So the better way to handle this is to let MySQL do it for you, with a join :
SELECT *
FROM testimonies inner join admin on testimonies.username = admin.username
WHERE visibility != 'Hide'
ORDER BY date_submitted DESC
The above will only return you testimonies with a matching admin. If you wanted to return testimonies even if they don't have an admin you'd want an outer join. You'd replace inner join admin with left outer join admin
So remove your second while loop and try that.
Also, the mysql_ functions are deprecated .. so you shouldn't be developing new code using them. Try and get my change to work as-is but you should consider looking at PDO [ Why shouldn't I use mysql_* functions in PHP? ].

SQL : Select all Posts from Followers

Im trying to find an efficient way to display all posts from people who are being followed by the logged in account holder.
There are two key tables:
1- Posts
table name : posts
id, account_name, published, body
2- Follows
Table name : follows
id, account_name, followed_name
I'm trying to find a way that i can display all the posts from all the accounts that are being followed. The connection between Posts and Follows is the Account_name.
I understand that it will probably be a join, but it's how I construct the WHERE clause. So far I have the following (The account name is set via $_SESSION['account_name']):
$sql = "SELECT * FROM posts LEFT JOIN follows ON posts.account_name = follows.account_name WHERE --- How would I only get the posts from the accounts being followed ?---"
I'm sure this is something simple my brain just feels drained and I cant seem to work it out.
UPDATE Attempting in PDO
Returning NULL at the moment,
$sql = "SELECT * FROM share_posts WHERE account_name IN (SELECT followed_name FROM $this->account_follows WHERE account_name = :account_name)";
return $this->AC->Database->select($sql, array('account_name' => $account_name));
The goes to my Database Class:
public function select($sql, $array = array(), $fetch_mode = PDO::FETCH_ASSOC)
{
$stmt = $this->AC->PDO->prepare($sql);
foreach ($array as $key => $value)
{
$stmt->bindValue("$key", $value);
}
$stmt->execute();
return $stmt->fetchALL($fetch_mode);
}
The returned data is NULL at the moment even though the logged in account has followed other accounts.
$account = $_SESSION['account_name'];
//do some sql injection checking on $account here
$sql = "SELECT * FROM posts WHERE account_name IN (SELECT followed_name FROM follows WHERE account_name='".$account."')";
This will get all the posts where the account name matches somebody you follow. I wasnt sure who was following who, but in this case the followed_name are the people account_name is following. If thats the other way around, switch the values
$sql = "SELECT * FROM posts WHERE account_name IN (SELECT account_name FROM follows WHERE followed_name='".$account."')";
I will write this the way I interpret your question.
What you need to do is select only the posts from the users that are followed by your logged in user.
To break this down, first you want to select the users followed by the logged in user. To do this, we use the Follows table.
We then want to select the posts by these users. As such my query would be this.
SELECT posts.* FROM follows
LEFT JOIN posts ON posts.account_name = follows.follows_name
WHERE follows.account_name = $logged_in_user

Retrieve and display comments/queries from database

I'm developing in php/sql a web application where users will be able to post items that they'd like to sell ( kinda like ebay ). I want non-members to be able to comment on the items or ask queries about items.
My problem is I want to display each item as well as any comment/query made about that item, in a similar manner as the way Facebook wall works.
I want to "append comments"(if any) to each item. The comments table is linked to the items table via column item_id. And the items table is linked to users table via column user_id. I have left joined users table with items table to display item details, i tried to left join comments table as well so that there are 3 joined tables.
That fails because no comments are displayed and only one item is displayed, despite there being multiple entries in each table. Here is the code i,m using.
$database->query
('
SELECT sale.*, query.*, users.id AS userid, users.username as user
FROM sale
LEFT JOIN users ON sale.user_id = users.id
LEFT JOIN query on sale.id = query.item_id
where category = "$category" ORDER BY sale.id DESC
');
$show = " "; //variable to hold items and comments
if ($database->count() == 0) {
// Show this message if there are no items
$show .= "<li class='noitems'>There are currently no items to display.</li>" ;
} else {
$show .= "<li>";
while ( $items = $database->statement->fetch(PDO::FETCH_ASSOC) )
{
$show .= "
//show item details in html
";
while( $query = $database->statement->fetch(PDO::FETCH_ASSOC) )
{
$show .= "
//show queries below item details
";
}
$show .= "</li>" ;
}
Welcome to Stackoverflow!
I recommend you taking a look at pdo. If you are already using mysql_ functions, then I recommend you switch. More on that can be found here.
Now that your pointed to the direction of to what functions to use when connecting/running queries, you now should create your tables. I use phpmyadmin for managing my database, I find it very good, but it's up to you what you use. Once you've decided on the service you use to manage your database, you should then learn how to use it by doing some google searches.
Now you need to set up your table and structure it correctly. If you say you're having items, then you should make a table called items. Next create the columns to the properties of the items. Also I recommend reading about Database Normalization, which is a key aspect of setting up your SQL tables Etc.
Once you have everything set up, you've connected to your database successfully Etc. You now need to set up the "Dynamic Page". What I mean by this is, there's only one page, say called 'dynamic', then a variable is passed to the url. These are called GET HTTP requests. Here's an example of what one would look like: http://example.com/item?id=345.
If you've noticed, you'll see the ? then the id variable defined to 345. You can GRAB this variable from the url by accessing the built in PHP array called $_GET[]. You can then type in your variable name you want to fetch into the []'s. Here's an example.
<?php
$data = $_GET['varname']; // get varname from the url
if(isnumeric($data)){ // is it totally made out of numbers?
$query = "SELECT fieldname FROM table WHERE id=:paramname";
$statement = $pdo->prepare($query); // prepare's the query
$statement->execute(array(
'paramname'=>$data // binds the parameter 'paramname' to the $data variable.
));
$result = $statement->fetch(PDO::FETCH_ASSOC); // grabs the result of the query
$result = $result['fieldname'];
echo 'varname was found in the database with the id equal to:'.$data.', and the result being: '.$result;
}
?>
So now you can see how you can grab the variable from the url and dynamically change the content with-in the page from that!
Hope this helped :)

Group result by field

Am building a messaging system for a site, but i want it to have an instant messaging app feel.
I have table with a structure like this:
<!-- language: lang-none -->
id
R_id = Reciever's id
S_id = Sender's Id
message
read = 0 if unread, 1 if read
post_time
conv_id = conversation id
I am trying to build a query that retrieves all messages pertaining to a receiving user and display it in a group format i.e all messages from a user grouped with the user's name, sort of like facebook messages.
This is the method in my model, am working with codeigniter
function get_user_conversations($user_id) {
//Load Models
$this->load->model('conversation_model');
//Load helper
$this->load->helper('date');
//database query
$q = $this->db->select('*')
->from('conversations_inbox')
->where('R_id',$user_id)
->group_by('S_id')
->order_by('post_time','desc')
->get();
$conversations = $q->result();
return $conversations;
}
Maybe something like this?
// Presuming you want the most recent ones first
$q = mysql_query("SELECT message FROM `TABLE` WHERE `R_id`='USERNAME_HERE' ORDER BY `post_time` DESC");
while ($row = mysql_fetch_array($q)) {
echo "<li>Message: " . $row['message'];
}
I'm honestly not really sure what you're asking, so that's the best I can do.

Relational MySQL - fetched properties?

I'm currently using the following PHP code:
// Get all subordinates
$subords = array();
$supervisorID = $this->session->userdata('supervisor_id');
$result = $this->db->query(sprintf("SELECT * FROM users WHERE supervisor_id=%d AND id!=%d",$supervisorID, $supervisorID));
$user_list_query = 'user_id='.$supervisorID;
foreach($result->result() as $user){
$user_list_query .= ' OR user_id='.$user->id;
$subords[$user->id] = $user;
}
// Get Submissions
$submissionsResult = $this->db->query(sprintf("SELECT * FROM submissions WHERE %s", $user_list_query));
$submissions = array();
foreach($submissionsResult->result() as $submission){
$entriesResult = $this->db->query(sprintf("SELECT * FROM submittedentries WHERE timestamp=%d", $submission->timestamp));
$entries = array();
foreach($entriesResult->result() as $entries) $entries[] = $entry;
$submissions[] = array(
'user' => $subords[$submission->user_id],
'entries' => $entries
);
$entriesResult->free_result();
}
Basically I'm getting a list of users that are subordinates of a given supervisor_id (every user entry has a supervisor_id field), then grabbing entries belonging to any of those users.
I can't help but think there is a more elegant way of doing this, like SELECT FROM tablename where user->supervisor_id=2222
Is there something like this with PHP/MySQL?
Should probably learn relational databases properly sometime. :(
EDIT:
here is the relevant schema
submissions
===============================
id, user_id, timestamp
submittedentries
===============================
id, user_id, timestamp
users
===============================
id, supervisor_id, email
one submission has many submittedentries, and currently I'm referencing this by using the timestamp. I'd be more than willing to alter this if someone can suggest a more efficient way. (and yes, there are more fields that I'm omitting)
This should, if I got the column names correct, get a list of submissions from users who have the specified supervisor.
SELECT * FROM users, submissions
WHERE users.supervisor_id = $supervisorID
AND submissions.user_id = users.id
This version attempts to combine the timestamp checking as well.
SELECT * FROM users, submissions, submittedentries
WHERE users.supervisor_id = $supervisorID
AND submissions.user_id = users.id
AND submittedentries.timestamp = submissions.timestamp
Edit: Updated to match the additional table info. I'm still not 100% sure that the second version is correct, will need to be tested against the database to find out :)
Oh, and in practice you should probably replace the asterisk with the names of the actual columns you want to retrieve.

Categories