Implementing Discussion Group System - php

I am going through the process of adding discussion groups to my site, currently users can post on topics then other users can reply, pretty simple.
Here is how I have set up the group tables
Disc_group
ID(int)
Name(varchar)
Description(varchar)
Created(date)
Creator(int) = user_id
invite_rule(enum 0,1) 0 = open invite, 1 = invite must be approved
Disc Users
ID(int)
User_id(int)
Group_id(int)
datejoined(date)
accepted(enum 0,1) 1 = accepted
admin(enum 0,1) 1 = admin
My question is I am trying to think of the most efficient way to implement this with the current topics, posts and tags tables.
I thought I could just add "group_id" into topics, so topics with group_id of 3 for example, only display if you are viewing the group page id=3.
I don't want any one to write code for me, I'm wanting to know what file structure would be recommended, such as
Non grouped posts are displayed in "topics.php?id=1" topics in groups displayed in "gtopics.php?id=1" for example, hopefully my issue isn't too confusing.

invite_rule(enum 0,1) 0 = open invite, 1 = invite must be approved
accepted(enum 0,1) 1 = accepted
admin(enum 0,1) 1 = admin
We can already see the above forming into a set of permissions, I highly recommend implementing a bit masking system that way you can store the user permissions in the database and perform a logical AND when you generate your authorization token.
Disc Users
ID(int)
User_id(int)
Group_id(int)
datejoined(date)
accepted(enum 0,1) 1 = accepted
admin(enum 0,1) 1 = admin
Is going to start hurting when it comes to normalization, I would propose the following structures to replace this:
DISC_GROUPS
GroupName
GroupId (not needed if group names need to be unique)
DISC_USER_GROUPS
UserId
GroupId
DISC_USERS
USER_ID
NAME
PERMISSIONS
DATE_JOINED
//other information about users
//This table may be unnecessary, unless you want to add some audit information perhaps
DISC_INFORMATION (THIS IS YOUR OLD DISC_USERS table)
ID
USERID
Notice how we don't duplicate information and we rely on the USER_ID relationship if we need more details.

Related

MYSQL Consolidate Conditional Update from Picklist Array

I am struggling to find a good way to approach this code with MYSQL and PHP.
I have a table of users and a table of groups. Each user will only belong to one group, or will belong to group 0, (not in a group).
I have an administration edit group page, which has the JS Picklist Plugin in it.
It lists the users which are in the group, and those that are not.
On submission of the form on this page, I get an array of users which are the only ones which should be in the group after the sql query.
So I need to do two things:
Remove the group id from any users which currently are in the group, but are not in the array returned by the form.
Ensure any users in the array returned have the group id updated to them.
For this example, I have a group ID of 25, after the form has been submitted there are two be two users in this group (44 and 45). No other users should remain in that group. But if the other users are in a different group such as 30, they should not be modified either.
I could have several hundred users, and whilst performance isn't the greatest concern, it just feels a bit hackish to me.
This is what I've failed at so far. For performance reasons we are talking maybe 300 users, so nothing to massive. The two queries do work as expected, just seems very hackish. Must be a better way, here to learn!
update users set user_group = 0 where (user_group = 25 AND uid != 45) AND (user_group = 25 AND uid != 44)
update users set user_group = 25 where ( uid = 44 OR uid = 45 )
Thanks!
UPDATE users
SET user_group = CASE
WHEN uid IN (...ids from post) THEN $group_id
ELSE 0
END
WHERE user_group = $group_id OR uid IN (...ids from post)
Untested and posted from my phone but the concept is there

MySQL/PHP: Looking for matching records from three tables(Forum permissions)

Maybe I am not putting the search in correctly in Google or SOF.com, but perhaps someone is willing to assist regardless. I know this is not the best method, but I am learning and I am hoping someone can assist in this way. I have a forum system in PHP/MySQL. The forum is set up to have an ID column.
I now also have 2 tables. One is a group table and the other is a forum permission table. The group table has an ID column and a user_id column, both int. The Forum Permission table has an id, forum_id and group_id. Basically I am trying find if the user belongs to a group(Group Table) and if that group is allowed to be in that forum(Forum Permission Table). The problem is that the user can belong to multiple groups and each forum can have multiple groups assigned to it.
Is there a query which can basically just search the three tables and distinguish if the user has access to the forum? If it were just one group to one forum, or one group per user, I can figure that out, but in this case I am stuck.
Any help? Example of Table structure below:
This is the Forum Table
Forum_ID || Forum_Name
1 ||| General tal
k
For Group Table:
Group_id ||| Group_name ||| User_ID
1 ||| Administrators ||| 2
For the Forum permission table(Forum_ID corresponds to Forum_ID in the Forums Table and Group_To_Allow corresponds to Group_ID on the groups table):
ID ||| Forum_ID ||| Group_To_Allow
1 ||| 1 ||| 1
Best I can do with the formatting.
EDIT:
OK, I figured it out with the InnerJoin. So using the table structure above:
SELECT *
FROM forum_perm
INNER JOIN membergroups
ON forum_perm.forum_groupallow=membergroups.group_id
WHERE forum_perm.forum_id = 1 AND membergroups.user_id = 6
LIMIT 0,1
Forum_perm.forum_id = 1 is the id number of the forum to check for the group. Membergroups.user_id = 6 is the users id number that belongs to the that group. The limit 0,1 will limit the result to just return one result instead of looping over and over. This is good because in PHP if MySQL loops through all the results and finds one group that does not match, it will still return false. Hope this helps anyone who is trying to achieve something similar.
You could make a JOIN statement and only select the highest value with MAX() from the certain row you want. I don't know your exact table structure or how you're doing that with the forum permissions. If you have only one column in your user table (I guess that's what you have, since that's usually the case), you maybe can use it in a IN statement (WHERE field IN(...). Maybe it works to just say mysql, hey take the value of this field (if the value of this field is commata-separated). I've never done it so I don't know it works.
Maybe you should make us some screenshots from your tables in phpmyadmin, so we can give you more accurate and specific informations.
edit: It does work with just throwing the name of the column.

Grouping Users on a virtual roster

I'm trying to come up with the most simple / userful / efficient method to group 3 users together using mysql.
To set the stage:
X number of users in a list (all with int account_id's)
mini groupings need to be created on a per user basis (user 1 wants to group with 220 for instance).
Max 3 people per grouping (user 1 + user 220 + user 9123 = group full)
Need to easily find if a user is in a group or not without looking in a bunch of columns
I'm stumped about how best to create a schema for this (so I can easily query my table to see if user is in a group, or if they can be added, or check for group space availability).
Anyone have any idea? My initial thought is schema like this (but it really seems too rigid):
Schema
GROUP_ID USER1 USER2 USER3 LASTUPDATE
1 1 220 null 5/25/2011 20:00:00
2 300 2 4 5/25/2011 20:00:00
How would you do it to make something this simple very flexible and efficient. I really feel stupid for asking.
Personally I would approach this by using 3 tables.
Users Table
user_id user_name ..... last_update
Groups Table
group_id group_name ......
Users to groups Table
user_to_group_id user_id group_id
This forms a many to many relationship by linking through the "Users to groups" table, obviously you can have more that 3 users linked to one group so you will have to make your PHP logic check for this when adding a new user to a group.
You can simply use SQL joins to retrieve all the data required and filter the results in your PHP code.
I hope this helps
Kind regards
Garry

What is the most efficient way to always make a database query that I know will only return a result very occasionally?

I am trying to work out how to implement a new piece of functionality on my website. My site allows people to download things uploaded by members of a group. The new piece of functionality will allow 1 member of the group to be a 'super' user whos uploads cannot be downloaded. So at the moment my query (more or less) is -
SELECT * FROM uploads WHERE group = $groupid
I am thinking I will store the 'super' status of the member in the 'members' table so will probably look up this to get the member id of the super member before doing the query.
$all_group_members = SELECT members FROM groups WHERE group_id = $groupid
$super_member = SELECT memberid FROM members WHERE memberid IN ($all_group_members) AND super_status = 1
Then modify the query to be -
SELECT * FROM uploads WHERE group = $groupid AND uploader ! = $super_member
However there may not always be a super member in a group, so my question is is there a more effective way to do this, for example store the super members ids in the session cookie? What about storing the super user id in the group table - still involves doing a query -
SELECT super_user FROM groups WHERE groupid = $group_id
But atleast thats one less query.
Is there just no way around this - I know that there will only be a super user about 5% of the time so 95% of the time this will be wasted query. Perhaps the session cookie could store a group_has_super_user variable.
Any other ways of doing this that im missing?
thanks
I assume, other group members can't download anything from my group's stuff. So, simply add a downloadable field to the uploads, and set it to
1, if a simple member has uploaded it, or
0, if a super member has.
Then the only query you have to run is:
SELECT * FROM uploads WHERE group = $groupid AND downloadable != 0
Also, if the membership is changing (e.g. someone else gets the super right), these flags should be recalculated in the group.
Don't forget to create index for (or set the primary key to) groupid + downloadable (or downloadable + groupid)!
CREATE TABLE uploads (id, user_id, …)
CREATE TABLE groups (id, …)
CREATE TABLE group_users (group_id, user_id, is_super, …)
SELECT u.*
FROM group_users gu
JOIN uploads u
ON u.user_id = gu.user_id
WHERE gu.group_id = $group_id
AND gu.is_super = 0

PHP MySQL. Linking 2 Tables columns together

I've got an small issue, I'm trying to make my own forum, but I am stuck at something.
I have 3 tables, 1 users with a user_level (Authentication level).
forum_section which contains all the sections with a user_level again.
But how can I link forum_section.user_level to forum_topics.user_level.
So if I define: forum_section.user_level = 4 for forum_section.section_id = 1.
For example:
Someone wants to visit the forum_section id 1 then they must have a auth level of 4.
And when they go to the topic it then again checks if the user level is 4, but I do not want to manual set the topic level, topic level must always be the same as the section level.
I've googled for this, but I can't really find a good manual for it. I guess it has something to do with: "foreign keys"?
Okay, let me explain a bit more just to be sure.
I have 3 tables
Table User
username = Wesley
userlevel < for example 4(admin).
Table section
section_id = 3
section_name = News
section_level = 3 <require level to view.
table topics
topic_id = 123
topic_name = I like candy
topic_level = Needs to be the same as section_level so if I change section_level it automatically changes this too.
You should have to manage your database by using master and transaction tables.
Your table format should look like this:
table name: user
user_id user_name
1 abc
2 xyz
3 pqr
4 new
table2 name : forum_section
forum_id user_id forum_name
1 4 abc
2 4 jkl
3 2 cbd
4 3 lmn
Now, you can JOIN these two tables and make a query as you want, like this:
SELECT forum_id FROM forum_section as fs,user as u WHERE fs.user_id = u.user_id AND fs.user_id = 4
This may help you. Please write if you need more help!
You need to either use a SQL JOIN or a NESTED SUB QUERY
The simplest implementation would be to initially establish the users access level, then filter subsequent queries based on this- so in your PHP, pass the access level to subsequent requests for content- if the query returns anything, the user can view the content, if not- they can be redirected.

Categories