Reputation: 352
I've written the code below and it works well but I have a feeling that it can be done better. Once I have 10 roles and 10 different states (new, checked etc), then the array will get very large.
Does anyone have a solution that has the same solution about passing in the state and role, and returning the lock and unlock state?
public function lockingPermissions($state, $role)
{
$lockingPermissions = [
'technician' => [
'new' => [
'lock' => true,
'unlock' => false
],
'checked' => [
'lock' => true,
'unlock' => false
]
],
.....
];
return $lockingPermissions[$role][$state];
}
Upvotes: 2
Views: 94
Reputation: 798
The multidimensional array is filled dynamically.
function lockingPermissions($state, $role)
{
$lockingPermissions = array();
$roles = array('technician','executive','programmer','other');
$states = array('new','checked','old','other');
$options = array('lock' => true, 'unlock' => false);
$newStates = array();
foreach($states as $value){
$newStates[$value] = $options;
}
foreach($roles as $role){
$lockingPermissions[$role] = $newStates;
}
//var_dump($lockingPermissions);
//Check the value
if(array_key_exists($role,$lockingPermissions)){
if(array_key_exists($state,$lockingPermissions[$role])){
return $lockingPermissions[$role][$state];
}else{
return false;
}
}else{
return false;
}
}
var_dump(lockingPermissions("new","technician"));
var_dump(lockingPermissions("checked","executive"));
UPDATE, More dynamically:
<?php
function lockingPermissions($state, $role)
{
$lockingPermissions = array();
$roles = array('technician','executive','programmer','other');
$states = array('new' => 'options_type_1','checked'=> 'options_type_1','old'=> 'options_type_2','other'=> 'options_type_2');
$options = array(
'options_type_1' => array('lock' => true, 'unlock' => false),
'options_type_2' => array('lock' => true, 'unlock' => false, 'other' => true)
);
$newStates = array();
foreach($states as $key => $value){
//$newStates[$value] = $options;
$newStates[$key] = $options[$value];
}
foreach($roles as $role){
$lockingPermissions[$role] = $newStates;
}
var_dump($lockingPermissions);
//Check the value
if(array_key_exists($role,$lockingPermissions)){
if(array_key_exists($state,$lockingPermissions[$role])){
return $lockingPermissions[$role][$state];
}else{
return false;
}
}else{
return false;
}
}
var_dump(lockingPermissions("new","technician"));
var_dump(lockingPermissions("checked","executive"));
//var_dump(lockingPermissions("new","technicianx"));
Upvotes: 1
Reputation: 11689
First of all, you have to assume that an empty value means no permission. By this way, you can omit all role definitions without permission. Then, you can use flags. First, define the flags:
define( 'LP_NEW_LOCK', 1 ); # 2**0
define( 'LP_NEW_UNLOCK', 2 ); # 2**1
define( 'LP_CHECKED_LOCK', 4 ); # 2**2
define( 'LP_CHECKED_UNLOCK', 8 ); # 2**3
(...)
define( 'LP_LOCK_ALL', 349525 ); # 2**0|2**2|2**4|2**6|2**8|2**10|2**12|2**14|2**16|2**18
define( 'LP_UNLOCK_ALL', 699050 ); # 2**1|2**3|2**5|2**7|2**9|2**11|2**13|2**15|2**17|2**19
define( 'LP_ALL', 1048575 ); # 2**20-2**0
I use constant, like PHP standard, but you can use variables1 (or directly the integers). Rule for flag are that they must be unique integers and powers of 2 (1, 2, 4, 8, 16, 32, ...). You can also create grouping flags with |
bitwise operator: i.e., a full-privileges for “new” can be 3 (= 1|2).
Then, you can create the array in this way:
$lockingPermissions = [
'admin' => LP_ALL,
'technician' => LP_LOCK_ALL,
'role3' => LP_NEW_LOCK | LP_NEW_UNLOCK | LP_CHECKED_LOCK,
'role4' => LP_LOCK_ALL ^ LP_NEW_LOCK, # lock all except new
'role5' => 0 # No permissions
];
At this point, you can call a hypothetical function in this way:
$perm = $lockingPermissions[$role];
and check permissions in this way:
if( $perm & LP_NEW_LOCK ) ...
1 If you want to use variables, you have to declare is as global inside the function. In this case, I suggest you to use an array to simplify the code.
Upvotes: 1