Heirarchical Sub-Menu - PHP - php

====================================================================
| menu id | parent_id | menu | Level |
====================================================================
| 1 | 0 | Control Panel | 1 |
====================================================================
| 2 | 1 | Administrative | 2 |
====================================================================
| 3 | 2 | Manage User | 3 |
====================================================================
| 4 | 2 | Manage Role | 3 |
====================================================================
| 5 | 1 | Change Password | 2 |
====================================================================
I have this table to create a sub-menu... the problem is don't know how echo the data and display the echoed data into like this:
- Control Panel
- Administrative
- Manage User
- Manage Role
- Change Password
Does anyone have the answer in PHP? Please I need this solution for my project. Please give me an example. Thank You!

print lines with level number of spaces or tabs before the text
print(getTabs($row['level']).'-'.$row['menu]))
Where getTabs returns argument number of tabs/spaces
Leaving the string format part to you

Your data is already hierarchical - even without the level column, you can build the whole tree. Can you be more specific regarding what you are trying to achieve?

Related

PHP, MySQL - efficiently determining access permissions based on distant parent

I'm struggling to come up with an efficient solution to determine user access to a specified folder, using PHP (specifically Laravel) and MySQL. I want to create a system that has Google Drive-esque functionality...
For example, Joe Bloggs creates many folders within folders, e.g. Level 1 > Level 2 > Level 3 > Level 4 > Level 5. Within any of these folders, can be any number of additional sub files and folders.
This would be the resulting database structure -
Table name: users
| id | name |
| -- | ---------- |
| 1 | Joe Bloggs |
| 2 | John Snow |
Table name: folders
| id | parent_id | author_id | name |
| -- | --------- | --------- | --------- |
| 1 | NULL | 1 | Level 1 |
| 2 | 1 | 1 | Level 2 |
| 3 | 2 | 1 | Level 3 |
| 4 | 3 | 1 | Level 4 |
| 5 | 4 | 1 | Level 5 |
| 6 | 2 | 1 | Level 3.1 |
| 7 | 2 | 1 | Level 3.2 |
Table name: folders_users
| id | folder_id | user_id | owner | read | write |
| 1 | 1 | 1 | 1 | 1 | 1 |
| 2 | 3 | 2 | 0 | 1 | 1 |
So based on record 1 in folder_users, Joe Bloggs should have owner, read & write permissions for all folders underneath Level 1. Joe Bloggs, then gives John Snow read & write access to Level 3, which in turn should give Joe Bloggs read & write access to Level 3, Level 3.1, Level 3.2 and anything created under any of these in future.
Additionally, it should be possible for a user to star a folder. I'd imagine this can simply be achieved with a separate table and query this separately -
Table name: starred_folders
| id | folder_id | user_id |
| -- | --------- | ------- |
| 1 | 7 | 2 |
The current solution I have is for every folder in the chain a user has permission to access, a record is created in the folders_users table. I feel like this is just overcomplicating things and creating excessive numbers of records. This is especially true when it comes to sharing a folder as I have to recreate the entire tree for that one user. Or, imagine if a user revokes write access to one of the shared users, the entire tree (potentially hundreds of records) has to be updated for a single flag.
What would be the best way to generate these trees, and to quickly and efficiently determine the user's access level in any given folder? I suspect the only way to do this is recursion, but I'm concerned about its efficiency? Or, should I perhaps be using something entirely different from MySQL for this? I've had a brief look into graph databases but I can't see it being a way forward for us as we don't have the infrastructure to support it.
Thanks,
Chris.
I'm writing this as a solution not the most efficient one.
You can add a column to your folders table (let's call it access) and then put ids of people that have access to that folder and it's children. I assume when you want to show information about a folder you must get its parents information from table as well so you won't need to add new queries for that.
And if you just have a access definition you can simple add records to this column like user1,user2,... and if not you can serialize an array like this
[
"read" => [user1,user2,...],
"write" => [user2]
]
Of course you can add a column for each access but if you have so many accesses this might be a solution too.

Database model for a multilanguage translation module

I need to design a db model for a backend module where user can translate page content into multiple languages. The things that will be translated are basic words, phrases, link names, titles, field names, field values. They should also be grouped so i can find them by group name. For example if there is a select field on page with different colors as options then i should be able to select all of them by group name.
So here is what i have at the moment:
lang
+----+---------+
| id | name |
+----+---------+
| 1 | english |
| 2 | german |
+----+---------+
lang_entity
+----+------------+-------------+-------+-------+
| id | module | group | name | order |
+----+------------+-------------+-------+-------+
| 1 | general | | hello | 0 |
| 2 | accounting | colorSelect | one | 1 |
| 3 | accounting | colorSelect | two | 2 |
| 4 | accounting | colorSelect | three | 3 |
+----+------------+-------------+-------+-------+
lang_entity_translation
+----+---------+----------------+-------------+
| id | lang_id | lang_entity_id | translation |
+----+---------+----------------+-------------+
| 1 | 1 | 1 | Hello |
| 2 | 2 | 1 | Guten tag |
| 3 | 1 | 2 | One |
| 4 | 2 | 2 | Ein |
| 5 | 1 | 3 | Two |
| 6 | 2 | 3 | Zwei |
| 7 | 1 | 4 | Three |
| 8 | 2 | 4 | Drei |
+----+---------+----------------+-------------+
So lang table holds different languages.
Table lang_entity has entities that can be translated for different languages.
Module row is just to group them by page modules in the backend translating module. Also this gives me possiblity to have entities with same name for different modules.
Group as mentioned is needed for selects and maybe some other places where multiple values are going to be used. This also gives me an option to allow user to add and order entities in one group.
And table lang_entity_translation holds the translations for each entity in each language.
So my question is are visible flaws in this kind of a design? Would you reccomend something different?
Also a bonus question: I really dont like the lang_entity table name, do you have a better idea of a table name that would hold all the words/phrases that are translated? :)
Edit: similar, but not a duplicate. The linked question is about translating dynamic products and having a seperate table for each translated type. Im talking about translating whole page content, including groups in a single table.
I don't understand the order column of lang_entity, but then I probably don't need to.
The setup looks sane, but make sure you add foreign key constraints from lang_entity_translation to language and lang_entity.
As for naming, I would call the table phrase or translatable.
We had similar situation. This was 7 years before.
We had different column for different language. Like for name we had
Name_Eng,Name_Ger,Name_Spa .We had 7-10 language.
We had common id for name for all language.
Based on the Language selection from UI we passed the language code to Back end In the Stored proc it was appended to the column Name
Example, we will be passing "Eng" if English is selected and we form the column name as Name_Eng and fetch the data. we were using dynamic query.

MySQL Accounting Code Database Structure

I have a question on making the effective database structure for accounting code. The result I was expecting is this
| ID | Code | Name | Parent |
| 1 | 1 | Assets | |
| 2 | 1 | Tangible Fixed Assets | 1 |
| 3 | 1 | Building | 2 |
| 4 | 2 | Intangible Fixed Assets| 1 |
| 5 | 1 | CopyRights | 3 |
I've been thinking about making 3 tables such as tbl_lvl1 for main parent, tbl_lvl2 as first child and tbl_lvl3 as second child. I found about recursive query, which is just only using 1 table, but it's kind of difficult making recursive query in MYSQL.
And the result I want to view in PHP, is something like this
| Code | Name |
| 1 | Assets |
| 11 | Tangible Fixed Assets |
| 111 | Building |
| 12 | Intangible Fixed Asset |
| 121 | CopyRights |
Which structure I should make? Using 3 table or 1 table ? Thank you
You're looking for a search tree, and I'd especially suggest a B-tree.
A search tree, generally spoken, allows you to hierarchically search for all sub-nodes in a single query through nested intervals.
There are literally dozens of implementations, so you don't need to dig deep into the details, even though I would suggest it, as it's a major data structure that you should be used to.

Database driven PHP navigation

Lets say we have following tables
Table Pages:
id | short_name | long_name | token
1 | Mail | My mail box | mail
2 | All mails | All mails | all
3 | Inbox | Inbox only | inb
4 | Users | Users | users
5 | All users | All users | all
and table navigation:
id | parent_id | page_id
1 | 0 | 4
2 | 0 | 1
3 | 1 | 2
4 | 1 | 3
5 | 4 | 5
I was working with only page ids for a long time. It was easy to find details of page with only 1 value - $_GET['id'], because ids of pages all are unique.
Now, I want to create human readable (token based) navigation system.
But there is 1 problem. Tokens are not always unique.
For ex. index.php?page=mail&subpage=all and index.php?page=users&subpage=all
Can't figure out, how to find short_name and long_name (or other information of page) for these 2 pages (by 2 - $_GET['page'] and $_GET['subpage'] or more variables)?
Maybe I'm in wrong way. If you think so, please suggest your idea, and explain. Thx in advance.
Sorry if this doesn't work out of the box, but does this help?
SELECT * FROM Pages
JOIN navigation ON Pages.id=navigation.page_id
WHERE navigation.parent_id=(SELECT id FROM Pages WHERE token={$page})
AND Pages.token={$subpage}

Sorting MySQL results based on it's context

I'm trying to create a nested comment system using PHP and MySQL. But I'm stuck
My Database structure is id, body, time, reply and depth.
A regular comment's reply field will be '0'. If it's replying to another it will correspond to the id of the comment it's replying to.
depth means how deep it is from the highest parent
So if this is the contents of my table...
+------+-------------+--------+---------+---------+
| id | body | time | reply | depth |
+------+-------------+--------+---------+---------+
| 1 | Some msg1 | 1 | 0 | 0 |
| 2 | Some msg2 | 2 | 0 | 0 |
| 3 | aReply1 | 3 | 1 | 1 |
| 4 | aReply2 | 4 | 1 | 1 |
| 5 | aReply21 | 5 | 3 | 2 |
+------+-------------+--------+---------+---------+
It would appear as something like this...
- (1) Some msg1
-- (3) aReply1
--- (5) aReply21
-- (4) aReply2
- (2) Some msg2
I hope it's possible using this method, it kind of goes beyond my logic.
If you can't change table structure you can just get all rows (select * from table order by time) then generate tree using PHP.
For tree storage I recommend to use Nested Sets algorithm.

Categories