Jonathan Bird
Jonathan Bird

Reputation: 352

Writing a clean multidimensional array

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

Answers (2)

Anderson Contreira
Anderson Contreira

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

fusion3k
fusion3k

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

Related Questions