PHP Private Message (PM) System - php

I am planning making a PM system for my users, overall it seems easy enough, but the way I have seen tutorials making PM systems, there is one problem.
In the way i planned it to work, there would be rows like, user_from, user_to and then the message - user_from would be the sender, and will see the message in his send messages, user_to will be the receiver and will see the message in his inbox. BUT, what if a user wants to delete a message from their sent folder, but the other user does not want to delete it from their inbox ??
Is there any simple way doing this ?
It could also be nice, to have the messages in conversations, like Gmail and Facebook, but that is maybe to hard to code (any tutorials appreciated)?

Use what's called a soft delete. This means when a record is 'deleted' it is never actually removed from the database but rather a flag is set to delete which allows you to remove it from a user interface while still having access to the data when you need it. So for this situation you could create two more columns called user_to_delete and user_from_delete. When either of these is set to true you would know not to show the message in the respective user's inbox/outbox. Goodluck.

You can fix the issue a few ways, but I would probably add a couple flags (from_deleted, to_deleted) to the table:
Instead of deleting the message, update the appropriate flag to 1.
When listing messages, filter out those that have been flagged.
You can setup the script so that after flagging, if both fields are flagged then you can actually delete the row.

I suggest the following database design:
MESSAGES
+----------+------------------+---------------------------+
| id | subject_id | body |
+----------+------------------+---------------------------+
SUBJECTS
+----------+-------------+--------------+-----------------+
| id | title | author | receivers |
+----------+-------------+--------------+-----------------+
INBOX
+----------+---------------+--------------+---------------+
| id | user_id | msg_id | read |
+----------+---------------+--------------+---------------+
OUTBOX
+----------+---------------+------------------------------+
| id | user_id | subject_id |
+----------+---------------+------------------------------+
When you send messages, you create a new row for all receivers in the inbox table, and in the outbox table one for the sender. In the messages table you insert one row with the ID of the subject and the message body. In the subjects table you insert one row with the title, author and all receivers (if the sender started a new subject or forwarded a full conversation or single message, otherwise add the message in the messages table using the existing subject ID) so that this info is kept even if one of the receivers deletes a messages from his/her inbox (in this case delete the row in the inbox table).
For the outbox there is no need for a 'read' flag, and notice that only the subject ID is used.

Another approach would be add two columns that will determine whether or not the owner or recipient have requested to delete (hide) the message.
owner_id | user_from | user_to | mailbox_folder | Message | Owner_hide | Recipient_hide
1 1 2 Sent Hi 1 0

Yes, there is a simple way of doing it! Having two more columns, respectively sender_deleted and receiver_deleted. If one of them "deletes" the message, then you updated the column with a value of 1. for example. When you display the messages, you select the messages you make sure the value is different than 1. Etc...

You would just create 2 rows, and add a column. example:
owner_id | user_from | user_to | mailbox_folder | Message
1 1 2 Sent Hi
2 1 2 Inbox Hi
Other columns: a unique row id, timestamps, subject line, etc...
Your mailboxes would then be built off of the owner_id column, and each user has their own copy to move/delete as they choose.
To add conversations, you could add a column, or another table. If it's a new message, get a new conversation id, otherwise use the same ID. Query by timestamps.

You could add a user_from_deleted & user_to_deleted rows and display a message only if it is not deleted.
To display the messages in conversations you could add an parent_id and display all the messages with the same parent_id

A PM system is a little more complex that one table. What if you PM more than one person?
In this case you would want multiple tables. One for users, messages, etc... You would link them up using primary and foreign keys.
Try looking up relational databases.
This should get you started:
http://www.databasejournal.com/sqletc/article.php/1469521/Introduction-to-Relational-Databases.htm

Related

How to design a database schema for a messaging app?

I'm creating a laravel website which has Messaging as an included feature.
I would like to take into consideration the following factors.
Both parties (the sender and the receiver) have the ability to delete the messages in their end.
if any of the parties deleted the message the other party should still having access to the message.
the message might have attachments.
I thought of the following schema but I think it has too much duplication and I'm looking for something better if any.
messages table:
-----------------
id
title
body
received_messages table:
------------------------
message_id
receiver_id
sender_id
is_read
sent_messages table:
------------------------
message_id
receiver_id
sender_id
Edit: Another schema came to my mind:
messages table:
-----------------
id
title
body
user_messages table:
-----------------
message_id
sender_id
receiver_id
sender_del // indicates that the sender deleted the message in their end
receiver_del // indicates that the receiver deleted the message in their end
read_at // timestamp null by default
When one party choose delete the message the corresponding field (sender_del, receiver_del) will be true so that the message will not be shown to that person
Using the previous schema the message will only be deleted from the DB if both parties deleted it
<?php
$user = auth()->user();
$received = $user->receivedMessages; // to get received messages
$sent = $user->sentMessages; // to get sent messages
any suggested modifications, which schema to use or a whole new schema are welcomed.
Thanks.

PHP Link user table to another table

Hi I am in the process of making a website that includes a user registration system for my final year of high school major project. The website stores driving logs for learner drivers. I'm kind of confused as to how I should desgin the database. I have a users table which stores the personal information of each user of the site. However, I would like the user to be able to insert information into another table which would be their "logbook" and this to be displayed on the my account page. Do I need to create a table within the database for each user or is there a way of connecting the tables so that i do not have to.
You do not need to create a table for each user. Instead, add a column in your "logbook" table which will contain and refer to the "id" of the user it's tracking. This will likely be the primary key of your "users" table. Then, to get the logs for a specific user, you would query the logbook table for rows only with at specific user ID.
Furthermore, in a more sophisticated setup, you can add constraints to link the two columns. See http://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html
U will not need table for each user...
Just one table will help u out...
The other table where u want to store user logs should only have reference to user I'd that u have created in users table..
Primary and foreign key - relational table concepts
For eg:
Let ur user has
1.userid
2.first name
3.lastname.... And other colums
Then ur userlogbook wala table should have
1.logid
2.userid
3.other columns...
Hope u got it..
You only need 1 table for the users, each user will be a row inside that table.
As you see in this table below, you need a way to be able to track which logbook record belongs to which user. That's done by storing the users ID (or any unique identifier, usually the primary key) to know exactly which user created the record.
-------------- -----------------
| User Table | | Logbook Table |
------------------------- -----------------------------------
| id | name | ...etc... | | id | user_id | date | ...etc... |
------------------------- -----------------------------------
| |
|_____________________________________|
I don't know how your system works, but I assume you know when a user is logged in right? Probably store their id in a session yeah? Well when you're inserting the logbook record, all you need to do is parse through their user ID in addition:
INSERT INTO logbook (id, user_id, .....) VALUES (NULL, $THE_USER_ID_FROM_SESSION, .....)
The above is pseudo code, you'd need to sanitize the input and actually assign the user id to a variable.
Now for fetching the user-specific information, all you need to do is add a simple WHERE clause:
SELECT id,column_1,column_2,... FROM logbook WHERE `user_id` = $THE_USER_ID_FROM_SESSION
The above is pseudo code, you'd need to sanitize the input and actually assign the user id to a variable.
There are a few questions I have, how much reading/writing are you going to be doing to the table? How are your tables set up?

How to make an efficient notification generator using php jquery

I am working on something smalland was thinking of making a good notification generator like facebook does Mainly I want how the the tables might look. How to make updates and all the nessecities and cautions i should have Thanks
I have users as they upload images comment like a persons profile I want the person whose post was like commented or any other action to be notified that this person likes your photo
The way Facebook does it
There's many ways to do it, one of which is to have a column in the table titled new_notification that will tell you if the notification is new(read by the user or not). So, for example, if a person likes another persons picture, in the table that column will have new_notification set to Y. When the user who's picture was liked logs into the website, you search for all rows where new_notification = Y do a count and show the number of notifications like facebook does. Once the user has seen the notifications or opened the notification bar, go through that table and set all the rows with new_notification = Y to 'N'.
Yes I agree with #Interstellar_Coder, you could have your post page info stored in one line in a database table, and your like info stored in another table. Reference which picture the person likes by ID.
Table 1 (picture posts):
ID | Picture | Comments | who
1 | (pic data) | my picture | user.name_1
Table 2 (likes):
row_ID | picture_ID | who
0 | 1 | user.name_2
1 | 1 | user.name_3
So in this example you have 1 picture posted by user.name_1, then this picture has been liked by user.name_2 and user.name_3. We know this because of the picture_ID field in the likes table.
You can check in your database who likes picture post with ID=1, and it will tell you who likes it, mysql code example:
select who from likes where picture_ID = 1;

User messaging system

I'm looking at creating a user messaging system (similar to Facebook).
What I want to know is essentially what should the table structure look like? The requirements I have are as follows:
Messages are exchanged between users - a sender can select multiple users to send a message to.
Messages are displayed in a thread-style layout, as a 1-1 conversation. i.e. each recipient's reply will appear in it's own thread.
Individual messages cannot be deleted, however a thread can be deleted. Deleting a thread doesn't delete any messages, it just removes that thread from the user's inbox. However the other user can still access the thread if he/she hasn't deleted it from his/her inbox.
Here is what I have at the moment:
Table messages
==============
id (PK)
user_id (from)
subject
body
sent_at
Table message_recipients
========================
message_id (PK)
user_id (PK)
read_status
EDIT: What about the following:
Table messages
==============
id (PK)
thread_id
user_id (from)
body
sent_at
Table threads
=============
id (PK)
user_id (from)
subject
Table thread_recipients
=======================
thread_id (PK)
user_id (PK)
read_status
sender_deleted
recipient_deleted
I would suggest having the following at least:
Users, Threads, Messages
All messages would have a thread
foreign key: thread_id
All threads would have at least one message and at least one recipient (as well as sender)
foreign key: to_user_id, from_user_id, message_id
From there you could simply assign a couple flags to your thread (to_user_deleted, from_user_deleted) that would be updated accordingly.
There a lot more things to consider of course, such what kinds of things you want to account for. For example:
Do you want to display the current message as opposed to the starting message?
Do you want to allow users to mark individual messages as read, or just threads?
You need to take all of these into account while designing your database.
Why not use something like Jabber (example: OpenFire or Web Client)
If you need PHP to interact with it you could use something like:
http://code.google.com/p/xmpphp/ or http://code.google.com/p/jaxl/
#Angelo R. Would like to know why we require the Thread Table? This isn't any discussion board. If you want to retrieve the whole thread/conversation of messages you can simply query by source AND recipient ID.
Plus, if you use Thread, nothing bad. But what in this situation
If new message - new thread_id (automatically created), If replied to existing conversation, you have the thread_id, but what if you are creating a new message (say like facebook popup), you don't know whether there was any previous conversation or if thread_id is available or not unless you execute a special query to it.
This was my thought. Tell me if I might be wrong somewhere.

Preserving old data changed by user

I have a users table that has the following fields: userid, phone, and address. Since this is user data, I'm letting the user change them whenever he wants. Problem is I'd like to keep track of those changes and preserve the old data too. Here's some of the ideas I considered:
appending the new data to the old data and using a separator like a pipe. When retrieving the field, I would check for the existence of that separator and if exists, get the chars after it as the new data. (feels cumbersome and doesn't feel right)
setting up a different changes table with the following fields: userid, fieldname, fieldcontent. When/if a user changes data (any data), I would log the event in this separate table under the user's userid, and the name/id of the field and the old content of the field, then I can now overwrite his old data in users with the new. If I want to find all changes made by this user, I would search the changes table by his userid. Problem with this is that I'm mixing all data changes (of all fields) into one table and so the fieldcontent field in changes has to be text to accommodate the varying field types. This still seems better than the first idea, but still not sure if I'm doing the right thing.
What other ideas are there or known best practices to keep old data?
Thanks in advance
Whatever you do don't do the first one.
The changes table is a better approach. It's also called an audit or history table. I wouldn't do a history of key-value pairs however. Instead do a history per relevant table. You can do this in application code or via database triggers. Basically whenever an insert, update or delete happens you record which happened and what data was changed.
Table user:
id
username
email address
phone
address
Table user_history:
id
change_type (I, U or D for insert, update or delete)
user_id (FK user.id)
email address
phone
address
date/time of change
optionally, also store who changed the record
A very simple way that we have used to track such changes is this:
users_history`
userid
changenumber smallint not null
changedate datetime not null
changeaddr varchar(32) not null
phone NULL,
address NULL
primary key on (userid, linenumber)
Each time you INSERT or UPDATE a record in the users table, simply INSERT a new record in the users_history table. changenumber starts at 1 and increments from there. changedate and changeaddr could be used to track when and where.
If a field value has not changed, feel free to put NULL in the respective users_history table field.
At the end of the day, your app does not need to change or store bulky history data in the users table, but you have all if it at your fingertips.
Edit:
This does preserve the old data. See the following example where the user started with a given address and phone, and then 4 days later updated the address, and 5 days later updated the phone. You have everything.
Current users record:
100 | 234-567-8901 | 123 Sesame Street
Sample History Table
100 | 1 | 2009-10-01 12:00 | 123-456-7890 | 555 Johnson Street
100 | 2 | 2009-10-05 13:00 | NULL | 123 Sesame Street
100 | 3 | 2009-10-10 15:00 | 234-567-8901 | NULL
The simplest way to implement this will be have another table just for history purpose, a snapshot. You don't need to mirror all the fields, just
change_id // row id (just for easy management later on if you need to delete specific row, otherwise its not really necessary)
user_id // Original user id
change_time // time of change
data // serialized data before change.

Categories