Я бы предложил создать серию групп пользователей в вашей базе данных, каждая из которых имеет один или несколько уровней учетных записей пользователей, затем назначить целое число в качестве иерархического значения для группы, а затем сделать то же самое для отдельных уровней учетных записей.внутри группы, что-то вроде этого (это реляционная структура, используйте InnoDB):
table: account_groups (Broader account groupings)
Fields:
-id_key - primary key, auto number
-group - unique index
-parent - index, foreign key=account_groups.group (this allows you to create group trees, so you can specify that a county group belongs to a state, and a municipality belongs to a county group, etc.)
-group_hierarchy - integer (0 is highest permission group, each subsequent one step lower)
table: account_levels (Account levels within a group)
Fields:
-id_key - primary key, auto number
-account_level - unique index
-group - index, foreign key=account_groups.group
-account_heirarchy - integer (same as other table but denotes heirarchy within the group
table: user_accounts (Individual user accounts)
Fields:
-id_key - primary key, auto number
-account_id - unique index, user account name
-account_level - index, foreign key=account_levels.account_level
table: user_groups (denotes which tree(s) the user has access to)
Fields:
-id_key - primary key, auto number
-account_id - index, foreign key=user_accounts.account_id
-group - index, foreign key=account_groups.group
А затем для разрешений:
table: permissions (directory of permissions that could be applied)
Fields:
-id_key - primary key, auto number
-permission - unique index, permission identifier
-other stuff you need associated with the individual permissions, based on how you want them to hook into your program
table: permissions_group_permissions (permissions applied at group level)
Fields:
-id_key - primary key, auto number
-group - index, foreign key=account_groups.group
-permission - index, foreign key= permissions.permission
table: permissions_account_permissions (permissions applied at account level)
Fields:
-id_key - primary key, auto number
-account_type - index, foreign key=account_levels.account_level
-permission - index, foreign key=permissions.permission
table: permissions_individual_permissions (permissions applied to individual accounts, if neccessary)
Fields:
-id_key - primary key, auto number
-account_id - index, foreign key=user_accounts.account_id
-permission - index, foreign key=permissions.permission
-allow_or_deny - boolean (TRUE means permission is granted, FALSE means permission if revoked. This allows you to fine tune individual accounts, either granting custom elevated permissions, or revoking individual permissions for troublesome accounts without demoting them from the group. This can be useful in some special circumstances)
-expiration - timestamp (allows you to set expiration dates for permissions, like if you want to temporarily suspend a specific action. Programmatically set default value of 00/00/00 00:00:00 as indefinite. You can do this at the account and group levels too by adding this field to those tables.)
Затем вы можете использовать php для перебораразрешения для отдельной учетной записи, сначала получая группу, связанную с уровнем учетной записи, создавая массив каждой последующей группы в иерархическом порядке, а затем перебирая иерархический порядок для текущей группы (добавляя как многомерный массив в групповой массив) изтекущий уровень учетной записи в группе до последнего существующего уровня учетной записи в группе.Затем вы должны получить все уровни учетной записи для каждой последующей группы и, наконец, получить все связанные разрешения для каждого уровня учетной записи, который был добавлен в массив.Если вы реализуете разрешения для отдельных пользователей, вам потребуется добавить массив разрешений с индивидуально примененными разрешениями и, наконец, удалить все разрешения, которые из вашего массива имеют для поля allow_or_deny значение FALSE.Если пользователю необходимо иметь доступ к нескольким деревьям, вы добавляете в таблицу account_groups запись, соответствующую идентификатору его учетной записи, обозначающую, каков наивысший уровень дерева, к которому у него есть доступ, а затем выполняете итерацию по всем последующим группам в дереве.Чтобы предоставить все соответствующие разрешения учетной записи, соберите все ассоциации групп для account_id из user_groups, а затем запустите ранее описанный процесс для каждого дерева.Если у них есть доступ только к одному дереву, вам даже не нужно использовать таблицу user_groups.
an example of how the structure fits your model:
group: USA, hierarchy = 0
group: California, parent-> USA, hierarchy = 1
group: Los Angeles, parent->California, hierarchy = 2
group: Texas, parent->USA, hierarchy = 1
group: Dallas, parent->Texas, hierarchy = 2
Члены группы USA могут получить доступ ко всему.Члены Калифорнии могут получить доступ ко всем последующим группам в иерархии для Калифорнии, но не к группам для Техаса, даже если они имеют одинаковое иерархическое значение (потому что это разные родительские ветви)
account levels:
admin, hierarchy=0
manager, hierarchy=1
analyst, hierarchy=2
staff member, hierarchy=3
Каждый уровень учетной записи имеет всеразрешений для каждого последующего уровня учетной записи.
user accounts:
Bob, manager (likes to spam junk email to everyone)
Вы по-прежнему можете отозвать разрешение электронной почты для Боба, добавив разрешение электронной почты в permissions_individual_permissions и установив для параметра allow_or_deny значение FALSE.Это позволяет вам помешать Бобу рассылать спам, не лишая его управления.
example PHP array:
$account=array(
groups=>array(), //Step 1: array_push each group the account is a member of here. Repeat for each tree from user_groups.
account_levels=>array(), //Step 2: loop through $account[groups], array_push each level here
permissions=>array(), //Step 3: loop through $account[account_levels], array_push each permission here. Then do the same for individual permissions applied to the account
restrictions=>array() //Step 4: loop through individual permissions where allow_or_deny=FALSE, array_push here (do the same for group and account level if you implemented restrictions for those tables as well). Tell your program to ignore permissions from this array, even if the account would otherwise have them.
);