Best way to create an anonymous mode for logged in users? - php

I'm working on a Web App similar to a discussion board and I want to give logged in users the ability to switch to an anonymous mode in which their username is not displayed but replaced by an ID when they post or reply to a topic. So the question is what is the best way to generate this ID given that :
A user has the same ID in the same topic.
The ID for the same user is different from a topic to another.
I'm in a LAMP environment so if you can suggest any PHP function to generate the ID or a way to store it in MySQL database that will be great.
Thanks !

All you really need is to:
be able to create an id, which in your case should probably be globally unique
associate that id with your regular user's id
be able to track that a unique id belongs to a topic
You can do this easily with one extra table:
table anonymous_ids
-------------------
user_id INT (references your user id)
anonymous_id VARCHAR, UNIQUE index
topic_id INT (references your threads/topic id)
When a user replies in a topic, you check whether there's already an anonymous id for him in this topic:
SELECT anonymous_id
FROM anonymous_ids
WHERE user_id = {userId}
AND topic_id = {topicId}
If there is no such id yet, you create it. That's the basic gist of it.

Related

Correct MySQL structure for storing user-based data

So I have a question, I'm hoping it isn't too subjective.
I have a blog-style website, so on the homepage articles are loaded alongside the date published, the user that posted it, etc. Basic data like this.
I store it in MySQL like so:
article_id username date content etc.
1 user1 2015-05-14 01:35:14 my content a
2 user2 2015-05-16 02:33:15 my content b
This way, I can display it using one query, where I retrieve the username, date, content, etc.
My question is. I want to allow users the option to change their username. There are two options I see for this.
Either I continue storing data as I do now, and manually update tables like this with user-related data to the new username. Or I store data by a user_id rather than username, and have an extra query for each article loaded to get the associated username from another user table.
Which is the correct approach?
I ask this because I assume there's a recommended practice for this situation? Is it normal to store data by username and update it, or to store by id to avoid having to do this - but at the cost of the overhead when querying data. I'm guessing it's possible to display the username for id-based data in just one query, but that would still take significantly longer?
Depends. Do you see there is a 1:1 relationship with Article:User if yes, then storing in a single table will probably suffice but generally an user will publish multiple articles which will make it a 1:* relationship and in which case you should create a separate table for UserDetailsd and have user_id as FOREIGN KEY in Article table probably.
You should create a users table, store user_id which would be incremental and a user_name. When showing the user name in your app, join to the users table and show the name from that table and it will always be current. This is the best practice if you wish to allow user name changes. Updating all usernames it the articles table is not recommended. This will also allow you to store other user related information such as email, join date, etc... without having to keep all that in the articles table.
Create a seperate table with all user-related information and alter your current table, so only content and article related stuff is included. That's what I'd suggest you
Make a separate table for users something like:
-------------------
user_id | user_name
-------------------
Where user_id should be PK.
And another table, lets say article should look like:
-----------------------------------------------
arcticle_id | date | content | etc. | user_id
-----------------------------------------------
Where article_id could be a PK and user_id would be the FK from users table, making a relationship which could be used in other tables as well.
You can create a table for users, and use a foreign key on field username, specifying the behavior on updates. Is something like this:
alter table posts add constraint fk_post_user foreign key (username) references users (name) on update cascade;
In this way, when you update a row on table users, all user names on table posts will be updated too.

Maintain many level hierarchy of tables in database

I have to maintain the data of friend list of friends who liked a particular category post. And this may be at any level. For eg.
if a friend of A who is B like a wanted post. then I ll maintain the record of A’s friends and B’s friend. Basically my requirement is
If user visit my product site I have to tell him/her that you're following friend already visited the same and they actually recommend you to use this and to build confidence that you are on the right way as your friends are also using it. I also want to suggest A that C who is the friend to B is using this product since this time and C suggest to many for using it.
I know this logic is already implemented in good sites.
I am just a starter. So pls suggest me the database for backend and required things for frontend.
Specially this question is to maintain the record on database. So I am asking for the database what should I use not how should I implement that would be next step.
As I am planning to use Graph database for it. In graph either bigdata or Neo4j.
Your ideas are most welcome and will be appreciated. Thanks
I hope my logic may takes you few steps forward
Initially we have to maintain the mutual friends records
foe example
id mut_id
1 2,3,4
Here 2,3,4 are your friends
next we need to maintain the records who has purchased/visited
prod_id buy_id
1 2,1
Now suppose 3 id wants to buy or visit site then we can show that your friend already visited or buyed product
Friends' relations is a classical many-to-many scheme. You need two tables to implement this:
1. A table with personal data, such as name, email etc. (could be more complex like person-properties relation)
2. A table with friends' retaionships data, usually it contains ID pairs of friends that relation is representing and some data about relation itself, such as category (friend/family/classmate etc) , level of affinity (if >0 it means positive relation, <0 negative such as enemies) and so on. Assume first ID is a person this relation belongs to (and can be maintained by), second ID is a person this relation applies to. Usually such kind of tables is constrained to pair of IDs to be unique, so nobody will be able to add same person as a friend twice
Here is some sample:
CREATE TABLE person
(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255),
email VARCHAR(255),
PRIMARY KEY (person_id)
);
CREATE TABLE relationship
(
id_person INT NOT NULL REFERENCES person(id),
id_person_related INT NOT NULL REFERENCES person(id),
id_category INT REFERENCES relcategories(id),
affinity INT,
PRIMARY KEY (id_person, id_person_related)
);
Note that affinity and id_category fiels are optional and last one requires table relcategories with INT id field to be create first
Visits of one friend to another can also be stored in relationship in a separate field

Register - Login Database Scheme

Here is what I want to ask:
I want to make a system to register patients so then they will be able to login. I have 3 type of users though.
admin (no need for registration)
doctor (standard number of doctors, no need for registration)
patient (they will be registered)
I want to keep more info for them than just id, username, password, email.
I am thinking of having more than 1 tables to do this and link them with primary and foreign keys:
1st table
accounts (it will store the login data)
Example:
acc_id(primary key)
acc_password
acc_username
acc_type
2nd table
doctors_extra_info
Example:
acc_id (foreign key)
doc_info_id (primary key)
doc_name
...
...
3rd table
patients_extra_info
Example:
acc_id (foreign key)
pat_info_id (primary key)
pat_name
...
...
4th table
admin_info
Example:
acc_id (foreign key)
admin_id (primary key)
admin_email
a. Which is the best way of doing this?
b. In the part of
registration, how to deal with primary and foreign keys? Two insert
commands in two different tables? [In order to have the same acc_id
in the account table and the extra info table]
c. At the login part,
I need to check the type of user and redirect (header(Location: ..);)
to a page? Is this the right way of doing it?
Any suggestions?
Thank you.
If you're using PHP then when you insert a record you can instantly retrieve the ID created using mysql_insert_id(). You then use this to create other records as your foreign key.
With regards to redirects, I'd simply get the user type from the database and then check the type of user and redirect to page required.
Generally though the tables you have created do not correlate properly. Remember the defining thing about the people using the system is that they are a person, and shouldn't be deined by their job role. They should have a account_type_id linking to another table. Otherwise you have three tables essentially holding the same information.
For example you should have your tables like this
User table
user_id
first_name
last_name
email
account_type_id*
Accounts type table
user_id
account_type_id*
account_type //e.g. patient, doctor, admin etc
This means now that you can easily extend the database with new tables, user access levels, new columns without having to duplicate the same column across three tables and so on. Try reading up on database normalization. A very good video from youtube is http://www.youtube.com/watch?v=fg7r3DgS3rA

Developing a simple voting system in php need help

I need to set up a simple voting system for my application., My application consists of articles posted as well as comments. I would like to add voting abilities to both articles and comments and at the same time be able to sort comments based upon highest voted etc.
I have the following restrictions i.e since the application needs users to log in - only logged in users can vote, secondly a user can vote on an item only once. Users can upvote or downvote or cancel a vote they've made.
What would be a decent table design for this, plus I need the solution to be scaleable. Thanks for the advice
I think I would go with a join-table between the users and articles tables :
users_articles
- article_id
- user_id
- score
- date
With the following notes :
article_id is a foreign key to the article that gets up/down-voted
user_id is a foreign key to the user that voted
score is +1 or -1 depending on the vote
the primary key is on the two article_id, user_id columns.
a user voting on an article means inserting one line in this table ; canceling the vote means deleting that line (or setting a 0 score if you want to keep track of the fact the user has voted)
That's for votes on articles.
And I would do another users_comments table for the votes on comments.

Incorporating Open ID with my current login System?

I am currently setting up Open ID authentication in my website and I am having troubles incorporating it with my current Login System and database... I've read the article at Plaxo & it recommends this type of table to store the openid info...
create table user_openids (
openid_url varchar(255) not null,
primary key (openid_url),
user_id int not null,
index (user_id)
);
This is my current Users-info table
Userid(PRIMARY) | username(UNIQUE) | password | Email
Userid is used to reference user-details for comments, ratings etc. (So it goes into the comments table and the ratings table as a User identifier)
I want a system similar to what Stack overflow uses just login using your Open ID and it gives you an unknown(OPENID-provider) display name.... while keeping my current login system intact.
1) How can I add Open ID details of users to my current Users-Info Table without affecting the current login setup?
2) Currently I use User-id(generated unique for every user) to store in the session to maintain Login. What should I do now in case of Open ID?
*My Thoughts(I don't know if I am right or not)
- Add an open-id field to store the unique open id url provided by the open id provider for each user and set it to null for non-open-id-users.
- Make User-id a text field and store a md5 of the open id url.(store this in session to maintain Login).
- I have no idea how can I handle Display-name/Username which is set to unique for each user because I would like to show unknown(OPENID_provider) (for users using open-id) which can be changed from the profile settings...
Any suggestions would be helpful....Thanks
The idea with the table layout you show is to have a 1:many from users:openids.
Thus, no changes to the users table are needed.
When someone logs in with an OpenID, you check if that OpenID is in the openids table. If so, you have the user_id of the user and you are done.
Otherwise create a new user (with no username/password set) and insert an (openid,user_id) pair for them into the openids table.
You template can display whatever nice placeholder (such as their OP, or whatever) where it would normally display username for users whose username is blank.
Hopefully you already disallow logging in with blank passwords, so there should be no security issue there.
What about this?
Add a display_name column to the users table, which doesn't have to be unique.
Make username and password in users optional
When somebody registers with OpenID, create a row in users with empty username/password and display name set to "unkonwn (provider)".
Allow users to set username/password, if they want to switch to password-based login.
Allow users to manage their OpenIDs, so that existing users can switch to OpenID-based login.
This means that users can have username/password, but they don't have to. They also can have one or multiple OpenIDs, but they don't have to. They can use non-unique display name.
Option 1: Only one login type is allowed
Here's my suggestion (UPDATED to prevent the need to edit all business logic related to username):
Create a new column called loginid to allow the storage of OpenIDs and old usernames, Add the UNIQUE INDEX on this column as well.
Populate loginid with existing data from username
DELETE INDEX from username to allow them to be non-unique. When creating a new user from OpenID, set username value to unknown(google) as described.
Keep password for legacy logins, ignore it for OpenID.
Update only the AUTH portion of your code to look for loginid rather than username.
Option 2: Allow multiple logins (also easily extends to linking multiple profiles from various sources)
Create a new table to stand as a master user table and contain all required fields per user (maybe email from your example above).
Create a table to store authentication containing: userid (FK to master record), username (stores the username appropriate to the login scheme), password
There are obviously flaws with both of these options, but it will hopefully get you started in the right direction.

Categories